# Binaries
*.a
+*.o
*.so
*.so.*
*.dylib
server/Sample/sfreerdp-server
server/X11/xfreerdp-server
xcode
+libfreerdp/codec/test/TestOpenH264ASM
# Other
*~
if(NOT IOS)
check_include_files(fcntl.h HAVE_FCNTL_H)
check_include_files(unistd.h HAVE_UNISTD_H)
+ check_include_files(execinfo.h HAVE_EXECINFO_H)
check_include_files(stdint.h HAVE_STDINT_H)
check_include_files(inttypes.h HAVE_INTTYPES_H)
check_include_files(sys/modem.h HAVE_SYS_MODEM_H)
if ((error = snd_pcm_hw_params_malloc(&hw_params)) < 0)
{
- DEBUG_WARN("snd_pcm_hw_params_malloc (%s)",
+ CLOG_ERR("snd_pcm_hw_params_malloc (%s)",
snd_strerror(error));
return FALSE;
}
{
if ((error = snd_pcm_open(&capture_handle, alsa->device_name, SND_PCM_STREAM_CAPTURE, 0)) < 0)
{
- DEBUG_WARN("snd_pcm_open (%s)", snd_strerror(error));
+ CLOG_ERR("snd_pcm_open (%s)", snd_strerror(error));
break;
}
}
else if (error < 0)
{
- DEBUG_WARN("snd_pcm_readi (%s)", snd_strerror(error));
+ CLOG_ERR("snd_pcm_readi (%s)", snd_strerror(error));
break;
}
DEBUG_DVC("NumFormats %d", NumFormats);
if ((NumFormats < 1) || (NumFormats > 1000))
{
- DEBUG_WARN("bad NumFormats %d", NumFormats);
+ CLOG_ERR("bad NumFormats %d", NumFormats);
return 1;
}
Stream_Seek_UINT32(s); /* cbSizeFormatsPacket */
if (initialFormat >= (UINT32) callback->formats_count)
{
- DEBUG_WARN("invalid format index %d (total %d)",
+ CLOG_ERR("invalid format index %d (total %d)",
initialFormat, callback->formats_count);
return 1;
}
if (NewFormat >= (UINT32) callback->formats_count)
{
- DEBUG_WARN("invalid format index %d (total %d)",
+ CLOG_ERR("invalid format index %d (total %d)",
NewFormat, callback->formats_count);
return 1;
}
break;
default:
- DEBUG_WARN("unknown MessageId=0x%x", MessageId);
+ CLOG_ERR("unknown MessageId=0x%x", MessageId);
error = 1;
break;
}
if (audin->device)
{
- DEBUG_WARN("existing device, abort.");
+ CLOG_ERR("existing device, abort.");
return;
}
if (entry(&entryPoints) != 0)
{
- DEBUG_WARN("%s entry returns error.", name);
+ CLOG_ERR("%s entry returns error.", name);
return FALSE;
}
if (audin->device == NULL)
{
- DEBUG_WARN("no sound device.");
+ CLOG_ERR("no sound device.");
}
return error;
#include <freerdp/dvc.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#include <freerdp/client/audin.h>
#ifdef WITH_DEBUG_DVC
-#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__)
+#define DEBUG_DVC(fmt, ...) CLOG_CLASS(DVC, fmt, ## __VA_ARGS__)
#else
-#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
+#define DEBUG_DVC(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif /* FREERDP_AUDIN_CLIENT_MAIN_H */
int rc = android_RecIn(opensles->stream, buffer.s, raw_size);
if (rc < 0)
{
- DEBUG_WARN("android_RecIn %d", rc);
+ CLOG_ERR("android_RecIn %d", rc);
continue;
}
break;
default:
- DEBUG_WARN("Encoding '%d' [%08X] not supported",
+ CLOG_ERR("Encoding '%d' [%08X] not supported",
(format->wFormatTag),
format->wFormatTag);
return;
* ignore duplicate requests. */
if (!opensles->stopEvent)
{
- DEBUG_WARN("[ERROR] function called without matching open.");
+ CLOG_ERR("[ERROR] function called without matching open.");
return;
}
e = Queue_Dequeue(p->queue);
if (!e)
{
- DEBUG_WARN("[ERROR] got e=%p from queue", e);
+ CLOG_ERR("[ERROR] got e=%p from queue", e);
return -1;
}
if (pa_context_connect(pulse->context, NULL, 0, NULL))
{
- DEBUG_WARN("pa_context_connect failed (%d)",
+ CLOG_ERR("pa_context_connect failed (%d)",
pa_context_errno(pulse->context));
return FALSE;
}
if (pa_threaded_mainloop_start(pulse->mainloop) < 0)
{
pa_threaded_mainloop_unlock(pulse->mainloop);
- DEBUG_WARN("pa_threaded_mainloop_start failed (%d)",
+ CLOG_ERR("pa_threaded_mainloop_start failed (%d)",
pa_context_errno(pulse->context));
return FALSE;
}
break;
if (!PA_CONTEXT_IS_GOOD(state))
{
- DEBUG_WARN("bad context state (%d)",
+ CLOG_ERR("bad context state (%d)",
pa_context_errno(pulse->context));
break;
}
*/
if (pulse->buffer == NULL)
{
- /* fprintf(stderr, "%s: ignoring input, pulse buffer not ready.\n", __func__); */
+ /* CLOG_ERR( "%s: ignoring input, pulse buffer not ready.\n", __func__); */
return;
}
&buffer_attr, PA_STREAM_ADJUST_LATENCY) < 0)
{
pa_threaded_mainloop_unlock(pulse->mainloop);
- DEBUG_WARN("pa_stream_connect_playback failed (%d)",
+ CLOG_ERR("pa_stream_connect_playback failed (%d)",
pa_context_errno(pulse->context));
return;
}
break;
if (!PA_STREAM_IS_GOOD(state))
{
- DEBUG_WARN("bad stream state (%d)",
+ CLOG_ERR("bad stream state (%d)",
pa_context_errno(pulse->context));
break;
}
if (!pulse->mainloop)
{
- DEBUG_WARN("pa_threaded_mainloop_new failed");
+ CLOG_ERR("pa_threaded_mainloop_new failed");
audin_pulse_free((IAudinDevice*) pulse);
return 1;
}
if (!pulse->context)
{
- DEBUG_WARN("pa_context_new failed");
+ CLOG_ERR("pa_context_new failed");
audin_pulse_free((IAudinDevice*) pulse);
return 1;
}
#include <freerdp/codec/audio.h>
#include <freerdp/channels/wtsvc.h>
#include <freerdp/server/audin.h>
+#include <freerdp/channels/log.h>
#define MSG_SNDIN_VERSION 0x01
#define MSG_SNDIN_FORMATS 0x02
break;
default:
- fprintf(stderr, "audin_server_thread_func: unknown MessageId %d\n", MessageId);
+ CLOG_ERR( "audin_server_thread_func: unknown MessageId %d\n", MessageId);
break;
}
}
}
if (num_formats * 36 != length)
- DEBUG_WARN("dataLen %d not divided by 36!", length);
+ CLOG_ERR("dataLen %d not divided by 36!", length);
ascii = (flags & CB_ASCII_NAMES) ? TRUE : FALSE;
#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[] =
{
"",
"CB_LOCK_CLIPDATA"
"CB_UNLOCK_CLIPDATA"
};
+#endif
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;
}
{
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
- printf("Cliprdr Sending (%d bytes)\n", dataLen + 8);
- winpr_HexDump(Stream_Buffer(s), dataLen + 8);
+ CLOG_DBG("Cliprdr Sending (%d bytes)\n", dataLen + 8);
+ winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), dataLen + 8);
#endif
-
svc_plugin_send((rdpSvcPlugin*) cliprdr, s);
}
void cliprdr_print_general_capability_flags(UINT32 flags)
{
- fprintf(stderr, "generalFlags (0x%08X) {\n", flags);
+ CLOG_ERR("generalFlags (0x%08X) {\n", flags);
if (flags & CB_USE_LONG_FORMAT_NAMES)
- fprintf(stderr, "\tCB_USE_LONG_FORMAT_NAMES\n");
+ CLOG_ERR("\tCB_USE_LONG_FORMAT_NAMES\n");
+
if (flags & CB_STREAM_FILECLIP_ENABLED)
- fprintf(stderr, "\tCB_STREAM_FILECLIP_ENABLED\n");
+ CLOG_ERR("\tCB_STREAM_FILECLIP_ENABLED\n");
+
if (flags & CB_FILECLIP_NO_FILE_PATHS)
- fprintf(stderr, "\tCB_FILECLIP_NO_FILE_PATHS\n");
+ CLOG_ERR("\tCB_FILECLIP_NO_FILE_PATHS\n");
+
if (flags & CB_CAN_LOCK_CLIPDATA)
- fprintf(stderr, "\tCB_CAN_LOCK_CLIPDATA\n");
+ CLOG_ERR("\tCB_CAN_LOCK_CLIPDATA\n");
- fprintf(stderr, "}\n");
+ CLOG_ERR("}\n");
}
static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s)
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
{
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;
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);
}
}
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++)
case CB_CAPSTYPE_GENERAL:
cliprdr_process_general_capability(cliprdr, s);
break;
-
default:
- DEBUG_WARN("unknown cliprdr capability set: %d", capabilitySetType);
+ CLOG_ERR("unknown cliprdr capability set: %d", capabilitySetType);
break;
}
}
{
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);
}
if (context->custom)
{
CLIPRDR_MONITOR_READY monitorReady;
-
monitorReady.msgType = CB_MONITOR_READY;
monitorReady.msgFlags = flags;
monitorReady.dataLen = length;
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);
}
}
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);
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)
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);
}
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)
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:
- DEBUG_WARN("unknown msgType %d", msgType);
+ 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);
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)
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);
}
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:
- DEBUG_WARN("unknown event type %d", GetMessageType(event->id));
+ CLOG_ERR("unknown event type %d", GetMessageType(event->id));
break;
}
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;
}
for (index = 0; index < formatList->cFormats; index++)
{
format = (CLIPRDR_FORMAT*) &(formatList->formats[index]);
-
length += 4;
-
formatNameSize = 2;
if (format->formatName)
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
}
cliprdr_packet_send(cliprdr, s);
-
return 0;
}
{
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;
}
{
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;
}
{
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;
}
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;
}
#include <winpr/stream.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#include <freerdp/utils/svc_plugin.h>
struct cliprdr_plugin
CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr);
#ifdef WITH_DEBUG_CLIPRDR
-#define DEBUG_CLIPRDR(fmt, ...) DEBUG_CLASS(CLIPRDR, fmt, ## __VA_ARGS__)
+#define DEBUG_CLIPRDR(fmt, ...) CLOG_CLASS(CLIPRDR, fmt, ## __VA_ARGS__)
#else
-#define DEBUG_CLIPRDR(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
+#define DEBUG_CLIPRDR(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif /* __CLIPRDR_MAIN_H */
#include <winpr/print.h>
#include <winpr/stream.h>
+#include <freerdp/channels/log.h>
#include "cliprdr_main.h"
/**
CLIPRDR_HEADER header;
ULONG written;
- printf("CliprdrServerSendCapabilities\n");
+ CLOG_DBG("CliprdrServerSendCapabilities\n");
header.msgType = CB_CLIP_CAPS;
header.msgFlags = 0;
CLIPRDR_HEADER header;
ULONG written;
- printf("CliprdrServerSendMonitorReady\n");
+ CLOG_DBG("CliprdrServerSendMonitorReady\n");
header.msgType = CB_MONITOR_READY;
header.msgFlags = 0;
CLIPRDR_HEADER header;
ULONG written;
- printf("CliprdrServerSendFormatListResponse\n");
+ CLOG_DBG("CliprdrServerSendFormatListResponse\n");
header.msgType = CB_FORMAT_LIST_RESPONSE;
header.msgFlags = CB_RESPONSE_OK;
ConvertFromUnicode(CP_UTF8, 0, wszTempDir, -1,
&(context->priv->ClientTemporaryDirectory), 0, NULL, NULL);
- printf("ClientTemporaryDirectory: %s\n", context->priv->ClientTemporaryDirectory);
+ CLOG_DBG("ClientTemporaryDirectory: %s\n", context->priv->ClientTemporaryDirectory);
return 0;
}
int length;
int position;
- printf("%s\n", __FUNCTION__);
+ CLOG_DBG("%s\n", __FUNCTION__);
position = Stream_GetPosition(s);
Stream_SetPosition(s, Stream_Length(s));
for (i = 0; i < context->priv->ClientFormatNameCount; i++)
{
- printf("Format %d: Id: 0x%04X Name: %s Length: %d\n", i,
+ CLOG_DBG("Format %d: Id: 0x%04X Name: %s Length: %d\n", i,
context->priv->ClientFormatNames[i].id,
context->priv->ClientFormatNames[i].name,
context->priv->ClientFormatNames[i].length);
static int cliprdr_server_receive_short_format_list(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header)
{
- printf("%s: unimplemented\n", __FUNCTION__);
+ CLOG_DBG("%s: unimplemented\n", __FUNCTION__);
return 0;
}
static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header)
{
- printf("CliprdrServerReceivePdu: msgType: %d msgFlags: 0x%08X dataLen: %d\n",
+ CLOG_DBG("CliprdrServerReceivePdu: msgType: %d msgFlags: 0x%08X dataLen: %d\n",
header->msgType, header->msgFlags, header->dataLen);
switch (header->msgType)
break;
default:
- printf("Unexpected clipboard PDU type: %d\n", header->msgType);
+ CLOG_DBG("Unexpected clipboard PDU type: %d\n", header->msgType);
break;
}
DISP_LISTENER_CALLBACK* listener_callback;
UINT32 MaxNumMonitors;
- UINT32 MaxMonitorWidth;
- UINT32 MaxMonitorHeight;
+ UINT32 MaxMonitorAreaFactorA;
+ UINT32 MaxMonitorAreaFactorB;
};
typedef struct _DISP_PLUGIN DISP_PLUGIN;
Stream_Write_UINT32(s, NumMonitors); /* NumMonitors (4 bytes) */
- //fprintf(stderr, "NumMonitors: %d\n", NumMonitors);
+ //CLOG_ERR( "NumMonitors: %d\n", NumMonitors);
for (index = 0; index < NumMonitors; index++)
{
if (Monitors[index].Width < 200)
Monitors[index].Width = 200;
- if (Monitors[index].Width > disp->MaxMonitorWidth)
- Monitors[index].Width = disp->MaxMonitorWidth;
-
if (Monitors[index].Height < 200)
Monitors[index].Height = 200;
- if (Monitors[index].Height > disp->MaxMonitorHeight)
- Monitors[index].Height = disp->MaxMonitorHeight;
-
Stream_Write_UINT32(s, Monitors[index].Flags); /* Flags (4 bytes) */
Stream_Write_UINT32(s, Monitors[index].Left); /* Left (4 bytes) */
Stream_Write_UINT32(s, Monitors[index].Top); /* Top (4 bytes) */
Stream_Write_UINT32(s, Monitors[index].PhysicalWidth); /* PhysicalWidth (4 bytes) */
Stream_Write_UINT32(s, Monitors[index].PhysicalHeight); /* PhysicalHeight (4 bytes) */
Stream_Write_UINT32(s, Monitors[index].Orientation); /* Orientation (4 bytes) */
+ Stream_Write_UINT32(s, Monitors[index].DesktopScaleFactor); /* DesktopScaleFactor (4 bytes) */
+ Stream_Write_UINT32(s, Monitors[index].DeviceScaleFactor); /* DeviceScaleFactor (4 bytes) */
#if 0
- fprintf(stderr, "\t: Flags: 0x%04X\n", Monitors[index].Flags);
- fprintf(stderr, "\t: Left: %d\n", Monitors[index].Left);
- fprintf(stderr, "\t: Top: %d\n", Monitors[index].Top);
- fprintf(stderr, "\t: Width: %d\n", Monitors[index].Width);
- fprintf(stderr, "\t: Height: %d\n", Monitors[index].Height);
- fprintf(stderr, "\t: PhysicalWidth: %d\n", Monitors[index].PhysicalWidth);
- fprintf(stderr, "\t: PhysicalHeight: %d\n", Monitors[index].PhysicalHeight);
- fprintf(stderr, "\t: Orientation: %d\n", Monitors[index].Orientation);
+ CLOG_ERR( "\t: Flags: 0x%04X\n", Monitors[index].Flags);
+ CLOG_ERR( "\t: Left: %d\n", Monitors[index].Left);
+ CLOG_ERR( "\t: Top: %d\n", Monitors[index].Top);
+ CLOG_ERR( "\t: Width: %d\n", Monitors[index].Width);
+ CLOG_ERR( "\t: Height: %d\n", Monitors[index].Height);
+ CLOG_ERR( "\t: PhysicalWidth: %d\n", Monitors[index].PhysicalWidth);
+ CLOG_ERR( "\t: PhysicalHeight: %d\n", Monitors[index].PhysicalHeight);
+ CLOG_ERR( "\t: Orientation: %d\n", Monitors[index].Orientation);
#endif
-
- Stream_Write_UINT32(s, Monitors[index].DesktopScaleFactor); /* DesktopScaleFactor (4 bytes) */
- Stream_Write_UINT32(s, Monitors[index].DeviceScaleFactor); /* DeviceScaleFactor (4 bytes) */
}
Stream_SealLength(s);
disp = (DISP_PLUGIN*) callback->plugin;
+ if (Stream_GetRemainingLength(s) < 12)
+ return -1;
+
Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */
- Stream_Read_UINT32(s, disp->MaxMonitorWidth); /* MaxMonitorWidth (4 bytes) */
- Stream_Read_UINT32(s, disp->MaxMonitorHeight); /* MaxMonitorHeight (4 bytes) */
+ Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorA); /* MaxMonitorAreaFactorA (4 bytes) */
+ Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorB); /* MaxMonitorAreaFactorB (4 bytes) */
- //fprintf(stderr, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d\n",
+ //CLOG_ERR( "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d\n",
// disp->MaxNumMonitors, disp->MaxMonitorWidth, disp->MaxMonitorHeight);
return 0;
UINT32 type;
UINT32 length;
+ if (Stream_GetRemainingLength(s) < 8)
+ return -1;
+
Stream_Read_UINT32(s, type); /* Type (4 bytes) */
Stream_Read_UINT32(s, length); /* Length (4 bytes) */
- //fprintf(stderr, "Type: %d Length: %d\n", type, length);
+ //CLOG_ERR( "Type: %d Length: %d\n", type, length);
switch (type)
{
DISP_CHANNEL_CALLBACK* callback;
DISP_LISTENER_CALLBACK* listener_callback = (DISP_LISTENER_CALLBACK*) pListenerCallback;
- callback = (DISP_CHANNEL_CALLBACK*) malloc(sizeof(DISP_CHANNEL_CALLBACK));
- ZeroMemory(callback, sizeof(DISP_CHANNEL_CALLBACK));
+ callback = (DISP_CHANNEL_CALLBACK*) calloc(1, sizeof(DISP_CHANNEL_CALLBACK));
+
+ if (!callback)
+ return -1;
callback->iface.OnDataReceived = disp_on_data_received;
callback->iface.OnClose = disp_on_close;
int status;
DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin;
- disp->listener_callback = (DISP_LISTENER_CALLBACK*) malloc(sizeof(DISP_LISTENER_CALLBACK));
- ZeroMemory(disp->listener_callback, sizeof(DISP_LISTENER_CALLBACK));
+ disp->listener_callback = (DISP_LISTENER_CALLBACK*) calloc(1, sizeof(DISP_LISTENER_CALLBACK));
+
+ if (!disp->listener_callback)
+ return -1;
disp->listener_callback->iface.OnNewChannelConnection = disp_on_new_channel_connection;
disp->listener_callback->plugin = pPlugin;
return 1;
}
-#ifdef STATIC_CHANNELS
-#define DVCPluginEntry disp_DVCPluginEntry
-#endif
-
-int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
+int disp_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
int error = 0;
DISP_PLUGIN* disp;
disp->iface.pInterface = (void*) context;
disp->MaxNumMonitors = 16;
- disp->MaxMonitorWidth = 8192;
- disp->MaxMonitorHeight = 8192;
+ disp->MaxMonitorAreaFactorA = 8192;
+ disp->MaxMonitorAreaFactorB = 8192;
error = pEntryPoints->RegisterPlugin(pEntryPoints, "disp", (IWTSPlugin*) disp);
}
#include <freerdp/dvc.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#include <freerdp/client/disp.h>
+#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000005
#define DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002
-#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000003
#endif /* FREERDP_CHANNEL_DISP_CLIENT_MAIN_H */
if (status != CHANNEL_RC_OK)
{
drdynvc->channel_error = status;
- DEBUG_WARN("VirtualChannelWrite failed %d", status);
+ CLOG_ERR("VirtualChannelWrite failed %d", status);
return 1;
}
if (status != CHANNEL_RC_OK)
{
- DEBUG_WARN("pVirtualChannelEventPush failed %d", status);
+ CLOG_ERR("pVirtualChannelEventPush failed %d", status);
return 1;
}
if (status != CHANNEL_RC_OK)
{
- DEBUG_WARN("VirtualChannelWrite failed %d", status);
+ CLOG_ERR("VirtualChannelWrite failed %d", status);
return 1;
}
if (status != CHANNEL_RC_OK)
{
- DEBUG_WARN("VirtualChannelWrite failed %d", status);
+ CLOG_ERR("VirtualChannelWrite failed %d", status);
return 1;
}
if (error != CHANNEL_RC_OK)
{
- DEBUG_WARN("VirtualChannelWrite failed %d", error);
+ CLOG_ERR("VirtualChannelWrite failed %d", error);
return 1;
}
break;
default:
- DEBUG_WARN("unknown drdynvc cmd 0x%x", Cmd);
+ CLOG_ERR("unknown drdynvc cmd 0x%x", Cmd);
break;
}
}
#include <freerdp/dvc.h>
#include <freerdp/types.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#ifdef WITH_DEBUG_DVC
-#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__)
+#define DEBUG_DVC(fmt, ...) CLOG_CLASS(DVC, fmt, ## __VA_ARGS__)
#else
-#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
+#define DEBUG_DVC(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif
}
else
{
- DEBUG_WARN("Maximum DVC listener number reached.");
+ CLOG_ERR("Maximum DVC listener number reached.");
return 1;
}
}
}
else
{
- DEBUG_WARN("event_type %d push failed.", GetMessageType(pEvent->id));
+ CLOG_ERR("event_type %d push failed.", GetMessageType(pEvent->id));
}
return status;
}
else
{
- DEBUG_WARN("Maximum DVC plugin number reached.");
+ CLOG_ERR("Maximum DVC plugin number reached.");
return 1;
}
}
DVCMAN_ENTRY_POINTS entryPoints;
PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL;
- fprintf(stderr, "Loading Dynamic Virtual Channel %s\n", args->argv[0]);
+ CLOG_ERR( "Loading Dynamic Virtual Channel %s\n", args->argv[0]);
pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[0],
NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC);
}
else
{
- DEBUG_WARN("channel rejected by plugin");
+ CLOG_ERR("channel rejected by plugin");
free(channel);
return 1;
if (!channel)
{
- DEBUG_WARN("ChannelId %d not found!", ChannelId);
+ CLOG_ERR("ChannelId %d not found!", ChannelId);
return 1;
}
if (!channel)
{
- DEBUG_WARN("ChannelId %d not found!", ChannelId);
+ CLOG_ERR("ChannelId %d not found!", ChannelId);
return 1;
}
if (!channel)
{
- DEBUG_WARN("ChannelId %d not found!", ChannelId);
+ CLOG_ERR("ChannelId %d not found!", ChannelId);
return 1;
}
Stream_Release(channel->dvc_data);
channel->dvc_data = StreamPool_Take(channel->dvcman->pool, length);
- Stream_AddRef(channel->dvc_data);
+ channel->dvc_data_length = length;
return 0;
}
if (!channel)
{
- DEBUG_WARN("ChannelId %d not found!", ChannelId);
+ CLOG_ERR("ChannelId %d not found!", ChannelId);
return 1;
}
/* Fragmented data */
if (Stream_GetPosition(channel->dvc_data) + dataSize > (UINT32) Stream_Capacity(channel->dvc_data))
{
- DEBUG_WARN("data exceeding declared length!");
+ CLOG_ERR("data exceeding declared length!");
Stream_Release(channel->dvc_data);
channel->dvc_data = NULL;
return 1;
Stream_Write(channel->dvc_data, Stream_Pointer(data), dataSize);
- if (((size_t) Stream_GetPosition(channel->dvc_data)) >= Stream_Capacity(channel->dvc_data))
+ if (((size_t) Stream_GetPosition(channel->dvc_data)) >= channel->dvc_data_length)
{
Stream_SealLength(channel->dvc_data);
Stream_SetPosition(channel->dvc_data, 0);
IWTSVirtualChannelCallback* channel_callback;
wStream* dvc_data;
+ UINT32 dvc_data_length;
CRITICAL_SECTION lock;
};
typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL;
#endif
#ifdef HAVE_FCNTL_H
+#define __USE_GNU /* for O_PATH */
#include <fcntl.h>
+#undef __USE_GNU
+#endif
+
+#ifdef _WIN32
+#pragma comment(lib, "Shlwapi.lib")
+#include <Shlwapi.h>
#endif
#include "drive_file.h"
if (STAT(file->fullpath, &st) == 0)
{
file->is_dir = (S_ISDIR(st.st_mode) ? TRUE : FALSE);
+ if (!file->is_dir && !S_ISREG(st.st_mode))
+ {
+ file->err = EPERM;
+ return TRUE;
+ }
#ifndef WIN32
if (st.st_size > (unsigned long) 0x07FFFFFFF)
largeFile = TRUE;
return NULL;
}
+#if defined(__linux__) && defined(O_PATH)
+ if (file->fd < 0 && file->err == EACCES)
+ {
+ /**
+ * We have no access permissions for the file or directory but if the
+ * peer is only interested in reading the object's attributes we can try
+ * to obtain a file descriptor who's only purpose is to perform
+ * operations that act purely at the file descriptor level.
+ * See open(2)
+ **/
+ {
+ if ((file->fd = OPEN(file->fullpath, O_PATH)) >= 0)
+ {
+ file->err = 0;
+ }
+ }
+ }
+#endif
+
return file;
}
return TRUE;
}
+int dir_empty(const char *path)
+{
+#ifdef _WIN32
+ return PathIsDirectoryEmptyA(path);
+#else
+ struct dirent *dp;
+ int empty = 1;
+
+ DIR *dir = opendir(path);
+ if (dir == NULL) //Not a directory or doesn't exist
+ return 1;
+
+ while ((dp = readdir(dir)) != NULL) {
+ if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
+ continue; /* Skip . and .. */
+
+ empty = 0;
+ break;
+ }
+ closedir(dir);
+ return empty;
+#endif
+}
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, wStream* input)
{
char* s = NULL;
int status;
char* fullpath;
struct STAT st;
+#if defined(__linux__) && !defined(ANDROID)
+ struct timespec tv[2];
+#else
struct timeval tv[2];
+#endif
UINT64 LastWriteTime;
UINT32 FileAttributes;
UINT32 FileNameLength;
return FALSE;
tv[0].tv_sec = st.st_atime;
- tv[0].tv_usec = 0;
tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime);
- tv[1].tv_usec = 0;
#ifndef WIN32
/* TODO on win32 */
#ifdef ANDROID
+ tv[0].tv_usec = 0;
+ tv[1].tv_usec = 0;
utimes(file->fullpath, tv);
+#elif defined (__linux__)
+ tv[0].tv_nsec = 0;
+ tv[1].tv_nsec = 0;
+ futimens(file->fd, tv);
#else
+ tv[0].tv_usec = 0;
+ tv[1].tv_usec = 0;
futimes(file->fd, tv);
#endif
case FileDispositionInformation:
/* http://msdn.microsoft.com/en-us/library/cc232098.aspx */
/* http://msdn.microsoft.com/en-us/library/cc241371.aspx */
+ if (file->is_dir && !dir_empty(file->fullpath))
+ break;
+
if (Length)
Stream_Read_UINT8(input, file->delete_pending);
else
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, wStream* input);
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
const char* path, wStream* output);
+int dir_empty(const char *path);
extern UINT sys_code_page;
}
+ if (file->is_dir && !dir_empty(file->fullpath))
+ irp->IoStatus = STATUS_DIRECTORY_NOT_EMPTY;
+
Stream_Write_UINT32(irp->output, Length);
irp->Complete(irp);
#include <string.h>
#include <winpr/crt.h>
+#include <winpr/stream.h>
#include <winpr/cmdline.h>
#include <freerdp/addin.h>
-#include <winpr/stream.h>
-
#include "echo_main.h"
typedef struct _ECHO_LISTENER_CALLBACK ECHO_LISTENER_CALLBACK;
static int echo_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream *data)
{
- int error;
+ int status;
ECHO_CHANNEL_CALLBACK* callback = (ECHO_CHANNEL_CALLBACK*) pChannelCallback;
- BYTE *pBuffer = Stream_Pointer(data);
- UINT32 cbSize = Stream_GetRemainingLength(data);
-
-#ifdef WITH_DEBUG_DVC
- int i = 0;
- char* debug_buffer;
- char* p;
-
- if (cbSize > 0)
- {
- debug_buffer = (char*) malloc(3 * cbSize);
- ZeroMemory(debug_buffer, 3 * cbSize);
-
- p = debug_buffer;
-
- for (i = 0; i < (int) (cbSize - 1); i++)
- {
- sprintf(p, "%02x ", pBuffer[i]);
- p += 3;
- }
- sprintf(p, "%02x", pBuffer[i]);
-
- DEBUG_DVC("ECHO %d: %s", cbSize, debug_buffer);
- free(debug_buffer);
- }
-#endif
+ BYTE* pBuffer = Stream_Pointer(data);
+ UINT32 cbSize = Stream_GetRemainingLength(data);
/* echo back what we have received. ECHO does not have any message IDs. */
- error = callback->channel->Write(callback->channel, cbSize, pBuffer, NULL);
+ status = callback->channel->Write(callback->channel, cbSize, pBuffer, NULL);
- return error;
+ return status;
}
static int echo_on_close(IWTSVirtualChannelCallback* pChannelCallback)
{
ECHO_CHANNEL_CALLBACK* callback = (ECHO_CHANNEL_CALLBACK*) pChannelCallback;
- DEBUG_DVC("");
-
free(callback);
return 0;
ECHO_CHANNEL_CALLBACK* callback;
ECHO_LISTENER_CALLBACK* listener_callback = (ECHO_LISTENER_CALLBACK*) pListenerCallback;
- DEBUG_DVC("");
+ callback = (ECHO_CHANNEL_CALLBACK*) calloc(1, sizeof(ECHO_CHANNEL_CALLBACK));
- callback = (ECHO_CHANNEL_CALLBACK*) malloc(sizeof(ECHO_CHANNEL_CALLBACK));
- ZeroMemory(callback, sizeof(ECHO_CHANNEL_CALLBACK));
+ if (!callback)
+ return -1;
callback->iface.OnDataReceived = echo_on_data_received;
callback->iface.OnClose = echo_on_close;
{
ECHO_PLUGIN* echo = (ECHO_PLUGIN*) pPlugin;
- DEBUG_DVC("");
+ echo->listener_callback = (ECHO_LISTENER_CALLBACK*) calloc(1, sizeof(ECHO_LISTENER_CALLBACK));
- echo->listener_callback = (ECHO_LISTENER_CALLBACK*) malloc(sizeof(ECHO_LISTENER_CALLBACK));
- ZeroMemory(echo->listener_callback, sizeof(ECHO_LISTENER_CALLBACK));
+ if (!echo->listener_callback)
+ return -1;
echo->listener_callback->iface.OnNewChannelConnection = echo_on_new_channel_connection;
echo->listener_callback->plugin = pPlugin;
{
ECHO_PLUGIN* echo = (ECHO_PLUGIN*) pPlugin;
- DEBUG_DVC("");
-
- free(echo);
+ if (echo)
+ {
+ free(echo);
+ }
return 0;
}
-#ifdef STATIC_CHANNELS
-#define DVCPluginEntry echo_DVCPluginEntry
-#endif
-
-int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
+int echo_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
- int error = 0;
+ int status = 0;
ECHO_PLUGIN* echo;
echo = (ECHO_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "echo");
- if (echo == NULL)
+ if (!echo)
{
- echo = (ECHO_PLUGIN*) malloc(sizeof(ECHO_PLUGIN));
- ZeroMemory(echo, sizeof(ECHO_PLUGIN));
+ echo = (ECHO_PLUGIN*) calloc(1, sizeof(ECHO_PLUGIN));
+
+ if (!echo)
+ return -1;
echo->iface.Initialize = echo_plugin_initialize;
echo->iface.Connected = NULL;
echo->iface.Disconnected = NULL;
echo->iface.Terminated = echo_plugin_terminated;
- error = pEntryPoints->RegisterPlugin(pEntryPoints, "echo", (IWTSPlugin*) echo);
+ status = pEntryPoints->RegisterPlugin(pEntryPoints, "echo", (IWTSPlugin*) echo);
}
- return error;
+ return status;
}
#include <freerdp/dvc.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#ifdef WITH_DEBUG_DVC
-#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__)
+#define DEBUG_DVC(fmt, ...) CLOG_CLASS(DVC, fmt, ## __VA_ARGS__)
#else
-#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
+#define DEBUG_DVC(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif /* __ECHO_MAIN_H */
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/stream.h>
+#include <winpr/sysinfo.h>
#include <freerdp/server/echo.h>
break;
}
- IFCALL(echo->context.Response, &echo->context, (PCHAR) Stream_Buffer(s), BytesReturned);
+ IFCALL(echo->context.Response, &echo->context, (BYTE *) Stream_Buffer(s), BytesReturned);
}
Stream_Free(s, TRUE);
define_channel_client("encomsp")
+include_directories(..)
+
set(${MODULE_PREFIX}_SRCS
encomsp_main.c
encomsp_main.h)
#include <winpr/crt.h>
#include <winpr/print.h>
+#include <freerdp/channels/log.h>
#include <freerdp/client/encomsp.h>
#include "encomsp_main.h"
-EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp)
-{
- EncomspClientContext* pInterface;
- pInterface = (EncomspClientContext*) encomsp->channelEntryPoints.pInterface;
- return pInterface;
-}
-
-int encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s)
-{
- UINT32 status = 0;
-
- if (!encomsp)
- return -1;
-
-#if 0
- printf("EncomspWrite (%d)\n", Stream_Length(s));
- winpr_HexDump(Stream_Buffer(s), Stream_Length(s));
-#endif
-
- status = encomsp->channelEntryPoints.pVirtualChannelWrite(encomsp->OpenHandle,
- Stream_Buffer(s), (UINT32) Stream_Length(s), s);
-
- if (status != CHANNEL_RC_OK)
- {
- fprintf(stderr, "encomsp_virtual_channel_write: VirtualChannelWrite failed %d\n", status);
- return -1;
- }
-
- return 1;
-}
-
-int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
{
if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE)
return -1;
return 1;
}
-int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
{
Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */
Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */
return 1;
}
-int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str)
+static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str)
{
ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING));
if (str->cchString > 1024)
return -1;
- if (Stream_GetRemainingLength(s) < (str->cchString * 2))
+ if (Stream_GetRemainingLength(s) < (size_t) (str->cchString * 2))
return -1;
Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */
return 1;
}
-int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp)
+{
+ EncomspClientContext* pInterface;
+ pInterface = (EncomspClientContext*) encomsp->channelEntryPoints.pInterface;
+ return pInterface;
+}
+
+int encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s)
+{
+ UINT32 status = 0;
+
+ if (!encomsp)
+ return -1;
+
+#if 0
+ printf("EncomspWrite (%d)\n", Stream_Length(s));
+ winpr_HexDump(Stream_Buffer(s), Stream_Length(s));
+#endif
+
+ status = encomsp->channelEntryPoints.pVirtualChannelWrite(encomsp->OpenHandle,
+ Stream_Buffer(s), (UINT32) Stream_Length(s), s);
+
+ if (status != CHANNEL_RC_OK)
+ {
+ fprintf(stderr, "encomsp_virtual_channel_write: VirtualChannelWrite failed %d\n", status);
+ return -1;
+ }
+
+ return 1;
+}
+
+static int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
return 1;
}
-int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
return 1;
}
-int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
return 1;
}
-int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
return 1;
}
-int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
return 1;
}
-int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
return 1;
}
-int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
return 1;
}
-int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
return 1;
}
-int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
return 1;
}
-int encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu)
+static int encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu)
{
wStream* s;
encomspPlugin* encomsp;
return 1;
}
-int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
return 1;
}
-int encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static int encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
EncomspClientContext* context;
if ((beg + header->Length) > end)
{
- if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1;
Stream_SetPosition(s, (beg + header->Length));
if (encomsp_read_header(s, &header) < 0)
return -1;
- //printf("EncomspReceive: Type: %d Length: %d\n", header.Type, header.Length);
+ //CLOG_DBG("EncomspReceive: Type: %d Length: %d\n", header.Type, header.Length);
switch (header.Type)
{
if (status != CHANNEL_RC_OK)
{
Stream_Free(s, TRUE);
- fprintf(stderr, "encomsp_send: VirtualChannelWrite failed %d\n", status);
+ CLOG_ERR( "encomsp_send: VirtualChannelWrite failed %d\n", status);
}
return status;
{
if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
{
- fprintf(stderr, "encomsp_plugin_process_received: read error\n");
+ CLOG_ERR( "encomsp_plugin_process_received: read error\n");
}
encomsp->data_in = NULL;
if (!encomsp)
{
- fprintf(stderr, "encomsp_virtual_channel_open_event: error no match\n");
+ CLOG_ERR( "encomsp_virtual_channel_open_event: error no match\n");
return;
}
if (status != CHANNEL_RC_OK)
{
- fprintf(stderr, "encomsp_virtual_channel_event_connected: open failed: status: %d\n", status);
+ CLOG_ERR( "encomsp_virtual_channel_event_connected: open failed: status: %d\n", status);
return;
}
if (!encomsp)
{
- fprintf(stderr, "encomsp_virtual_channel_init_event: error no match\n");
+ CLOG_ERR( "encomsp_virtual_channel_init_event: error no match\n");
return;
}
define_channel_server("encomsp")
+include_directories(..)
+
set(${MODULE_PREFIX}_SRCS
encomsp_main.c
encomsp_main.h)
#include "encomsp_main.h"
+static int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
+{
+ if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE)
+ return -1;
+
+ Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */
+ Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */
+
+ return 1;
+}
+
+#if 0
+
+static int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
+{
+ Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */
+ Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */
+
+ return 1;
+}
+
+static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str)
+{
+ ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING));
+
+ if (Stream_GetRemainingLength(s) < 2)
+ return -1;
+
+ Stream_Read_UINT16(s, str->cchString); /* cchString (2 bytes) */
+
+ if (str->cchString > 1024)
+ return -1;
+
+ if (Stream_GetRemainingLength(s) < (str->cchString * 2))
+ return -1;
+
+ Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */
+
+ return 1;
+}
+
+#endif
+
+static int encomsp_recv_change_participant_control_level_pdu(EncomspServerContext* context, wStream* s, ENCOMSP_ORDER_HEADER* header)
+{
+ int beg, end;
+ ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu;
+
+ beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
+
+ CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
+
+ if (Stream_GetRemainingLength(s) < 6)
+ return -1;
+
+ Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */
+ Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */
+
+ end = (int) Stream_GetPosition(s);
+
+ if ((beg + header->Length) < end)
+ return -1;
+
+ if ((beg + header->Length) > end)
+ {
+ if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
+ return -1;
+
+ Stream_SetPosition(s, (beg + header->Length));
+ }
+
+ if (context->ChangeParticipantControlLevel)
+ {
+ return context->ChangeParticipantControlLevel(context, &pdu);
+ }
+
+ return 1;
+}
+
static int encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s)
{
- return 0;
+ int status = 1;
+ ENCOMSP_ORDER_HEADER header;
+
+ while (Stream_GetRemainingLength(s) > 0)
+ {
+ if (encomsp_read_header(s, &header) < 0)
+ return -1;
+
+ printf("EncomspReceive: Type: %d Length: %d\n", header.Type, header.Length);
+
+ switch (header.Type)
+ {
+ case ODTYPE_PARTICIPANT_CTRL_CHANGED:
+ status = encomsp_recv_change_participant_control_level_pdu(context, s, &header);
+ break;
+
+ default:
+ status = -1;
+ break;
+ }
+
+ if (status < 0)
+ return -1;
+ }
+
+ return status;
}
static void* encomsp_server_thread(void* arg)
HANDLE events[8];
HANDLE ChannelEvent;
DWORD BytesReturned;
+ ENCOMSP_ORDER_HEADER* header;
EncomspServerContext* context;
context = (EncomspServerContext*) arg;
break;
}
- if (0)
+ if (Stream_GetPosition(s) >= ENCOMSP_ORDER_HEADER_SIZE)
{
- encomsp_server_receive_pdu(context, s);
+ header = (ENCOMSP_ORDER_HEADER*) Stream_Buffer(s);
+
+ if (header->Length >= Stream_GetPosition(s))
+ {
+ Stream_SealLength(s);
+ Stream_SetPosition(s, 0);
+ encomsp_server_receive_pdu(context, s);
+ Stream_SetPosition(s, 0);
+ }
}
}
rdpPrinterDriver* printer_win_get_driver(void);
#ifdef WITH_DEBUG_WINPR
-#define DEBUG_WINPR(fmt, ...) DEBUG_CLASS(WINPR, fmt, ## __VA_ARGS__)
+#define DEBUG_WINPR(fmt, ...) CLOG_CLASS(WINPR, fmt, ## __VA_ARGS__)
#else
-#define DEBUG_WINPR(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
+#define DEBUG_WINPR(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif
#include <winpr/crt.h>
#include <freerdp/utils/rail.h>
+#include <freerdp/channels/log.h>
#include "rail_orders.h"
}
default:
- fprintf(stderr, "Unknown RAIL PDU order reveived.");
+ CLOG_ERR( "Unknown RAIL PDU order reveived.");
break;
}
#include <freerdp/types.h>
#include <freerdp/addin.h>
#include <freerdp/client/channels.h>
+#include <freerdp/channels/log.h>
#include "rdpdr_main.h"
if (!ServiceName)
return FALSE;
- fprintf(stderr, "Loading device service %s (static)\n", ServiceName);
+ CLOG_ERR( "Loading device service %s (static)\n", ServiceName);
entry = (PDEVICE_SERVICE_ENTRY) freerdp_load_channel_addin_entry(ServiceName, NULL, "DeviceServiceEntry", 0);
if (!entry)
#include <freerdp/types.h>
#include <freerdp/constants.h>
+#include <freerdp/channels/log.h>
#include <freerdp/channels/rdpdr.h>
#ifdef _WIN32
if (mfd < 0)
{
- fprintf(stderr, "ERROR: Unable to open /proc/mounts.");
+ CLOG_ERR( "ERROR: Unable to open /proc/mounts.");
return NULL;
}
count++;
- fprintf(stderr, "registered device #%d: %s (type=%d id=%d)\n",
+ CLOG_ERR( "registered device #%d: %s (type=%d id=%d)\n",
count, device->name, device->type, device->id);
}
}
if (status != CHANNEL_RC_OK)
{
Stream_Free(s, TRUE);
- fprintf(stderr, "rdpdr_send: VirtualChannelWrite failed %d\n", status);
+ CLOG_ERR( "rdpdr_send: VirtualChannelWrite failed %d\n", status);
}
return status;
{
if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
{
- fprintf(stderr, "svc_plugin_process_received: read error\n");
+ CLOG_ERR( "svc_plugin_process_received: read error\n");
}
rdpdr->data_in = NULL;
if (!rdpdr)
{
- fprintf(stderr, "rdpdr_virtual_channel_open_event: error no match\n");
+ CLOG_ERR( "rdpdr_virtual_channel_open_event: error no match\n");
return;
}
if (status != CHANNEL_RC_OK)
{
- fprintf(stderr, "rdpdr_virtual_channel_event_connected: open failed: status: %d\n", status);
+ CLOG_ERR( "rdpdr_virtual_channel_event_connected: open failed: status: %d\n", status);
return;
}
if (!rdpdr)
{
- fprintf(stderr, "rdpdr_virtual_channel_init_event: error no match\n");
+ CLOG_ERR( "rdpdr_virtual_channel_init_event: error no match\n");
return;
}
#include <winpr/print.h>
#include <winpr/stream.h>
+#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)
BOOL status;
RDPDR_HEADER header;
ULONG written;
-
- printf("RdpdrServerSendAnnounceRequest\n");
-
+ 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;
}
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) */
-
- printf("Client Announce Response: VersionMajor: 0x%04X VersionMinor: 0x%04X ClientId: 0x%04X\n",
- VersionMajor, VersionMinor, ClientId);
-
+ CLOG_DBG("Client Announce Response: VersionMajor: 0x%04X VersionMinor: 0x%04X ClientId: 0x%04X\n",
+ VersionMajor, VersionMinor, ClientId);
context->priv->ClientId = ClientId;
-
return 0;
}
{
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) */
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
{
}
Stream_Seek(s, ComputerNameLen);
-
- printf("ClientComputerName: %s\n", context->priv->ClientComputerName);
-
+ CLOG_DBG("ClientComputerName: %s\n", context->priv->ClientComputerName);
return 0;
}
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) */
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;
}
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 */
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 */
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) */
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;
}
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;
}
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;
}
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;
}
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;
}
RDPDR_HEADER header;
UINT16 numCapabilities;
ULONG written;
-
- printf("RdpdrServerSendCoreCapabilityRequest\n");
-
+ 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;
}
int i;
UINT16 numCapabilities;
RDPDR_CAPABILITY_HEADER capabilityHeader;
-
Stream_Read_UINT16(s, numCapabilities); /* numCapabilities (2 bytes) */
Stream_Seek_UINT16(s); /* Padding (2 bytes) */
break;
default:
- printf("Unknown capabilityType %d\n", capabilityHeader.CapabilityType);
+ CLOG_DBG("Unknown capabilityType %d\n", capabilityHeader.CapabilityType);
Stream_Seek(s, capabilityHeader.CapabilityLength - RDPDR_CAPABILITY_HEADER_LENGTH);
break;
}
BOOL status;
RDPDR_HEADER header;
ULONG written;
-
- printf("RdpdrServerSendClientIdConfirm\n");
-
+ 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;
}
UINT32 DeviceId;
char PreferredDosName[9];
UINT32 DeviceDataLength;
-
PreferredDosName[8] = 0;
-
Stream_Read_UINT32(s, DeviceCount); /* DeviceCount (4 bytes) */
-
- printf("%s: DeviceCount: %d\n", __FUNCTION__, DeviceCount);
+ CLOG_DBG("%s: DeviceCount: %d\n", __FUNCTION__, DeviceCount);
for (i = 0; i < DeviceCount; i++)
{
Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */
Stream_Read(s, PreferredDosName, 8); /* PreferredDosName (8 bytes) */
Stream_Read_UINT32(s, DeviceDataLength); /* DeviceDataLength (4 bytes) */
-
- printf("Device %d Name: %s Id: 0x%04X DataLength: %d\n",
- i, PreferredDosName, DeviceId, DeviceDataLength);
+ CLOG_DBG("Device %d Name: %s Id: 0x%04X DataLength: %d\n",
+ i, PreferredDosName, DeviceId, DeviceDataLength);
switch (DeviceId)
{
BOOL status;
RDPDR_HEADER header;
ULONG written;
-
- printf("%s\n", __FUNCTION__);
-
+ 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)
{
- printf("RdpdrServerReceivePdu: Component: 0x%04X PacketId: 0x%04X\n",
- header->Component, header->PacketId);
-
- winpr_HexDump(Stream_Buffer(s), Stream_Length(s));
+ CLOG_DBG("RdpdrServerReceivePdu: Component: 0x%04X PacketId: 0x%04X\n",
+ header->Component, header->PacketId);
+ winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), Stream_Length(s));
if (header->Component == RDPDR_CTYP_CORE)
{
if (context->priv->UserLoggedOnPdu)
rdpdr_server_send_user_logged_on(context);
+
break;
case PAKID_CORE_DEVICELIST_ANNOUNCE:
}
else
{
- printf("Unknown RDPDR_HEADER.Component: 0x%04X\n", header->Component);
+ CLOG_DBG("Unknown RDPDR_HEADER.Component: 0x%04X\n", header->Component);
return -1;
}
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)
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)
}
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;
}
{
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;
}
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;
}
}
status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL);
#ifdef WITH_DEBUG_RDPEI
- fprintf(stderr, "rdpei_send_pdu: eventId: %d (%s) length: %d status: %d\n",
+ CLOG_ERR( "rdpei_send_pdu: eventId: %d (%s) length: %d status: %d\n",
eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength, status);
#endif
void rdpei_print_contact_flags(UINT32 contactFlags)
{
if (contactFlags & CONTACT_FLAG_DOWN)
- printf(" CONTACT_FLAG_DOWN");
+ CLOG_DBG(" CONTACT_FLAG_DOWN");
if (contactFlags & CONTACT_FLAG_UPDATE)
- printf(" CONTACT_FLAG_UPDATE");
+ CLOG_DBG(" CONTACT_FLAG_UPDATE");
if (contactFlags & CONTACT_FLAG_UP)
- printf(" CONTACT_FLAG_UP");
+ CLOG_DBG(" CONTACT_FLAG_UP");
if (contactFlags & CONTACT_FLAG_INRANGE)
- printf(" CONTACT_FLAG_INRANGE");
+ CLOG_DBG(" CONTACT_FLAG_INRANGE");
if (contactFlags & CONTACT_FLAG_INCONTACT)
- printf(" CONTACT_FLAG_INCONTACT");
+ CLOG_DBG(" CONTACT_FLAG_INCONTACT");
if (contactFlags & CONTACT_FLAG_CANCELED)
- printf(" CONTACT_FLAG_CANCELED");
+ CLOG_DBG(" CONTACT_FLAG_CANCELED");
}
int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
RDPINPUT_CONTACT_DATA* contact;
#ifdef WITH_DEBUG_RDPEI
- printf("contactCount: %d\n", frame->contactCount);
- printf("frameOffset: 0x%08X\n", (UINT32) frame->frameOffset);
+ CLOG_DBG("contactCount: %d\n", frame->contactCount);
+ CLOG_DBG("frameOffset: 0x%08X\n", (UINT32) frame->frameOffset);
#endif
rdpei_write_2byte_unsigned(s, frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */
contact->contactRectBottom = contact->y + rectSize;
#ifdef WITH_DEBUG_RDPEI
- printf("contact[%d].contactId: %d\n", index, contact->contactId);
- printf("contact[%d].fieldsPresent: %d\n", index, contact->fieldsPresent);
- printf("contact[%d].x: %d\n", index, contact->x);
- printf("contact[%d].y: %d\n", index, contact->y);
- printf("contact[%d].contactFlags: 0x%04X", index, contact->contactFlags);
+ CLOG_DBG("contact[%d].contactId: %d\n", index, contact->contactId);
+ CLOG_DBG("contact[%d].fieldsPresent: %d\n", index, contact->fieldsPresent);
+ CLOG_DBG("contact[%d].x: %d\n", index, contact->x);
+ CLOG_DBG("contact[%d].y: %d\n", index, contact->y);
+ CLOG_DBG("contact[%d].contactFlags: 0x%04X", index, contact->contactFlags);
rdpei_print_contact_flags(contact->contactFlags);
- printf("\n");
+ CLOG_DBG("\n");
#endif
Stream_Write_UINT8(s, contact->contactId); /* contactId (1 byte) */
#if 0
if (protocolVersion != RDPINPUT_PROTOCOL_V10)
{
- fprintf(stderr, "Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion);
+ CLOG_ERR( "Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion);
return -1;
}
#endif
Stream_Read_UINT32(s, pduLength); /* pduLength (4 bytes) */
#ifdef WITH_DEBUG_RDPEI
- fprintf(stderr, "rdpei_recv_pdu: eventId: %d (%s) length: %d\n",
+ CLOG_ERR( "rdpei_recv_pdu: eventId: %d (%s) length: %d\n",
eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength);
#endif
#include <freerdp/dvc.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#include <freerdp/client/rdpei.h>
typedef struct _RDPINPUT_CONTACT_POINT RDPINPUT_CONTACT_POINT;
#ifdef WITH_DEBUG_DVC
-#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__)
+#define DEBUG_DVC(fmt, ...) CLOG_CLASS(DVC, fmt, ## __VA_ARGS__)
#else
-#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
+#define DEBUG_DVC(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif /* FREERDP_CHANNEL_RDPEI_CLIENT_MAIN_H */
#include <winpr/crt.h>
#include <winpr/stream.h>
+#include "rdpgfx_common.h"
+
#include "rdpgfx_codec.h"
int rdpgfx_decode_uncompressed(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
return 1;
}
+int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, RDPGFX_H264_METABLOCK* meta)
+{
+ UINT32 index;
+ RDPGFX_RECT16* regionRect;
+ RDPGFX_H264_QUANT_QUALITY* quantQualityVal;
+
+ if (Stream_GetRemainingLength(s) < 4)
+ return -1;
+
+ Stream_Read_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */
+
+ if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 8))
+ return -1;
+
+ meta->regionRects = (RDPGFX_RECT16*) malloc(meta->numRegionRects * sizeof(RDPGFX_RECT16));
+
+ if (!meta->regionRects)
+ return -1;
+
+ meta->quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(meta->numRegionRects * sizeof(RDPGFX_H264_QUANT_QUALITY));
+
+ if (!meta->quantQualityVals)
+ return -1;
+
+#if 0
+ printf("H264_METABLOCK: numRegionRects: %d\n", (int) meta->numRegionRects);
+#endif
+
+ for (index = 0; index < meta->numRegionRects; index++)
+ {
+ regionRect = &(meta->regionRects[index]);
+ rdpgfx_read_rect16(s, regionRect);
+
+#if 0
+ printf("regionRects[%d]: left: %d top: %d right: %d bottom: %d\n",
+ index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom);
+#endif
+ }
+
+ if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 2))
+ return -1;
+
+ for (index = 0; index < meta->numRegionRects; index++)
+ {
+ quantQualityVal = &(meta->quantQualityVals[index]);
+ Stream_Read_UINT8(s, quantQualityVal->qpVal); /* qpVal (1 byte) */
+ Stream_Read_UINT8(s, quantQualityVal->qualityVal); /* qualityVal (1 byte) */
+
+ quantQualityVal->qp = quantQualityVal->qpVal & 0x3F;
+ quantQualityVal->r = (quantQualityVal->qpVal >> 6) & 1;
+ quantQualityVal->p = (quantQualityVal->qpVal >> 7) & 1;
+
+#if 0
+ printf("quantQualityVals[%d]: qp: %d r: %d p: %d qualityVal: %d\n",
+ index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p, quantQualityVal->qualityVal);
+#endif
+ }
+
+ return 1;
+}
+
int rdpgfx_decode_h264(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
{
+ int status;
+ wStream* s;
+ RDPGFX_H264_BITMAP_STREAM h264;
+ RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
+
+ s = Stream_New(cmd->data, cmd->length);
+
+ if (!s)
+ return -1;
+
+ status = rdpgfx_read_h264_metablock(gfx, s, &(h264.meta));
+
+ if (status < 0)
+ return -1;
+
+ h264.data = Stream_Pointer(s);
+ h264.length = (UINT32) Stream_GetRemainingLength(s);
+
+ Stream_Free(s, FALSE);
+
+ cmd->extra = (void*) &h264;
+
+ if (context && context->SurfaceCommand)
+ {
+ context->SurfaceCommand(context, cmd);
+ }
+
+ free(h264.meta.regionRects);
+ free(h264.meta.quantQualityVals);
+
return 1;
}
#include <winpr/collections.h>
#include <freerdp/addin.h>
+#include <freerdp/channels/log.h>
#include "rdpgfx_common.h"
#include "rdpgfx_codec.h"
Stream_Read_UINT32(s, capsSet.version); /* version (4 bytes) */
Stream_Read_UINT32(s, capsDataLength); /* capsDataLength (4 bytes) */
Stream_Read_UINT32(s, capsSet.flags); /* capsData (4 bytes) */
+
+ /*TODO: interpret this answer*/
WLog_Print(gfx->log, WLOG_DEBUG, "RecvCapsConfirmPdu: version: 0x%04X flags: 0x%04X",
capsSet.version, capsSet.flags);
pad = 340 - (RDPGFX_HEADER_SIZE + 12 + (pdu.monitorCount * 20));
- if (Stream_GetRemainingLength(s) < pad)
+ if (Stream_GetRemainingLength(s) < (size_t) pad)
return -1;
Stream_Seek(s, pad); /* pad (total size is 340 bytes) */
Stream_Read_UINT16(s, pdu.importedEntriesCount); /* cacheSlot (2 bytes) */
- if (Stream_GetRemainingLength(s) < (pdu.importedEntriesCount * 2))
+ if (Stream_GetRemainingLength(s) < (size_t) (pdu.importedEntriesCount * 2))
return -1;
pdu.cacheSlots = (UINT16*) calloc(pdu.importedEntriesCount, sizeof(UINT16));
cmd.length = pdu.bitmapDataLength;
cmd.data = pdu.bitmapData;
- if (context && context->SurfaceCommand)
+ if (cmd.codecId == RDPGFX_CODECID_H264)
{
- context->SurfaceCommand(context, &cmd);
+ rdpgfx_decode(gfx, &cmd);
+ }
+ else
+ {
+ if (context && context->SurfaceCommand)
+ {
+ context->SurfaceCommand(context, &cmd);
+ }
}
return 1;
rdpgfx_read_color32(s, &(pdu.fillPixel)); /* fillPixel (4 bytes) */
Stream_Read_UINT16(s, pdu.fillRectCount); /* fillRectCount (2 bytes) */
- if (Stream_GetRemainingLength(s) < (pdu.fillRectCount * 8))
+ if (Stream_GetRemainingLength(s) < (size_t) (pdu.fillRectCount * 8))
return -1;
pdu.fillRects = (RDPGFX_RECT16*) calloc(pdu.fillRectCount, sizeof(RDPGFX_RECT16));
{
context->SolidFill(context, &pdu);
}
+
+ free(pdu.fillRects);
return 1;
}
rdpgfx_read_rect16(s, &(pdu.rectSrc)); /* rectSrc (8 bytes ) */
Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */
- if (Stream_GetRemainingLength(s) < (pdu.destPtsCount * 4))
+ if (Stream_GetRemainingLength(s) < (size_t) (pdu.destPtsCount * 4))
return -1;
pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16));
context->SurfaceToSurface(context, &pdu);
}
+ free(pdu.destPts);
+
return 1;
}
Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */
- if (Stream_GetRemainingLength(s) < (pdu.destPtsCount * 4))
+ if (Stream_GetRemainingLength(s) < (size_t) (pdu.destPtsCount * 4))
return -1;
pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16));
if (status < 0)
{
- fprintf(stderr, "Error while parsing GFX cmdId: %s (0x%04X)\n",
+ CLOG_ERR( "Error while parsing GFX cmdId: %s (0x%04X)\n",
rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId);
return -1;
}
if (end != (beg + header.pduLength))
{
- fprintf(stderr, "Unexpected gfx pdu end: Actual: %d, Expected: %d\n",
+ CLOG_ERR( "Unexpected gfx pdu end: Actual: %d, Expected: %d\n",
end, (beg + header.pduLength));
Stream_SetPosition(s, (beg + header.pduLength));
if (status < 0)
{
- printf("zgfx_decompress failure! status: %d\n", status);
+ CLOG_DBG("zgfx_decompress failure! status: %d\n", status);
return 0;
}
s = Stream_New(pDstData, DstSize);
- while (Stream_GetPosition(s) < Stream_Length(s))
+ while (((size_t) Stream_GetPosition(s)) < Stream_Length(s))
{
status = rdpgfx_recv_pdu(callback, s);
}
Stream_Free(s, TRUE);
+
+ //free(Stream_Buffer(data));
+ //Stream_Free(data,TRUE);
return status;
}
return pData;
}
-#ifdef STATIC_CHANNELS
-#define DVCPluginEntry rdpgfx_DVCPluginEntry
-#endif
-
-int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
+int rdpgfx_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
int status = 0;
RDPGFX_PLUGIN* gfx;
return -1;
gfx->log = WLog_Get("com.freerdp.gfx.client");
+#if 0
+ WLog_SetLogLevel(gfx->log, WLOG_DEBUG);
+#endif
+
gfx->settings = (rdpSettings*) pEntryPoints->GetRdpSettings(pEntryPoints);
gfx->iface.Initialize = rdpgfx_plugin_initialize;
gfx->zgfx = zgfx_context_new(FALSE);
+ if (!gfx->zgfx)
+ return -1;
+
status = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpgfx", (IWTSPlugin*) gfx);
}
#include <freerdp/types.h>
#include <freerdp/codec/dsp.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#include "rdpsnd_main.h"
#define SND_PCM_CHECK(_func, _status) \
if (_status < 0) \
{ \
- fprintf(stderr, "%s: %d\n", _func, _status); \
+ CLOG_ERR( "%s: %d\n", _func, _status); \
return -1; \
}
if (alsa->buffer_size > buffer_size_max)
{
- fprintf(stderr, "Warning: requested sound buffer size %d, got %d instead\n",
+ CLOG_ERR( "Warning: requested sound buffer size %d, got %d instead\n",
(int) alsa->buffer_size, (int) buffer_size_max);
alsa->buffer_size = buffer_size_max;
}
if (status < 0)
{
- DEBUG_WARN("snd_mixer_open failed");
+ CLOG_ERR("snd_mixer_open failed");
return;
}
if (status < 0)
{
- DEBUG_WARN("snd_mixer_attach failed");
+ CLOG_ERR("snd_mixer_attach failed");
snd_mixer_close(alsa->mixer_handle);
return;
}
if (status < 0)
{
- DEBUG_WARN("snd_mixer_selem_register failed");
+ CLOG_ERR("snd_mixer_selem_register failed");
snd_mixer_close(alsa->mixer_handle);
return;
}
if (status < 0)
{
- DEBUG_WARN("snd_mixer_load failed");
+ CLOG_ERR("snd_mixer_load failed");
snd_mixer_close(alsa->mixer_handle);
return;
}
if (status < 0)
{
- DEBUG_WARN("snd_pcm_open failed");
+ CLOG_ERR("snd_pcm_open failed");
}
else
{
}
else if (status < 0)
{
- fprintf(stderr, "status: %d\n", status);
+ CLOG_ERR( "status: %d\n", status);
snd_pcm_close(alsa->pcm_handle);
alsa->pcm_handle = NULL;
rdpsnd_alsa_open((rdpsndDevicePlugin*) alsa, NULL, alsa->latency);
wave->wLatency = (UINT16) (wave->wLocalTimeB - wave->wLocalTimeA);
wave->wTimeStampB = wave->wTimeStampA + wave->wLatency;
- //fprintf(stderr, "wTimeStampA: %d wTimeStampB: %d wLatency: %d\n", wave->wTimeStampA, wave->wTimeStampB, wave->wLatency);
+ //CLOG_ERR( "wTimeStampA: %d wTimeStampB: %d wLatency: %d\n", wave->wTimeStampA, wave->wTimeStampB, wave->wLatency);
}
static COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] =
#define reportResult(result,operation) (_reportResult((result),(operation),__FILE__,__LINE__))
static inline bool _reportResult(kern_return_t result, const char *operation, const char* file, int line) {
if ( result != ERR_SUCCESS ) {
- printf("%s:%d: %s: %s\n", file, line, operation, mach_error_string(result));
+ CLOG_DBG("%s:%d: %s: %s\n", file, line, operation, mach_error_string(result));
return false;
}
return true;
if ( virtualAddress != bufferAddress+buffer->length ) {
// If the memory is not contiguous, clean up both allocated buffers and try again
if ( retries-- == 0 ) {
- printf("Couldn't map buffer memory to end of buffer\n");
+ CLOG_DBG("Couldn't map buffer memory to end of buffer\n");
return false;
}
if (status != 0)
{
- fprintf(stderr, "AudioQueueNewOutput failure\n");
+ CLOG_ERR( "AudioQueueNewOutput failure\n");
return;
}
if (status != 0)
{
- printf("AudioQueueGetProperty failure: kAudioQueueProperty_DecodeBufferSizeFrames\n");
+ CLOG_DBG("AudioQueueGetProperty failure: kAudioQueueProperty_DecodeBufferSizeFrames\n");
}
for (index = 0; index < MAC_AUDIO_QUEUE_NUM_BUFFERS; index++)
if (status != 0)
{
- fprintf(stderr, "AudioQueueAllocateBuffer failed\n");
+ CLOG_ERR( "AudioQueueAllocateBuffer failed\n");
}
}
if (status != 0)
{
- fprintf(stderr, "AudioQueueSetParameter kAudioQueueParam_Volume failed: %f\n", fVolume);
+ CLOG_ERR( "AudioQueueSetParameter kAudioQueueParam_Volume failed: %f\n", fVolume);
}
}
if (status != 0)
{
- fprintf(stderr, "AudioQueueStart failed\n");
+ CLOG_ERR( "AudioQueueStart failed\n");
}
mac->isPlaying = TRUE;
#include <freerdp/types.h>
#include <freerdp/codec/dsp.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#include "opensl_io.h"
#include "rdpsnd_main.h"
assert(opensles->stream);
if (!opensles->stream)
- DEBUG_WARN("android_OpenAudioDevice failed");
+ CLOG_ERR("android_OpenAudioDevice failed");
else
rdpsnd_opensles_set_volume(device, opensles->volume);
ret = android_AudioOut(opensles->stream, src.s, size / 2);
if (ret < 0)
- DEBUG_WARN("android_AudioOut failed (%d)", ret);
+ CLOG_ERR("android_AudioOut failed (%d)", ret);
}
static void rdpsnd_opensles_start(rdpsndDevicePlugin* device)
#include <freerdp/types.h>
#include <freerdp/addin.h>
#include <freerdp/constants.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#include <freerdp/utils/signal.h>
#include "rdpsnd_main.h"
}
#if 0
- fprintf(stderr, "Server ");
+ CLOG_ERR( "Server ");
rdpsnd_print_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats);
- fprintf(stderr, "\n");
+ CLOG_ERR( "\n");
- fprintf(stderr, "Client ");
+ CLOG_ERR( "Client ");
rdpsnd_print_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats);
- fprintf(stderr, "\n");
+ CLOG_ERR( "\n");
#endif
}
Stream_Seek_UINT8(s); /* bPad */
Stream_Read_UINT16(s, BodySize);
- //fprintf(stderr, "msgType %d BodySize %d\n", msgType, BodySize);
+ //CLOG_ERR( "msgType %d BodySize %d\n", msgType, BodySize);
switch (msgType)
{
break;
default:
- DEBUG_WARN("unknown msgType %d", msgType);
+ CLOG_ERR("unknown msgType %d", msgType);
break;
}
{
if (rdpsnd->device)
{
- DEBUG_WARN("existing device, abort.");
+ CLOG_ERR("existing device, abort.");
return;
}
if (entry(&entryPoints) != 0)
{
- DEBUG_WARN("%s entry returns error.", name);
+ CLOG_ERR("%s entry returns error.", name);
return FALSE;
}
if (!rdpsnd->device)
{
- DEBUG_WARN("no sound device.");
+ CLOG_ERR("no sound device.");
return;
}
if (status != CHANNEL_RC_OK)
{
Stream_Free(s, TRUE);
- fprintf(stderr, "rdpdr_virtual_channel_write: VirtualChannelWrite failed %d\n", status);
+ CLOG_ERR( "rdpdr_virtual_channel_write: VirtualChannelWrite failed %d\n", status);
}
return status;
{
if (Stream_Capacity(s) != Stream_GetPosition(s))
{
- fprintf(stderr, "rdpsnd_virtual_channel_event_data_received: read error\n");
+ CLOG_ERR( "rdpsnd_virtual_channel_event_data_received: read error\n");
}
plugin->data_in = NULL;
if (!plugin)
{
- fprintf(stderr, "rdpsnd_virtual_channel_open_event: error no match\n");
+ CLOG_ERR( "rdpsnd_virtual_channel_open_event: error no match\n");
return;
}
if (status != CHANNEL_RC_OK)
{
- fprintf(stderr, "rdpsnd_virtual_channel_event_connected: open failed: status: %d\n", status);
+ CLOG_ERR( "rdpsnd_virtual_channel_event_connected: open failed: status: %d\n", status);
return;
}
if (!plugin)
{
- fprintf(stderr, "rdpsnd_virtual_channel_init_event: error no match\n");
+ CLOG_ERR( "rdpsnd_virtual_channel_init_event: error no match\n");
return;
}
#include <freerdp/client/rdpsnd.h>
#if defined(WITH_DEBUG_SND)
-#define DEBUG_SND(fmt, ...) DEBUG_CLASS("rdpsnd", fmt, ## __VA_ARGS__)
+#define DEBUG_SND(fmt, ...) CLOG_CLASS("rdpsnd", fmt, ## __VA_ARGS__)
#else
#define DEBUG_SND(fmt, ...) do { } while (0)
#endif
#include <freerdp/types.h>
#include <freerdp/codec/dsp.h>
+#include <freerdp/channels/log.h>
#include "rdpsnd_main.h"
switch (uMsg)
{
case MM_WOM_OPEN:
- fprintf(stderr, "MM_WOM_OPEN\n");
+ CLOG_ERR( "MM_WOM_OPEN\n");
break;
case MM_WOM_CLOSE:
- fprintf(stderr, "MM_WOM_CLOSE\n");
+ CLOG_ERR( "MM_WOM_CLOSE\n");
break;
case MM_WOM_DONE:
if (!wave)
return;
- fprintf(stderr, "MM_WOM_DONE: dwBufferLength: %d cBlockNo: %d\n",
+ CLOG_ERR( "MM_WOM_DONE: dwBufferLength: %d cBlockNo: %d\n",
lpWaveHdr->dwBufferLength, wave->cBlockNo);
wave->wLocalTimeB = GetTickCount();
if (mmResult != MMSYSERR_NOERROR)
{
- fprintf(stderr, "waveOutOpen failed: %d\n", mmResult);
+ CLOG_ERR( "waveOutOpen failed: %d\n", mmResult);
}
}
if (mmResult != MMSYSERR_NOERROR)
{
- fprintf(stderr, "waveOutClose failure: %d\n", mmResult);
+ CLOG_ERR( "waveOutClose failure: %d\n", mmResult);
}
winmm->hWaveOut = NULL;
if (mmResult != MMSYSERR_NOERROR)
{
- fprintf(stderr, "waveOutPrepareHeader failure: %d\n", mmResult);
+ CLOG_ERR( "waveOutPrepareHeader failure: %d\n", mmResult);
return;
}
if (mmResult != MMSYSERR_NOERROR)
{
- fprintf(stderr, "waveOutWrite failure: %d\n", mmResult);
+ CLOG_ERR( "waveOutWrite failure: %d\n", mmResult);
waveOutUnprepareHeader(winmm->hWaveOut, lpWaveHdr, sizeof(WAVEHDR));
return;
}
#include <winpr/print.h>
#include <winpr/stream.h>
+#include <freerdp/channels/log.h>
+
#include "rdpsnd_main.h"
BOOL rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
Stream_Read_UINT16(s, quality);
Stream_Seek_UINT16(s); // reserved
- fprintf(stderr, "Client requested sound quality: %#0X\n", quality);
+ CLOG_ERR( "Client requested sound quality: %#0X\n", quality);
return TRUE;
}
if (!context->num_client_formats)
{
- fprintf(stderr, "%s: client doesn't support any format!\n", __FUNCTION__);
+ CLOG_ERR( "%s: client doesn't support any format!\n", __FUNCTION__);
return FALSE;
}
if (!context->num_client_formats)
{
- fprintf(stderr, "%s: client doesn't support any known format!\n", __FUNCTION__);
+ CLOG_ERR( "%s: client doesn't support any known format!\n", __FUNCTION__);
goto out_free;
}
if (client_format_index < 0 || client_format_index >= context->num_client_formats)
{
- fprintf(stderr, "%s: index %d is not correct.\n", __FUNCTION__, client_format_index);
+ CLOG_ERR( "%s: index %d is not correct.\n", __FUNCTION__, client_format_index);
return FALSE;
}
if (format->nSamplesPerSec == 0)
{
- fprintf(stderr, "%s: invalid Client Sound Format!!\n", __FUNCTION__);
+ CLOG_ERR( "%s: invalid Client Sound Format!!\n", __FUNCTION__);
return FALSE;
}
if (!WTSVirtualChannelQuery(priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &bytesReturned) || (bytesReturned != sizeof(HANDLE)))
{
- fprintf(stderr, "%s: error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)\n",
+ CLOG_ERR( "%s: error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)\n",
__FUNCTION__, bytesReturned);
if (buffer)
WTSFreeMemory(buffer);
if (GetLastError() == ERROR_NO_DATA)
return TRUE;
- fprintf(stderr, "%s: channel connection closed\n", __FUNCTION__);
+ CLOG_ERR( "%s: channel connection closed\n", __FUNCTION__);
return FALSE;
}
priv->expectedBytes -= bytesReturned;
/* when here we have the header + the body */
#ifdef WITH_DEBUG_SND
- fprintf(stderr, "%s: message type %d\n", __FUNCTION__, priv->msgType);
+ CLOG_ERR( "%s: message type %d\n", __FUNCTION__, priv->msgType);
#endif
priv->expectedBytes = 4;
priv->waitingHeader = TRUE;
break;
default:
- fprintf(stderr, "%s: UNKOWN MESSAGE TYPE!! (%#0X)\n\n", __FUNCTION__, priv->msgType);
+ CLOG_ERR( "%s: UNKOWN MESSAGE TYPE!! (%#0X)\n\n", __FUNCTION__, priv->msgType);
ret = FALSE;
break;
}
#include <freerdp/assistance.h>
+#include <freerdp/channels/log.h>
#include <freerdp/client/remdesk.h>
#include "remdesk_main.h"
if (status != CHANNEL_RC_OK)
{
- fprintf(stderr, "remdesk_virtual_channel_write: VirtualChannelWrite failed %d\n", status);
+ CLOG_ERR( "remdesk_virtual_channel_write: VirtualChannelWrite failed %d\n", status);
return -1;
}
return 1;
}
-int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
+static int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
{
int status;
UINT32 ChannelNameLen;
return 1;
}
-int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
+static int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
{
int index;
UINT32 ChannelNameLen;
return 1;
}
-int remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader)
+static int remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader)
{
remdesk_write_channel_header(s, (REMDESK_CHANNEL_HEADER*) ctlHeader);
Stream_Write_UINT32(s, ctlHeader->msgType); /* msgType (4 bytes) */
return 1;
}
-int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize)
+static int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize)
{
ctlHeader->msgType = msgType;
strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME);
return 1;
}
-int remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
+static int remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
{
return 1;
}
-int remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
+static int remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
{
UINT32 versionMajor;
UINT32 versionMinor;
return 1;
}
-int remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
+static int remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
{
wStream* s;
REMDESK_CTL_VERSION_INFO_PDU pdu;
return 1;
}
-int remdesk_recv_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult)
+static int remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult)
{
UINT32 result;
*pResult = result;
- //printf("RemdeskRecvResult: 0x%04X\n", result);
+ //CLOG_DBG("RemdeskRecvResult: 0x%04X\n", result);
return 1;
}
-int remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
+static int remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
{
int status;
wStream* s;
return 1;
}
-int remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
+static int remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
{
int status;
wStream* s;
return 1;
}
-int remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
+static int remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
{
int status;
wStream* s;
return 1;
}
-int remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
+static int remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
{
int status;
wStream* s;
return 1;
}
-int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
+static int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
{
int status = 1;
UINT32 msgType = 0;
Stream_Read_UINT32(s, msgType); /* msgType (4 bytes) */
- //printf("msgType: %d\n", msgType);
+ //CLOG_DBG("msgType: %d\n", msgType);
switch (msgType)
{
break;
case REMDESK_CTL_RESULT:
- status = remdesk_recv_result_pdu(remdesk, s, header, &result);
+ status = remdesk_recv_ctl_result_pdu(remdesk, s, header, &result);
break;
case REMDESK_CTL_AUTHENTICATE:
break;
default:
- fprintf(stderr, "remdesk_recv_control_pdu: unknown msgType: %d\n", msgType);
+ CLOG_ERR( "remdesk_recv_control_pdu: unknown msgType: %d\n", msgType);
status = -1;
break;
}
return status;
}
-int remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
+static int remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
{
int status = 1;
REMDESK_CHANNEL_HEADER header;
#if 0
- printf("RemdeskReceive: %d\n", Stream_GetRemainingLength(s));
+ CLOG_DBG("RemdeskReceive: %d\n", Stream_GetRemainingLength(s));
winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s));
#endif
if (status != CHANNEL_RC_OK)
{
Stream_Free(s, TRUE);
- fprintf(stderr, "remdesk_send: VirtualChannelWrite failed %d\n", status);
+ CLOG_ERR( "remdesk_send: VirtualChannelWrite failed %d\n", status);
}
return status;
{
if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
{
- fprintf(stderr, "remdesk_plugin_process_received: read error\n");
+ CLOG_ERR( "remdesk_plugin_process_received: read error\n");
}
remdesk->data_in = NULL;
if (!remdesk)
{
- fprintf(stderr, "remdesk_virtual_channel_open_event: error no match\n");
+ CLOG_ERR( "remdesk_virtual_channel_open_event: error no match\n");
return;
}
if (status != CHANNEL_RC_OK)
{
- fprintf(stderr, "remdesk_virtual_channel_event_connected: open failed: status: %d\n", status);
+ CLOG_ERR( "remdesk_virtual_channel_event_connected: open failed: status: %d\n", status);
return;
}
if (!remdesk)
{
- fprintf(stderr, "remdesk_virtual_channel_init_event: error no match\n");
+ CLOG_ERR( "remdesk_virtual_channel_init_event: error no match\n");
return;
}
#include "remdesk_main.h"
+int remdesk_virtual_channel_write(RemdeskServerContext* context, wStream* s)
+{
+ BOOL status;
+ ULONG BytesWritten = 0;
+
+ status = WTSVirtualChannelWrite(context->priv->ChannelHandle,
+ (PCHAR) Stream_Buffer(s), Stream_Length(s), &BytesWritten);
+
+ return (status) ? 1 : -1;
+}
+
+static int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+ int status;
+ UINT32 ChannelNameLen;
+ char* pChannelName = NULL;
+
+ if (Stream_GetRemainingLength(s) < 8)
+ return -1;
+
+ Stream_Read_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */
+ Stream_Read_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
+
+ if (ChannelNameLen > 64)
+ return -1;
+
+ if ((ChannelNameLen % 2) != 0)
+ return -1;
+
+ if (Stream_GetRemainingLength(s) < ChannelNameLen)
+ return -1;
+
+ ZeroMemory(header->ChannelName, sizeof(header->ChannelName));
+
+ pChannelName = (char*) header->ChannelName;
+ status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s),
+ ChannelNameLen / 2, &pChannelName, 32, NULL, NULL);
+
+ Stream_Seek(s, ChannelNameLen);
+
+ if (status <= 0)
+ return -1;
+
+ return 1;
+}
+
+static int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+ int index;
+ UINT32 ChannelNameLen;
+ WCHAR ChannelNameW[32];
+
+ ZeroMemory(ChannelNameW, sizeof(ChannelNameW));
+
+ for (index = 0; index < 32; index++)
+ {
+ ChannelNameW[index] = (WCHAR) header->ChannelName[index];
+ }
+
+ ChannelNameLen = (strlen(header->ChannelName) + 1) * 2;
+
+ Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */
+ Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
+
+ Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */
+
+ return 1;
+}
+
+static int remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader)
+{
+ remdesk_write_channel_header(s, (REMDESK_CHANNEL_HEADER*) ctlHeader);
+ Stream_Write_UINT32(s, ctlHeader->msgType); /* msgType (4 bytes) */
+ return 1;
+}
+
+static int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize)
+{
+ ctlHeader->msgType = msgType;
+ strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME);
+ ctlHeader->DataLength = 4 + msgSize;
+ return 1;
+}
+
+static int remdesk_send_ctl_result_pdu(RemdeskServerContext* context, UINT32 result)
+{
+ wStream* s;
+ REMDESK_CTL_RESULT_PDU pdu;
+
+ pdu.result = result;
+
+ remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_RESULT, 4);
+
+ s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
+
+ remdesk_write_ctl_header(s, &(pdu.ctlHeader));
+
+ Stream_Write_UINT32(s, pdu.result); /* result (4 bytes) */
+
+ Stream_SealLength(s);
+
+ remdesk_virtual_channel_write(context, s);
+
+ Stream_Free(s, TRUE);
+
+ return 1;
+}
+
+static int remdesk_send_ctl_version_info_pdu(RemdeskServerContext* context)
+{
+ wStream* s;
+ REMDESK_CTL_VERSION_INFO_PDU pdu;
+
+ remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERSIONINFO, 8);
+
+ pdu.versionMajor = 1;
+ pdu.versionMinor = 2;
+
+ s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
+
+ remdesk_write_ctl_header(s, &(pdu.ctlHeader));
+
+ Stream_Write_UINT32(s, pdu.versionMajor); /* versionMajor (4 bytes) */
+ Stream_Write_UINT32(s, pdu.versionMinor); /* versionMinor (4 bytes) */
+
+ Stream_SealLength(s);
+
+ remdesk_virtual_channel_write(context, s);
+
+ return 1;
+}
+
+static int remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+ UINT32 versionMajor;
+ UINT32 versionMinor;
+
+ if (Stream_GetRemainingLength(s) < 8)
+ return -1;
+
+ Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */
+ Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */
+
+ return 1;
+}
+
+static int remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+ int status;
+ int cchStringW;
+ WCHAR* pStringW;
+ UINT32 msgLength;
+ int cbRaConnectionStringW = 0;
+ WCHAR* raConnectionStringW = NULL;
+ REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu;
+
+ msgLength = header->DataLength - 4;
+
+ pStringW = (WCHAR*) Stream_Pointer(s);
+ raConnectionStringW = pStringW;
+ cchStringW = 0;
+
+ while ((msgLength > 0) && pStringW[cchStringW])
+ {
+ msgLength -= 2;
+ cchStringW++;
+ }
+
+ if (pStringW[cchStringW] || !cchStringW)
+ return -1;
+
+ cchStringW++;
+ cbRaConnectionStringW = cchStringW * 2;
+
+ pdu.raConnectionString = NULL;
+
+ status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW,
+ cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL);
+
+ if (status <= 0)
+ return -1;
+
+ printf("RaConnectionString: %s\n",
+ pdu.raConnectionString);
+
+ free(pdu.raConnectionString);
+
+ remdesk_send_ctl_result_pdu(context, 0);
+
+ return 1;
+}
+
+static int remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+ int status;
+ int cchStringW;
+ WCHAR* pStringW;
+ UINT32 msgLength;
+ int cbExpertBlobW = 0;
+ WCHAR* expertBlobW = NULL;
+ int cbRaConnectionStringW = 0;
+ WCHAR* raConnectionStringW = NULL;
+ REMDESK_CTL_AUTHENTICATE_PDU pdu;
+
+ msgLength = header->DataLength - 4;
+
+ pStringW = (WCHAR*) Stream_Pointer(s);
+ raConnectionStringW = pStringW;
+ cchStringW = 0;
+
+ while ((msgLength > 0) && pStringW[cchStringW])
+ {
+ msgLength -= 2;
+ cchStringW++;
+ }
+
+ if (pStringW[cchStringW] || !cchStringW)
+ return -1;
+
+ cchStringW++;
+ cbRaConnectionStringW = cchStringW * 2;
+
+ pStringW += cchStringW;
+ expertBlobW = pStringW;
+ cchStringW = 0;
+
+ while ((msgLength > 0) && pStringW[cchStringW])
+ {
+ msgLength -= 2;
+ cchStringW++;
+ }
+
+ if (pStringW[cchStringW] || !cchStringW)
+ return -1;
+
+ cchStringW++;
+ cbExpertBlobW = cchStringW * 2;
+
+ pdu.raConnectionString = NULL;
+
+ status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW,
+ cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL);
+
+ if (status <= 0)
+ return -1;
+
+ pdu.expertBlob = NULL;
+
+ status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW,
+ cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL);
+
+ if (status <= 0)
+ return -1;
+
+ printf("RaConnectionString: %s ExpertBlob: %s\n",
+ pdu.raConnectionString, pdu.expertBlob);
+
+ free(pdu.raConnectionString);
+ free(pdu.expertBlob);
+
+ return 1;
+}
+
+static int remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+ int status;
+ int cbExpertBlobW = 0;
+ WCHAR* expertBlobW = NULL;
+ REMDESK_CTL_VERIFY_PASSWORD_PDU pdu;
+
+ if (Stream_GetRemainingLength(s) < 8)
+ return -1;
+
+ pdu.expertBlob = NULL;
+ expertBlobW = (WCHAR*) Stream_Pointer(s);
+ cbExpertBlobW = header->DataLength - 4;
+
+ status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL);
+
+ printf("ExpertBlob: %s\n", pdu.expertBlob);
+
+ remdesk_send_ctl_result_pdu(context, 0);
+
+ return 1;
+}
+
+static int remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
+{
+ int status = 1;
+ UINT32 msgType = 0;
+
+ if (Stream_GetRemainingLength(s) < 4)
+ return -1;
+
+ Stream_Read_UINT32(s, msgType); /* msgType (4 bytes) */
+
+ printf("msgType: %d\n", msgType);
+
+ switch (msgType)
+ {
+ case REMDESK_CTL_REMOTE_CONTROL_DESKTOP:
+ status = remdesk_recv_ctl_remote_control_desktop_pdu(context, s, header);
+ break;
+
+ case REMDESK_CTL_AUTHENTICATE:
+ status = remdesk_recv_ctl_authenticate_pdu(context, s, header);
+ break;
+
+ case REMDESK_CTL_DISCONNECT:
+ break;
+
+ case REMDESK_CTL_VERSIONINFO:
+ status = remdesk_recv_ctl_version_info_pdu(context, s, header);
+ break;
+
+ case REMDESK_CTL_ISCONNECTED:
+ break;
+
+ case REMDESK_CTL_VERIFY_PASSWORD:
+ status = remdesk_recv_ctl_verify_password_pdu(context, s, header);
+ break;
+
+ case REMDESK_CTL_EXPERT_ON_VISTA:
+ break;
+
+ case REMDESK_CTL_RANOVICE_NAME:
+ break;
+
+ case REMDESK_CTL_RAEXPERT_NAME:
+ break;
+
+ case REMDESK_CTL_TOKEN:
+ break;
+
+ default:
+ fprintf(stderr, "remdesk_recv_control_pdu: unknown msgType: %d\n", msgType);
+ status = -1;
+ break;
+ }
+
+ return status;
+}
+
static int remdesk_server_receive_pdu(RemdeskServerContext* context, wStream* s)
{
- return 0;
+ int status = 1;
+ REMDESK_CHANNEL_HEADER header;
+
+#if 0
+ printf("RemdeskReceive: %d\n", Stream_GetRemainingLength(s));
+ winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s));
+#endif
+
+ remdesk_read_channel_header(s, &header);
+
+ if (strcmp(header.ChannelName, "RC_CTL") == 0)
+ {
+ status = remdesk_recv_ctl_pdu(context, s, &header);
+ }
+ else if (strcmp(header.ChannelName, "70") == 0)
+ {
+
+ }
+ else if (strcmp(header.ChannelName, "71") == 0)
+ {
+
+ }
+ else if (strcmp(header.ChannelName, ".") == 0)
+ {
+
+ }
+ else if (strcmp(header.ChannelName, "1000.") == 0)
+ {
+
+ }
+ else if (strcmp(header.ChannelName, "RA_FX") == 0)
+ {
+
+ }
+ else
+ {
+
+ }
+
+ return 1;
}
static void* remdesk_server_thread(void* arg)
DWORD status;
DWORD nCount;
void* buffer;
+ UINT32* pHeader;
+ UINT32 PduLength;
HANDLE events[8];
HANDLE ChannelEvent;
DWORD BytesReturned;
events[nCount++] = ChannelEvent;
events[nCount++] = context->priv->StopEvent;
+ remdesk_send_ctl_version_info_pdu(context);
+
while (1)
{
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
Stream_EnsureRemainingCapacity(s, BytesReturned);
}
- if (0)
+ if (Stream_GetPosition(s) >= 8)
{
- remdesk_server_receive_pdu(context, s);
+ pHeader = (UINT32*) Stream_Buffer(s);
+ PduLength = pHeader[0] + pHeader[1] + 8;
+
+ if (PduLength >= Stream_GetPosition(s))
+ {
+ Stream_SealLength(s);
+ Stream_SetPosition(s, 0);
+ remdesk_server_receive_pdu(context, s);
+ Stream_SetPosition(s, 0);
+ }
}
}
context->priv->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) remdesk_server_thread, (void*) context, 0, NULL);
- return 0;
+ return 1;
}
static int remdesk_server_stop(RemdeskServerContext* context)
WaitForSingleObject(context->priv->Thread, INFINITE);
CloseHandle(context->priv->Thread);
- return 0;
+ return 1;
}
RemdeskServerContext* remdesk_server_context_new(HANDLE vcm)
if (context->priv)
{
-
+ context->priv->Version = 1;
}
}
HANDLE Thread;
HANDLE StopEvent;
void* ChannelHandle;
+
+ UINT32 Version;
};
#endif /* FREERDP_CHANNEL_SERVER_REMDESK_MAIN_H */
}
else
{
- fprintf(stderr, "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X",
+ CLOG_ERR( "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X",
irp->MajorFunction, irp->MinorFunction);
irp->IoStatus = STATUS_NOT_SUPPORTED;
#ifndef FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H
#define FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#include <freerdp/channels/rdpdr.h>
#include <winpr/crt.h>
#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";
}
return STATUS_NO_MEMORY;
status = smartcard_unpack_establish_context_call(smartcard, irp->input, call);
-
smartcard_trace_establish_context_call(smartcard, call);
-
return status;
}
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)
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;
}
{
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;
}
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;
}
{
UINT32 status;
Long_Return ret;
-
status = ret.ReturnCode = SCardIsValidContext(operation->hContext);
-
smartcard_trace_long_return(smartcard, &ret, "IsValidContext");
-
return ret.ReturnCode;
}
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;
}
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;
return status;
smartcard_trace_list_readers_return(smartcard, &ret, FALSE);
-
status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret);
if (status)
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;
}
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;
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)
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;
}
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;
}
}
smartcard_trace_get_status_change_return(smartcard, &ret, FALSE);
-
status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret);
if (status)
if (rgReaderState->szReader)
free((void*) rgReaderState->szReader);
}
+
free(call->rgReaderStates);
}
free(ret.rgReaderStates);
-
return ret.ReturnCode;
}
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;
}
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;
}
}
smartcard_trace_get_status_change_return(smartcard, &ret, TRUE);
-
status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret);
if (status)
if (rgReaderState->szReader)
free((void*) rgReaderState->szReader);
}
+
free(call->rgReaderStates);
}
free(ret.rgReaderStates);
-
return ret.ReturnCode;
}
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;
}
{
LONG status;
Long_Return ret;
-
status = ret.ReturnCode = SCardCancel(operation->hContext);
-
smartcard_trace_long_return(smartcard, &ret, "Cancel");
-
return ret.ReturnCode;
}
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;
}
}
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)
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;
}
}
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)
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;
}
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)
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;
}
{
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)
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;
}
{
LONG status;
Long_Return ret;
-
status = ret.ReturnCode = SCardBeginTransaction(operation->hCard);
-
smartcard_trace_long_return(smartcard, &ret, "BeginTransaction");
-
return ret.ReturnCode;
}
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;
}
{
LONG status;
Long_Return ret;
-
status = ret.ReturnCode = SCardEndTransaction(operation->hCard, call->dwDisposition);
-
smartcard_trace_long_return(smartcard, &ret, "EndTransaction");
-
return ret.ReturnCode;
}
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;
}
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)
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;
}
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)
{
}
smartcard_trace_status_return(smartcard, &ret, FALSE);
-
status = smartcard_pack_status_return(smartcard, irp->output, &ret);
if (status != SCARD_S_SUCCESS)
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;
}
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)
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;
}
LONG status;
Transmit_Return ret;
IRP* irp = operation->irp;
-
ret.cbRecvLength = 0;
ret.pbRecvBuffer = NULL;
}
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)
if (call->pbSendBuffer)
free(call->pbSendBuffer);
+
if (ret.pbRecvBuffer)
free(ret.pbRecvBuffer);
+
if (call->pioSendPci)
free(call->pioSendPci);
+
if (call->pioRecvPci)
free(call->pioRecvPci);
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;
}
LONG status;
Control_Return ret;
IRP* irp = operation->irp;
-
ret.cbOutBufferSize = call->cbOutBufferSize;
ret.pvOutBuffer = (BYTE*) malloc(call->cbOutBufferSize);
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)
if (call->pvInBuffer)
free(call->pvInBuffer);
+
if (ret.pvOutBuffer)
free(ret.pvOutBuffer);
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;
}
DWORD cbAttrLen;
GetAttrib_Return ret;
IRP* irp = operation->irp;
-
ret.pbAttr = NULL;
if (call->fpbAttrIsNULL)
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;
}
return status;
free(ret.pbAttr);
-
return ret.ReturnCode;
}
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;
}
{
UINT32 status;
Long_Return ret;
-
status = ret.ReturnCode = SCARD_S_SUCCESS;
if (!smartcard->StartedEvent)
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;
}
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
- printf("%s (0x%08X) FileId: %d CompletionId: %d\n",
- smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
+ CLOG_DBG("%s (0x%08X) FileId: %d CompletionId: %d\n",
+ smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
#endif
if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
(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)
}
operation->call = call;
-
return status;
}
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
* 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 */
(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;
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;
}
error = snd_pcm_open(&alsa->out_handle, alsa->device, SND_PCM_STREAM_PLAYBACK, 0);
if(error < 0)
{
- DEBUG_WARN("failed to open device %s", alsa->device);
+ CLOG_ERR("failed to open device %s", alsa->device);
return FALSE;
}
DEBUG_TSMF("open device %s", alsa->device);
error = snd_pcm_hw_params_malloc(&hw_params);
if(error < 0)
{
- DEBUG_WARN("snd_pcm_hw_params_malloc failed");
+ CLOG_ERR("snd_pcm_hw_params_malloc failed");
return FALSE;
}
snd_pcm_hw_params_any(alsa->out_handle, hw_params);
error = snd_pcm_sw_params_malloc(&sw_params);
if(error < 0)
{
- DEBUG_WARN("snd_pcm_sw_params_malloc");
+ CLOG_ERR("snd_pcm_sw_params_malloc");
return FALSE;
}
snd_pcm_sw_params_current(alsa->out_handle, sw_params);
#include <winpr/crt.h>
+#include <freerdp/channels/log.h>
#include <freerdp/utils/event.h>
#include <freerdp/client/tsmf.h>
#include <libavcodec/avcodec.h>
+#include <libavutil/common.h>
#include "tsmf_constants.h"
#include "tsmf_decoder.h"
#define MAX_AUDIO_FRAME_SIZE 192000
#endif
+#if LIBAVCODEC_VERSION_MAJOR < 55
+#define AV_CODEC_ID_VC1 CODEC_ID_VC1
+#define AV_CODEC_ID_WMAV2 CODEC_ID_WMAV2
+#define AV_CODEC_ID_WMAPRO CODEC_ID_WMAPRO
+#define AV_CODEC_ID_MP3 CODEC_ID_MP3
+#define AV_CODEC_ID_MP2 CODEC_ID_MP2
+#define AV_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO
+#define AV_CODEC_ID_WMV3 CODEC_ID_WMV3
+#define AV_CODEC_ID_AAC CODEC_ID_AAC
+#define AV_CODEC_ID_H264 CODEC_ID_H264
+#define AV_CODEC_ID_AC3 CODEC_ID_AC3
+#endif
+
+
typedef struct _TSMFFFmpegDecoder
{
ITSMFDecoder iface;
mdecoder->codec_context = avcodec_alloc_context3(NULL);
if(!mdecoder->codec_context)
{
- DEBUG_WARN("avcodec_alloc_context failed.");
+ CLOG_ERR("avcodec_alloc_context failed.");
return FALSE;
}
return TRUE;
mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id);
if(!mdecoder->codec)
{
- DEBUG_WARN("avcodec_find_decoder failed.");
+ CLOG_ERR("avcodec_find_decoder failed.");
return FALSE;
}
mdecoder->codec_context->codec_id = mdecoder->codec_id;
TSMFFFmpegDecoder *mdecoder = (TSMFFFmpegDecoder *) decoder;
if(avcodec_open2(mdecoder->codec_context, mdecoder->codec, NULL) < 0)
{
- DEBUG_WARN("avcodec_open2 failed.");
+ CLOG_ERR("avcodec_open2 failed.");
return FALSE;
}
mdecoder->prepared = 1;
switch(media_type->SubType)
{
case TSMF_SUB_TYPE_WVC1:
- mdecoder->codec_id = CODEC_ID_VC1;
+ mdecoder->codec_id = AV_CODEC_ID_VC1;
break;
case TSMF_SUB_TYPE_WMA2:
- mdecoder->codec_id = CODEC_ID_WMAV2;
+ mdecoder->codec_id = AV_CODEC_ID_WMAV2;
break;
case TSMF_SUB_TYPE_WMA9:
- mdecoder->codec_id = CODEC_ID_WMAPRO;
+ mdecoder->codec_id = AV_CODEC_ID_WMAPRO;
break;
case TSMF_SUB_TYPE_MP3:
- mdecoder->codec_id = CODEC_ID_MP3;
+ mdecoder->codec_id = AV_CODEC_ID_MP3;
break;
case TSMF_SUB_TYPE_MP2A:
- mdecoder->codec_id = CODEC_ID_MP2;
+ mdecoder->codec_id = AV_CODEC_ID_MP2;
break;
case TSMF_SUB_TYPE_MP2V:
- mdecoder->codec_id = CODEC_ID_MPEG2VIDEO;
+ mdecoder->codec_id = AV_CODEC_ID_MPEG2VIDEO;
break;
case TSMF_SUB_TYPE_WMV3:
- mdecoder->codec_id = CODEC_ID_WMV3;
+ mdecoder->codec_id = AV_CODEC_ID_WMV3;
break;
case TSMF_SUB_TYPE_AAC:
- mdecoder->codec_id = CODEC_ID_AAC;
+ mdecoder->codec_id = AV_CODEC_ID_AAC;
/* For AAC the pFormat is a HEAACWAVEINFO struct, and the codec data
is at the end of it. See
http://msdn.microsoft.com/en-us/library/dd757806.aspx */
break;
case TSMF_SUB_TYPE_H264:
case TSMF_SUB_TYPE_AVC1:
- mdecoder->codec_id = CODEC_ID_H264;
+ mdecoder->codec_id = AV_CODEC_ID_H264;
break;
case TSMF_SUB_TYPE_AC3:
- mdecoder->codec_id = CODEC_ID_AC3;
+ mdecoder->codec_id = AV_CODEC_ID_AC3;
break;
default:
return FALSE;
#endif
if(len < 0)
{
- DEBUG_WARN("data_size %d, avcodec_decode_video failed (%d)", data_size, len);
+ CLOG_ERR("data_size %d, avcodec_decode_video failed (%d)", data_size, len);
ret = FALSE;
}
else
if(!decoded)
{
- DEBUG_WARN("data_size %d, no frame is decoded.", data_size);
+ CLOG_ERR("data_size %d, no frame is decoded.", data_size);
ret = FALSE;
}
else
#endif
if(len <= 0 || frame_size <= 0)
{
- DEBUG_WARN("error decoding");
+ CLOG_ERR("error decoding");
break;
}
src += len;
case AVMEDIA_TYPE_AUDIO:
return tsmf_ffmpeg_decode_audio(decoder, data, data_size, extensions);
default:
- DEBUG_WARN("unknown media type.");
+ CLOG_ERR("unknown media type.");
return FALSE;
}
}
case PIX_FMT_YUV420P:
return RDP_PIXFMT_I420;
default:
- DEBUG_WARN("unsupported pixel format %u",
+ CLOG_ERR("unsupported pixel format %u",
mdecoder->codec_context->pix_fmt);
return (UINT32) -1;
}
avcodec_register_all();
initialized = TRUE;
}
- fprintf(stderr, "TSMFDecoderEntry FFMPEG\n");
+ CLOG_ERR( "TSMFDecoderEntry FFMPEG\n");
decoder = (TSMFFFmpegDecoder *) malloc(sizeof(TSMFFFmpegDecoder));
ZeroMemory(decoder, sizeof(TSMFFFmpegDecoder));
decoder->iface.SetFormat = tsmf_ffmpeg_set_format;
if (!hdl)
{
- DEBUG_WARN("%s: Could not allocate handle.", __func__);
+ CLOG_ERR("%s: Could not allocate handle.", __func__);
return -1;
}
if (hdl->shmid < 0)
{
- DEBUG_WARN("%s: failed to get access to shared memory - shmget()",
+ CLOG_ERR("%s: failed to get access to shared memory - shmget()",
__func__);
return -2;
}
if (hdl->xfwin == (int *)-1)
{
- DEBUG_WARN("%s: shmat failed!", __func__);
+ CLOG_ERR("%s: shmat failed!", __func__);
return -3;
}
if (!hdl->disp)
{
- DEBUG_WARN("Failed to open display");
+ CLOG_ERR("Failed to open display");
return -4;
}
if (!bus)
{
- DEBUG_WARN("gst_pipeline_get_bus failed!");
+ CLOG_ERR("gst_pipeline_get_bus failed!");
return 1;
}
if (!hdl->subwin)
{
- DEBUG_WARN("Could not create subwindow!");
+ CLOG_ERR("Could not create subwindow!");
}
XMapWindow(hdl->disp, hdl->subwin);
if (!gst_video_overlay_set_render_rectangle(overlay, 0, 0, width, height))
{
- DEBUG_WARN("Could not resize overlay!");
+ CLOG_ERR("Could not resize overlay!");
}
gst_video_overlay_expose(overlay);
#else
if (!gst_x_overlay_set_render_rectangle(overlay, 0, 0, width, height))
{
- DEBUG_WARN("Could not resize overlay!");
+ CLOG_ERR("Could not resize overlay!");
}
gst_x_overlay_expose(overlay);
state_change = gst_element_set_state(mdecoder->pipe, desired_state);
if (state_change == GST_STATE_CHANGE_FAILURE)
- DEBUG_WARN("%s: (%s) GST_STATE_CHANGE_FAILURE.", sname, name);
+ CLOG_ERR("%s: (%s) GST_STATE_CHANGE_FAILURE.", sname, name);
else if (state_change == GST_STATE_CHANGE_ASYNC)
{
- DEBUG_WARN("%s: (%s) GST_STATE_CHANGE_ASYNC.", sname, name);
+ CLOG_ERR("%s: (%s) GST_STATE_CHANGE_ASYNC.", sname, name);
mdecoder->state = desired_state;
}
else
if (!data)
{
- DEBUG_WARN("Could not allocate %"G_GSIZE_FORMAT" bytes of data.", size);
+ CLOG_ERR("Could not allocate %"G_GSIZE_FORMAT" bytes of data.", size);
return NULL;
}
if (!buffer)
{
- DEBUG_WARN("Could not create GstBuffer");
+ CLOG_ERR("Could not create GstBuffer");
free(data);
return NULL;
}
NULL);
break;
default:
- DEBUG_WARN("unknown format:(%d).", media_type->SubType);
+ CLOG_ERR("unknown format:(%d).", media_type->SubType);
return FALSE;
}
if (!buffer)
{
- DEBUG_WARN("could not allocate GstBuffer!");
+ CLOG_ERR("could not allocate GstBuffer!");
return FALSE;
}
if (!mdecoder->pipe)
{
- DEBUG_WARN("Failed to create new pipe");
+ CLOG_ERR("Failed to create new pipe");
return FALSE;
}
if (!mdecoder->src)
{
- DEBUG_WARN("Failed to get appsrc");
+ CLOG_ERR("Failed to get appsrc");
return FALSE;
}
if (!mdecoder->outsink)
{
- DEBUG_WARN("Failed to get sink");
+ CLOG_ERR("Failed to get sink");
return FALSE;
}
if (!mdecoder->volume)
{
- DEBUG_WARN("Failed to get volume");
+ CLOG_ERR("Failed to get volume");
return FALSE;
}
}
if (!mdecoder)
{
- DEBUG_WARN("Decoder not initialized!");
+ CLOG_ERR("Decoder not initialized!");
return FALSE;
}
if (mdecoder->gst_caps == NULL)
{
- DEBUG_WARN("tsmf_gstreamer_set_format not called or invalid format.");
+ CLOG_ERR("tsmf_gstreamer_set_format not called or invalid format.");
return FALSE;
}
if (!mdecoder->src)
{
- DEBUG_WARN("failed to construct pipeline correctly. Unable to push buffer to source element.");
+ CLOG_ERR("failed to construct pipeline correctly. Unable to push buffer to source element.");
return FALSE;
}
if (gst_buf == NULL)
{
- DEBUG_WARN("tsmf_get_buffer_from_data(%p, %d) failed.", data, data_size);
+ CLOG_ERR("tsmf_get_buffer_from_data(%p, %d) failed.", data, data_size);
return FALSE;
}
GST_SEEK_TYPE_SET, sample_time,
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))
{
- DEBUG_WARN("seek failed");
+ CLOG_ERR("seek failed");
}
mdecoder->pipeline_start_time_valid = 0;
if (mdecoder->paused)
{
- DEBUG_WARN("%s: Ignoring control PAUSE, already received!", get_type(mdecoder));
+ CLOG_ERR("%s: Ignoring control PAUSE, already received!", get_type(mdecoder));
return;
}
if (!mdecoder->paused && !mdecoder->shutdown)
{
- DEBUG_WARN("%s: Ignoring control RESUME, already received!", get_type(mdecoder));
+ CLOG_ERR("%s: Ignoring control RESUME, already received!", get_type(mdecoder));
return;
}
if (mdecoder->shutdown)
{
- DEBUG_WARN("%s: Ignoring control STOP, already received!", get_type(mdecoder));
+ CLOG_ERR("%s: Ignoring control STOP, already received!", get_type(mdecoder));
return;
}
gst_app_src_end_of_stream((GstAppSrc *)mdecoder->src);
}
else
- DEBUG_WARN("Unknown control message %08x", control_msg);
+ CLOG_ERR("Unknown control message %08x", control_msg);
}
static BOOL tsmf_gstreamer_buffer_filled(ITSMFDecoder *decoder)
return FALSE;
if(pa_context_connect(pulse->context, NULL, 0, NULL))
{
- DEBUG_WARN("pa_context_connect failed (%d)",
+ CLOG_ERR("pa_context_connect failed (%d)",
pa_context_errno(pulse->context));
return FALSE;
}
if(pa_threaded_mainloop_start(pulse->mainloop) < 0)
{
pa_threaded_mainloop_unlock(pulse->mainloop);
- DEBUG_WARN("pa_threaded_mainloop_start failed (%d)",
+ CLOG_ERR("pa_threaded_mainloop_start failed (%d)",
pa_context_errno(pulse->context));
return FALSE;
}
pulse->mainloop = pa_threaded_mainloop_new();
if(!pulse->mainloop)
{
- DEBUG_WARN("pa_threaded_mainloop_new failed");
+ CLOG_ERR("pa_threaded_mainloop_new failed");
return FALSE;
}
pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp");
if(!pulse->context)
{
- DEBUG_WARN("pa_context_new failed");
+ CLOG_ERR("pa_context_new failed");
return FALSE;
}
pa_context_set_state_callback(pulse->context, tsmf_pulse_context_state_callback, pulse);
if(tsmf_pulse_connect(pulse))
{
- DEBUG_WARN("tsmf_pulse_connect failed");
+ CLOG_ERR("tsmf_pulse_connect failed");
return FALSE;
}
DEBUG_TSMF("open device %s", pulse->device);
if(!pulse->stream)
{
pa_threaded_mainloop_unlock(pulse->mainloop);
- DEBUG_WARN("pa_stream_new failed (%d)",
+ CLOG_ERR("pa_stream_new failed (%d)",
pa_context_errno(pulse->context));
return FALSE;
}
NULL, NULL) < 0)
{
pa_threaded_mainloop_unlock(pulse->mainloop);
- DEBUG_WARN("pa_stream_connect_playback failed (%d)",
+ CLOG_ERR("pa_stream_connect_playback failed (%d)",
pa_context_errno(pulse->context));
return FALSE;
}
break;
if(!PA_STREAM_IS_GOOD(state))
{
- DEBUG_WARN("bad stream state (%d)",
+ CLOG_ERR("bad stream state (%d)",
pa_context_errno(pulse->context));
break;
}
if (audio == NULL)
{
- DEBUG_WARN("failed to call export function in %s", name);
+ CLOG_ERR("failed to call export function in %s", name);
return NULL;
}
#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;
}
};
-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--)
- fprintf(stderr, "%02X", guid[i]);
- fprintf(stderr, "-");
- for(i = 5; i >= 4; i--)
- fprintf(stderr, "%02X", guid[i]);
- fprintf(stderr, "-");
- for(i = 7; i >= 6; i--)
- fprintf(stderr, "%02X", guid[i]);
- fprintf(stderr, "-");
- for(i = 8; i < 16; i++)
- {
- fprintf(stderr, "%02X", guid[i]);
- if(i == 9)
- fprintf(stderr, "-");
+
+ 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("-");
}
- fprintf(stderr, "\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;
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) */
}
/* 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 {
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;
/* 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 */
/* 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 */
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 */
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);
decoder = entry();
if(decoder == NULL)
{
- DEBUG_WARN("failed to call export function in %s", name);
+ CLOG_ERR("failed to call export function in %s", name);
return NULL;
}
if(!decoder->SetFormat(decoder, media_type))
MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW);
break;
default:
- DEBUG_WARN("unknown capability type %d", CapabilityType);
+ CLOG_ERR("unknown capability type %d", CapabilityType);
break;
}
Stream_SetPosition(ifman->output, pos + cbCapabilityLength);
if(presentation)
tsmf_presentation_free(presentation);
else
- DEBUG_WARN("unknown presentation id");
+ CLOG_ERR("unknown presentation id");
Stream_EnsureRemainingCapacity(ifman->output, 4);
Stream_Write_UINT32(ifman->output, 0); /* Result */
ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
}
else
{
- DEBUG_WARN("unknown presentation id");
+ CLOG_ERR("unknown presentation id");
}
ifman->output_pending = TRUE;
return 0;
presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
if(presentation == NULL)
{
- DEBUG_WARN("unknown presentation id");
+ CLOG_ERR("unknown presentation id");
return 1;
}
stream = tsmf_stream_find_by_id(presentation, StreamId);
if(stream == NULL)
{
- DEBUG_WARN("unknown stream id");
+ CLOG_ERR("unknown stream id");
return 1;
}
tsmf_stream_push_sample(stream, ifman->channel_callback,
presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
if(presentation == NULL)
{
- DEBUG_WARN("unknown presentation id");
+ CLOG_ERR("unknown presentation id");
return 1;
}
tsmf_presentation_flush(presentation);
if(presentation)
tsmf_presentation_start(presentation);
else
- DEBUG_WARN("unknown presentation id");
+ CLOG_ERR("unknown presentation id");
Stream_EnsureRemainingCapacity(ifman->output, 16);
Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
Stream_Write_UINT32(ifman->output, 0); /* StreamId */
if(presentation)
tsmf_presentation_paused(presentation);
else
- DEBUG_WARN("unknown presentation id");
+ CLOG_ERR("unknown presentation id");
return 0;
}
if(presentation)
tsmf_presentation_restarted(presentation);
else
- DEBUG_WARN("unknown presentation id");
+ CLOG_ERR("unknown presentation id");
return 0;
}
if(presentation)
tsmf_presentation_stop(presentation);
else
- DEBUG_WARN("unknown presentation id");
+ CLOG_ERR("unknown presentation id");
Stream_EnsureRemainingCapacity(ifman->output, 16);
Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
Stream_Write_UINT32(ifman->output, 0); /* StreamId */
Stream_Write_UINT64(s, data_size); /* cbData */
DEBUG_TSMF("response size %d", (int) Stream_GetPosition(s));
if(!callback || !callback->channel || !callback->channel->Write)
- DEBUG_WARN("callback=%p, channel=%p, write=%p", callback,
+ CLOG_ERR("callback=%p, channel=%p, write=%p", callback,
callback->channel, callback->channel->Write);
else
status = callback->channel->Write(callback->channel,
Stream_GetPosition(s), Stream_Buffer(s), NULL);
if(status)
{
- DEBUG_WARN("response error %d", status);
+ CLOG_ERR("response error %d", status);
}
Stream_Free(s, TRUE);
}
status = callback->channel_mgr->PushEvent(callback->channel_mgr, event);
if(status)
{
- DEBUG_WARN("response error %d", status);
+ CLOG_ERR("response error %d", status);
return FALSE;
}
return TRUE;
/* 2.2.1 Shared Message Header (SHARED_MSG_HEADER) */
if(cbSize < 12)
{
- DEBUG_WARN("invalid size. cbSize=%d", cbSize);
+ CLOG_ERR("invalid size. cbSize=%d", cbSize);
return 1;
}
}
if(status == -1)
{
- DEBUG_WARN("InterfaceId 0x%X FunctionId 0x%X not processed.",
+ CLOG_ERR("InterfaceId 0x%X FunctionId 0x%X not processed.",
InterfaceId, FunctionId);
/* When a request is not implemented we return empty response indicating error */
}
status = callback->channel->Write(callback->channel, length, Stream_Buffer(output), NULL);
if(status)
{
- DEBUG_WARN("response error %d", status);
+ CLOG_ERR("response error %d", status);
}
}
Stream_Free(output, TRUE);
if (!presentation)
{
- DEBUG_WARN("calloc failed");
+ CLOG_ERR("calloc failed");
return NULL;
}
ArrayList_Unlock(presentation_list);
if (!found)
- DEBUG_WARN("presentation id %s not found", guid_to_string(guid, guid_str, sizeof(guid_str)));
+ CLOG_ERR("presentation id %s not found", guid_to_string(guid, guid_str, sizeof(guid_str)));
return (found) ? presentation : NULL;
}
if (stream)
{
- DEBUG_WARN("duplicated stream id %d!", stream_id);
+ CLOG_ERR("duplicated stream id %d!", stream_id);
return NULL;
}
if (!stream)
{
- DEBUG_WARN("Calloc failed");
+ CLOG_ERR("Calloc failed");
return NULL;
}
if (stream->decoder)
{
- DEBUG_WARN("duplicated call");
+ CLOG_ERR("duplicated call");
return;
}
if (!sample)
{
- DEBUG_WARN("calloc failed!");
+ CLOG_ERR("calloc failed!");
return;
}
if (!sample->data)
{
- DEBUG_WARN("calloc failed!");
+ CLOG_ERR("calloc failed!");
free(sample);
return;
}
#include <freerdp/dvc.h>
#include <freerdp/types.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#ifdef WITH_DEBUG_TSMF
-#define DEBUG_TSMF(fmt, ...) DEBUG_CLASS(TSMF, fmt, ## __VA_ARGS__)
+#define DEBUG_TSMF(fmt, ...) CLOG_CLASS(TSMF, fmt, ## __VA_ARGS__)
#else
-#define DEBUG_TSMF(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
+#define DEBUG_TSMF(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__)
#endif
typedef struct _TS_AM_MEDIA_TYPE
{
case IOCTL_INTERNAL_USB_SUBMIT_URB: /** 0x00220003 */
LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_SUBMIT_URB"));
- fprintf(stderr, " Function IOCTL_INTERNAL_USB_SUBMIT_URB: Unchecked\n");
+ CLOG_ERR( " Function IOCTL_INTERNAL_USB_SUBMIT_URB: Unchecked\n");
break;
case IOCTL_INTERNAL_USB_RESET_PORT: /** 0x00220007 */
case IOCTL_INTERNAL_USB_CYCLE_PORT: /** 0x0022001F */
LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_CYCLE_PORT"));
- fprintf(stderr, " Function IOCTL_INTERNAL_USB_CYCLE_PORT: Unchecked\n");
+ CLOG_ERR( " Function IOCTL_INTERNAL_USB_CYCLE_PORT: Unchecked\n");
break;
case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: /** 0x00220027 */
LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION"));
- fprintf(stderr, " Function IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: Unchecked\n");
+ CLOG_ERR( " Function IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: Unchecked\n");
break;
default:
if (transferDir == 0)
{
- fprintf(stderr, "urb_select_configuration: not support transfer out\n");
+ CLOG_ERR( "urb_select_configuration: not support transfer out\n");
return -1;
}
if (transferDir == 0)
{
- fprintf(stderr, "urb_select_interface: not support transfer out\n");
+ CLOG_ERR( "urb_select_interface: not support transfer out\n");
return -1;
}
switch (transferDir)
{
case USBD_TRANSFER_DIRECTION_OUT:
- fprintf(stderr, "Function urb_os_feature_descriptor_request: OUT Unchecked\n");
+ CLOG_ERR( "Function urb_os_feature_descriptor_request: OUT Unchecked\n");
memcpy(buffer, data + offset, OutputBufferSize);
break;
case USBD_TRANSFER_DIRECTION_IN:
switch (transferDir)
{
case USBD_TRANSFER_DIRECTION_OUT:
- fprintf(stderr, "Function urb_control_feature_request: OUT Unchecked\n");
+ CLOG_ERR( "Function urb_control_feature_request: OUT Unchecked\n");
memcpy(buffer, data + offset, OutputBufferSize);
bmRequestType |= 0x00;
break;
bmRequest = 0x01; /* REQUEST_CLEAR_FEATURE */
break;
default:
- fprintf(stderr, "urb_control_feature_request: Error Command %x\n", command);
+ CLOG_ERR( "urb_control_feature_request: Error Command %x\n", command);
zfree(out_data);
return -1;
}
}
else
{
- //fprintf(stderr, "actual length %d \n", act_len);
+ //CLOG_ERR( "actual length %d \n", act_len);
//exit(EXIT_FAILURE);
}
}
if (ret < 0)
{
- fprintf(stderr, "config_release_all_interface: error num %d\n", ret);
+ CLOG_ERR( "config_release_all_interface: error num %d\n", ret);
return -1;
}
}
if (ret < 0)
{
- fprintf(stderr, "claim_all_interface: error num %d\n", ret);
+ CLOG_ERR( "claim_all_interface: error num %d\n", ret);
return -1;
}
}
switch (status)
{
case LIBUSB_TRANSFER_COMPLETED:
- //fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_COMPLETED\n");
+ //CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_COMPLETED\n");
break;
case LIBUSB_TRANSFER_ERROR:
- fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_ERROR\n");
+ CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_ERROR\n");
break;
case LIBUSB_TRANSFER_TIMED_OUT:
- fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_TIMED_OUT\n");
+ CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_TIMED_OUT\n");
break;
case LIBUSB_TRANSFER_CANCELLED:
- fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_CANCELLED\n");
+ CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_CANCELLED\n");
break;
case LIBUSB_TRANSFER_STALL:
- fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_STALL\n");
+ CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_STALL\n");
break;
case LIBUSB_TRANSFER_NO_DEVICE:
- fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_NO_DEVICE\n");
+ CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_NO_DEVICE\n");
break;
case LIBUSB_TRANSFER_OVERFLOW:
- fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_OVERFLOW\n");
+ CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_OVERFLOW\n");
break;
default:
- fprintf(stderr, "Transfer Status: Get unknow error num %d (0x%x)\n",
+ CLOG_ERR( "Transfer Status: Get unknow error num %d (0x%x)\n",
status, status);
}
return 0;
switch (status)
{
case LIBUSB_TRANSFER_COMPLETED:
- fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_COMPLETED\n");
+ CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_COMPLETED\n");
break;
case LIBUSB_TRANSFER_ERROR:
- fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_ERROR\n");
+ CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_ERROR\n");
break;
case LIBUSB_TRANSFER_TIMED_OUT:
- fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_TIMED_OUT\n");
+ CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_TIMED_OUT\n");
break;
case LIBUSB_TRANSFER_CANCELLED:
- fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_CANCELLED\n");
+ CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_CANCELLED\n");
break;
case LIBUSB_TRANSFER_STALL:
- fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_STALL\n");
+ CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_STALL\n");
break;
case LIBUSB_TRANSFER_NO_DEVICE:
- fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_NO_DEVICE\n");
+ CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_NO_DEVICE\n");
break;
case LIBUSB_TRANSFER_OVERFLOW:
- fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_OVERFLOW\n");
+ CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_OVERFLOW\n");
break;
default:
- fprintf(stderr, "Transfer status: unknow status %d(0x%x)\n", status, status);
+ CLOG_ERR( "Transfer status: unknow status %d(0x%x)\n", status, status);
break;
}
}
if (ret < 0)
{
- fprintf(stderr, "libusb_get_device_descriptor: ERROR!!\n");
+ CLOG_ERR( "libusb_get_device_descriptor: ERROR!!\n");
free(descriptor);
return NULL;
}
if (error < 0)
{
- fprintf(stderr, "%s: Set interface altsetting get error num %d\n",
+ CLOG_ERR( "%s: Set interface altsetting get error num %d\n",
__func__, error);
}
}
LibusbConfig = pdev->LibusbConfig;
if (LibusbConfig->bNumInterfaces != MsConfig->NumInterfaces)
{
- fprintf(stderr, "Select Configuration: Libusb NumberInterfaces(%d) is different "
+ CLOG_ERR( "Select Configuration: Libusb NumberInterfaces(%d) is different "
"with MsConfig NumberInterfaces(%d)\n",
LibusbConfig->bNumInterfaces, MsConfig->NumInterfaces);
}
ret = libusb_set_configuration(libusb_handle, bConfigurationValue);
if (ret < 0){
- fprintf(stderr, "libusb_set_configuration: ERROR number %d!!\n", ret);
+ CLOG_ERR( "libusb_set_configuration: ERROR number %d!!\n", ret);
func_claim_all_interface(libusb_handle, (*LibusbConfig)->bNumInterfaces);
return -1;
}
{
ret = libusb_get_active_config_descriptor (libusb_dev, LibusbConfig);
if (ret < 0){
- fprintf(stderr, "libusb_get_config_descriptor_by_value: ERROR number %d!!\n", ret);
+ CLOG_ERR( "libusb_get_config_descriptor_by_value: ERROR number %d!!\n", ret);
func_claim_all_interface(libusb_handle, (*LibusbConfig)->bNumInterfaces);
return -1;
}
*UsbdStatus = 0;
/*
if(pdev->request_queue->unregister_request(pdev->request_queue, RequestId))
- fprintf(stderr, "request_queue_unregister_request: not fount request 0x%x\n", RequestId);
+ CLOG_ERR( "request_queue_unregister_request: not fount request 0x%x\n", RequestId);
*/
return error;
}
ms_string_desc,
0x12,
Timeout);
- //fprintf(stderr, "Get ms string: result number %d", error);
+ //CLOG_ERR( "Get ms string: result number %d", error);
if (error > 0)
{
BYTE bMS_Vendorcode;
data_read_BYTE(ms_string_desc + 16, bMS_Vendorcode);
- //fprintf(stderr, "bMS_Vendorcode:0x%x", bMS_Vendorcode);
+ //CLOG_ERR( "bMS_Vendorcode:0x%x", bMS_Vendorcode);
/** get os descriptor */
error = libusb_control_transfer(pdev->libusb_handle,
LIBUSB_ENDPOINT_IN |LIBUSB_REQUEST_TYPE_VENDOR | Recipient,
*UsbdStatus = USBD_STATUS_SUCCESS;
/*
if(pdev->request_queue->unregister_request(pdev->request_queue, RequestId))
- fprintf(stderr, "request_queue_unregister_request: not fount request 0x%x\n", RequestId);
+ CLOG_ERR( "request_queue_unregister_request: not fount request 0x%x\n", RequestId);
*/
return error;
}
if (iso_transfer == NULL)
{
- fprintf(stderr, "Error: libusb_alloc_transfer.\n");
+ CLOG_ERR( "Error: libusb_alloc_transfer.\n");
status = -1;
}
if (!ep_desc)
{
- fprintf(stderr, "func_get_ep_desc: endpoint 0x%x is not found!!\n", EndpointAddress);
+ CLOG_ERR( "func_get_ep_desc: endpoint 0x%x is not found!!\n", EndpointAddress);
return -1;
}
transfer_type = (ep_desc->bmAttributes) & 0x3;
if (request)
{
if(pdev->request_queue->unregister_request(pdev->request_queue, RequestId))
- fprintf(stderr, "request_queue_unregister_request: not fount request 0x%x\n", RequestId);
+ CLOG_ERR( "request_queue_unregister_request: not fount request 0x%x\n", RequestId);
}
libusb_free_transfer(transfer);
if (status < 0)
{
- fprintf(stderr, "USB init: Error to get HUB handle!!\n");
+ CLOG_ERR( "USB init: Error to get HUB handle!!\n");
pdev->hub_handle = NULL;
}
if (!pdev->devDescriptor)
{
- fprintf(stderr, "USB init: Error to get device descriptor!!\n");
+ CLOG_ERR( "USB init: Error to get device descriptor!!\n");
zfree(pdev);
return NULL;
}
if (status < 0)
{
- fprintf(stderr, "libusb_get_descriptor: ERROR!!ret:%d\n", status);
+ CLOG_ERR( "libusb_get_descriptor: ERROR!!ret:%d\n", status);
zfree(pdev);
return NULL;
}
case CLASS_CONTENT_SECURITY:
//case CLASS_WIRELESS_CONTROLLER:
//case CLASS_ELSE_DEVICE:
- fprintf(stderr, " Device is not supported!!\n");
+ CLOG_ERR( " Device is not supported!!\n");
zfree(pdev);
return NULL;
default:
ssize_t total_device;
int i, status, num = 0;
- fprintf(stderr, "VID: 0x%04X PID: 0x%04X\n", idVendor, idProduct);
+ CLOG_ERR( "VID: 0x%04X PID: 0x%04X\n", idVendor, idProduct);
array = (UDEVICE**) malloc(16 * sizeof(UDEVICE*));
if (status < 0)
{
- fprintf(stderr, "libusb_open: (by id) error: 0x%08X (%d)\n", status, status);
+ CLOG_ERR( "libusb_open: (by id) error: 0x%08X (%d)\n", status, status);
zfree(descriptor);
zfree(array[num]);
continue;
if (pDev->libusb_dev == NULL)
{
- fprintf(stderr, "libusb_device_new: ERROR!!\n");
+ CLOG_ERR( "libusb_device_new: ERROR!!\n");
zfree(pDev);
return NULL;
}
if (status < 0)
{
- fprintf(stderr, "libusb_open: (by addr) ERROR!!\n");
+ CLOG_ERR( "libusb_open: (by addr) ERROR!!\n");
zfree(pDev);
return NULL;
}
}
else
{
- fprintf(stderr, "udevman_register_udevice: function error!!");
+ CLOG_ERR( "udevman_register_udevice: function error!!");
return 0;
}
}
}
pthread_mutex_unlock(&queue->request_loading);
- fprintf(stderr, "request_queue_get_request_by_id: ERROR!!\n");
+ CLOG_ERR( "request_queue_get_request_by_id: ERROR!!\n");
return NULL;
}
int num = 0;
USB_SEARCHDEV* usb;
- fprintf(stderr, "=========== Usb Search List ========= \n");
+ CLOG_ERR( "=========== Usb Search List ========= \n");
self->rewind(self);
while (self->has_next(self))
{
usb = self->get_next(self);
- fprintf(stderr, " USB %d: \n", num++);
- fprintf(stderr, " idVendor: 0x%04X \n", usb->idVendor);
- fprintf(stderr, " idProduct: 0x%04X \n", usb->idProduct);
+ CLOG_ERR( " USB %d: \n", num++);
+ CLOG_ERR( " idVendor: 0x%04X \n", usb->idVendor);
+ CLOG_ERR( " idProduct: 0x%04X \n", usb->idProduct);
}
- fprintf(stderr, "================= END =============== \n");
+ CLOG_ERR( "================= END =============== \n");
}
void searchman_free(USB_SEARCHMAN* self)
if (ret != 0)
{
- fprintf(stderr, "searchman mutex initialization: searchman->mutex failed");
+ CLOG_ERR( "searchman mutex initialization: searchman->mutex failed");
exit(EXIT_FAILURE);
}
#include <freerdp/dvc.h>
#include <freerdp/addin.h>
+#include <freerdp/channels/log.h>
#include "urbdrc_types.h"
#include "urbdrc_main.h"
if (!udev)
{
- fprintf(stderr, "Can't create udev\n");
+ CLOG_ERR( "Can't create udev\n");
return 0;
}
}
else
{
- fprintf(stderr, "No Device from receive_device(). An error occured.\n");
+ CLOG_ERR( "No Device from receive_device(). An error occured.\n");
}
}
}
if (transfer_data == NULL)
{
- fprintf(stderr, "transfer_data is NULL!!");
+ CLOG_ERR( "transfer_data is NULL!!");
return 0;
}
if (urbdrc->udevman)
{
- DEBUG_WARN("existing device, abort.");
+ CLOG_ERR("existing device, abort.");
return;
}
if (entry(&entryPoints) != 0)
{
- DEBUG_WARN("%s entry returns error.", name);
+ CLOG_ERR("%s entry returns error.", name);
return FALSE;
}
#include <freerdp/dvc.h>
#include <freerdp/types.h>
-#include <freerdp/utils/debug.h>
+#include <freerdp/channels/log.h>
#include <freerdp/utils/msusb.h>
#include <uuid/uuid.h>
#include <winpr/stream.h>
#ifdef WITH_DEBUG_DVC
-#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__)
+#define DEBUG_DVC(fmt, ...) CLOG_CLASS(DVC, fmt, ## __VA_ARGS__)
#else
-#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
+#define DEBUG_DVC(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__)
#endif
#define CAPABILITIES_NEGOTIATOR 0x00000000
#define MAX_URB_REQUSET_NUM 0x80
#define LOG_LEVEL 1
-#define LLOG(_level, _args) \
- do { if (_level < LOG_LEVEL) { printf _args ; } } while (0)
-#define LLOGLN(_level, _args) \
- do { if (_level < LOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
+#define LLOG(_level, args) \
+ do { if (_level < LOG_LEVEL) { CLOG_DBG args ; } } while (0)
+#define LLOGLN(_level, args) \
+ do { if (_level < LOG_LEVEL) { CLOG_DBG args ; } } while (0)
#define dummy_wait_obj(void) do{ sleep(5); } while(0)
#define dummy_wait_s_obj(_s) do{ sleep(_s); } while(0)
}
}
-static void *jni_update_thread(void *arg)
-{
- int status;
- wMessage message;
- wMessageQueue* queue;
- freerdp* instance = (freerdp*) arg;
-
- assert( NULL != instance);
-
- DEBUG_ANDROID("Start.");
-
- status = 1;
- queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
-
- while (MessageQueue_Wait(queue))
- {
- while (MessageQueue_Peek(queue, &message, TRUE))
- {
- status = freerdp_message_queue_process_message(instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message);
-
- if (!status)
- break;
- }
-
- if (!status)
- break;
- }
-
- DEBUG_ANDROID("Quit.");
-
- ExitThread(0);
- return NULL;
-}
-
static void* jni_input_thread(void* arg)
{
HANDLE event[3];
const rdpSettings* settings = instance->context->settings;
- HANDLE update_thread;
HANDLE input_thread;
HANDLE channels_thread;
- BOOL async_update = settings->AsyncUpdate;
BOOL async_input = settings->AsyncInput;
BOOL async_channels = settings->AsyncChannels;
BOOL async_transport = settings->AsyncTransport;
return 0;
}
- if (async_update)
- {
- update_thread = CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE) jni_update_thread, instance, 0, NULL);
- }
-
if (async_input)
{
input_thread = CreateThread(NULL, 0,
WaitForSingleObject(channels_thread, INFINITE);
CloseHandle(channels_thread);
}
-
- if (async_update)
- {
- wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
- MessageQueue_PostQuit(update_queue, 0);
- WaitForSingleObject(update_thread, INFINITE);
- CloseHandle(update_thread);
- }
-
+
if (async_input)
{
wMessageQueue* input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
}
/* store performance settings */
- if (disableWallpaper == JNI_TRUE)
- settings->DisableWallpaper = TRUE;
-
- if (disableFullWindowDrag == JNI_TRUE)
- settings->DisableFullWindowDrag = TRUE;
-
- if (disableMenuAnimations == JNI_TRUE)
- settings->DisableMenuAnims = TRUE;
-
- if (disableTheming == JNI_TRUE)
- settings->DisableThemes = TRUE;
-
- if (enableFontSmoothing == JNI_TRUE)
- settings->AllowFontSmoothing = TRUE;
-
- if(enableDesktopComposition == JNI_TRUE)
- settings->AllowDesktopComposition = TRUE;
-
+ settings->DisableWallpaper = (disableWallpaper == JNI_TRUE) ? TRUE : FALSE;
+ settings->DisableFullWindowDrag = (disableFullWindowDrag == JNI_TRUE) ? TRUE : FALSE;
+ settings->DisableMenuAnims = (disableMenuAnimations == JNI_TRUE) ? TRUE : FALSE;
+ settings->DisableThemes = (disableTheming == JNI_TRUE) ? TRUE : FALSE;
+ settings->AllowFontSmoothing = (enableFontSmoothing == JNI_TRUE) ? TRUE : FALSE;
+ settings->AllowDesktopComposition = (enableDesktopComposition == JNI_TRUE) ? TRUE : FALSE;
/* Create performance flags from settings */
- settings->PerformanceFlags = PERF_FLAG_NONE;
- if (settings->AllowFontSmoothing)
- settings->PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING;
-
- if (settings->AllowDesktopComposition)
- settings->PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION;
-
- if (settings->DisableWallpaper)
- settings->PerformanceFlags |= PERF_DISABLE_WALLPAPER;
-
- if (settings->DisableFullWindowDrag)
- settings->PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG;
-
- if (settings->DisableMenuAnims)
- settings->PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS;
-
- if (settings->DisableThemes)
- settings->PerformanceFlags |= PERF_DISABLE_THEMING;
+ freerdp_performance_flags_make(settings);
DEBUG_ANDROID("performance_flags: %04X", settings->PerformanceFlags);
}
break;
default:
- fprintf(stderr, "df_process_channel_event: unknown event type %d\n", GetMessageType(event->id));
+ DEBUG_WARN( "df_process_channel_event: unknown event type %d\n", GetMessageType(event->id));
break;
}
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
- fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
+ DEBUG_WARN( "Failed to get FreeRDP file descriptor\n");
break;
}
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
- fprintf(stderr, "Failed to get channel manager file descriptor\n");
+ DEBUG_WARN( "Failed to get channel manager file descriptor\n");
break;
}
if (df_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
- fprintf(stderr, "Failed to get dfreerdp file descriptor\n");
+ DEBUG_WARN( "Failed to get dfreerdp file descriptor\n");
break;
}
(errno == EINPROGRESS) ||
(errno == EINTR))) /* signal occurred */
{
- fprintf(stderr, "dfreerdp_run: select failed\n");
+ DEBUG_WARN( "dfreerdp_run: select failed\n");
break;
}
}
if (freerdp_check_fds(instance) != TRUE)
{
- fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
+ DEBUG_WARN( "Failed to check FreeRDP file descriptor\n");
break;
}
if (df_check_fds(instance, &rfds_set) != TRUE)
{
- fprintf(stderr, "Failed to check dfreerdp file descriptor\n");
+ DEBUG_WARN( "Failed to check dfreerdp file descriptor\n");
break;
}
if (freerdp_channels_check_fds(channels, instance) != TRUE)
{
- fprintf(stderr, "Failed to check channel manager file descriptor\n");
+ DEBUG_WARN( "Failed to check channel manager file descriptor\n");
break;
}
df_process_channel_event(channels, instance);
vkcode &= 0xFF;
#if 0
- fprintf(stderr, "keyDown: keyCode: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n",
+ DEBUG_WARN( "keyDown: keyCode: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n",
keyCode, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode));
#endif
vkcode &= 0xFF;
#if 0
- fprintf(stderr, "keyUp: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n",
+ DEBUG_WARN( "keyUp: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n",
keyCode, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode));
#endif
vkcode &= 0xFF;
#if 0
- fprintf(stderr, "flagsChanged: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X extended: %d name: %s modFlags: 0x%04X\n",
+ DEBUG_WARN( "flagsChanged: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X extended: %d name: %s modFlags: 0x%04X\n",
key - 8, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode), modFlags);
if (modFlags & NSAlphaShiftKeyMask)
- fprintf(stderr, "NSAlphaShiftKeyMask\n");
+ DEBUG_WARN( "NSAlphaShiftKeyMask\n");
if (modFlags & NSShiftKeyMask)
- fprintf(stderr, "NSShiftKeyMask\n");
+ DEBUG_WARN( "NSShiftKeyMask\n");
if (modFlags & NSControlKeyMask)
- fprintf(stderr, "NSControlKeyMask\n");
+ DEBUG_WARN( "NSControlKeyMask\n");
if (modFlags & NSAlternateKeyMask)
- fprintf(stderr, "NSAlternateKeyMask\n");
+ DEBUG_WARN( "NSAlternateKeyMask\n");
if (modFlags & NSCommandKeyMask)
- fprintf(stderr, "NSCommandKeyMask\n");
+ DEBUG_WARN( "NSCommandKeyMask\n");
if (modFlags & NSNumericPadKeyMask)
- fprintf(stderr, "NSNumericPadKeyMask\n");
+ DEBUG_WARN( "NSNumericPadKeyMask\n");
if (modFlags & NSHelpKeyMask)
- fprintf(stderr, "NSHelpKeyMask\n");
+ DEBUG_WARN( "NSHelpKeyMask\n");
#endif
if ((modFlags & NSAlphaShiftKeyMask) && !(kbdModFlags & NSAlphaShiftKeyMask))
if (!settings->ServerHostname)
{
- fprintf(stderr, "error: server hostname was not specified with /v:<server>[:port]\n");
+ DEBUG_WARN( "error: server hostname was not specified with /v:<server>[:port]\n");
[NSApp terminate:nil];
return -1;
}
}
else
{
- fprintf(stderr, "update_activity_cb: No queue!\n");
+ DEBUG_WARN( "update_activity_cb: No queue!\n");
}
}
}
else
{
- fprintf(stderr, "input_activity_cb: No queue!\n");
+ DEBUG_WARN( "input_activity_cb: No queue!\n");
}
}
if (event)
{
- fprintf(stderr, "channel_activity_cb: message %d\n", event->id);
+ DEBUG_WARN( "channel_activity_cb: message %d\n", event->id);
switch (GetMessageClass(event->id))
{
if (g_thread_count < 1)
ReleaseSemaphore(g_sem, 1, NULL);
+ ExitThread(0);
return NULL;
}
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-
#include <assert.h>
#include <winpr/crt.h>
#include "wf_cliprdr.h"
+extern BOOL WINAPI AddClipboardFormatListener(_In_ HWND hwnd);
+extern BOOL WINAPI RemoveClipboardFormatListener(_In_ HWND hwnd);
+
#define WM_CLIPRDR_MESSAGE (WM_USER + 156)
#define OLE_SETCLIPBOARD 1
cliprdr->map_size= 0;
}
-
+/*
+2.2.2.3 Client Temporary Directory PDU (CLIPRDR_TEMP_DIRECTORY)
+ The Temporary Directory PDU is an optional PDU sent from the client to the server.
+ This PDU informs the server of a location on the client file system that MUST be
+ used to deposit files being copied to the client. The location MUST be accessible
+ by the server to be useful. Section 3.1.1.3 specifies how direct file access
+ impacts file copy and paste.
+*/
int cliprdr_send_tempdir(cliprdrContext *cliprdr)
{
RDP_CB_TEMPDIR_EVENT *cliprdr_event;
if (!cliprdr_event)
return -1;
+ /* Sending the TEMP path would only be valid iff the path is accessible from the server.
+ This should perhaps to change to a command line parameter value
+ */
GetEnvironmentVariableW(L"TEMP", (LPWSTR)cliprdr_event->dirname, 260);
return freerdp_channels_send_event(cliprdr->channels, (wMessage *)cliprdr_event);
switch (Msg)
{
case WM_CREATE:
+ DEBUG_CLIPRDR("info: %s - WM_CREATE", __FUNCTION__);
cliprdr = (cliprdrContext *)((CREATESTRUCT *)lParam)->lpCreateParams;
- cliprdr->hwndNextViewer = SetClipboardViewer(hWnd);
-
- if (cliprdr->hwndNextViewer == NULL && GetLastError() != 0)
- {
- DEBUG_CLIPRDR("error: SetClipboardViewer failed with 0x%0x.", GetLastError());
+ if (!AddClipboardFormatListener(hWnd)) {
+ DEBUG_CLIPRDR("error: AddClipboardFormatListener failed with %#x.", GetLastError());
}
cliprdr->hwndClipboard = hWnd;
break;
case WM_CLOSE:
- ChangeClipboardChain(hWnd, cliprdr->hwndNextViewer);
+ DEBUG_CLIPRDR("info: %s - WM_CLOSE", __FUNCTION__);
+ RemoveClipboardFormatListener(hWnd);
break;
- case WM_CHANGECBCHAIN:
- if (cliprdr->hwndNextViewer == (HWND)wParam)
- {
- cliprdr->hwndNextViewer = (HWND)lParam;
- }
- else if (cliprdr->hwndNextViewer != NULL)
- {
- SendMessage(cliprdr->hwndNextViewer, Msg, wParam, lParam);
- }
- break;
-
- case WM_DRAWCLIPBOARD:
+ case WM_CLIPBOARDUPDATE:
+ DEBUG_CLIPRDR("info: %s - WM_CLIPBOARDUPDATE", __FUNCTION__);
if (cliprdr->channel_initialized)
{
if ((GetClipboardOwner() != cliprdr->hwndClipboard) && (S_FALSE == OleIsCurrentClipboard(cliprdr->data_obj)))
cliprdr_send_format_list(cliprdr);
}
}
- if (cliprdr->hwndNextViewer != NULL && cliprdr->hwndNextViewer != hWnd)
- SendMessage(cliprdr->hwndNextViewer, Msg, wParam, lParam);
break;
case WM_RENDERALLFORMATS:
+ DEBUG_CLIPRDR("info: %s - WM_RENDERALLFORMATS", __FUNCTION__);
/* discard all contexts in clipboard */
if (!OpenClipboard(cliprdr->hwndClipboard))
{
break;
case WM_RENDERFORMAT:
+ DEBUG_CLIPRDR("info: %s - WM_RENDERFORMAT", __FUNCTION__);
if (cliprdr_send_data_request(cliprdr, (UINT32)wParam) != 0)
{
DEBUG_CLIPRDR("error: cliprdr_send_data_request failed.");
break;
case WM_CLIPRDR_MESSAGE:
+ DEBUG_CLIPRDR("info: %s - WM_CLIPRDR_MESSAGE", __FUNCTION__);
switch (wParam)
{
case OLE_SETCLIPBOARD:
+ DEBUG_CLIPRDR("info: %s - OLE_SETCLIPBOARD", __FUNCTION__);
if (wf_create_file_obj(cliprdr, &cliprdr->data_obj))
if (OleSetClipboard(cliprdr->data_obj) != S_OK)
wf_destroy_file_obj(cliprdr->data_obj);
}
break;
- case WM_CLIPBOARDUPDATE:
case WM_DESTROYCLIPBOARD:
case WM_ASKCBFORMATNAME:
case WM_HSCROLLCLIPBOARD:
if (!wfc->instance->settings->RedirectClipboard)
{
wfc->cliprdr_context = NULL;
- fprintf(stderr, "clipboard is not redirected.\n");
+ DEBUG_WARN( "clipboard is not redirected.\n");
return;
}
static void wf_cliprdr_process_cb_monitor_ready_event(wfContext *wfc, RDP_CB_MONITOR_READY_EVENT *ready_event)
{
cliprdrContext *cliprdr = (cliprdrContext *)wfc->cliprdr_context;
-
+#if 0
+ /*Disabled since the current function only sends the temp directory which is not
+ guaranteed to be accessible to the server
+ */
cliprdr_send_tempdir(cliprdr);
-
+#endif
cliprdr->channel_initialized = TRUE;
cliprdr_send_format_list(wfc->cliprdr_context);
if (file_name == NULL || buffer == NULL || puSize == NULL)
{
- fprintf(stderr, "get file contents Invalid Arguments.\n");
+ DEBUG_WARN( "get file contents Invalid Arguments.\n");
return FALSE;
}
hFile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
hRet = OleGetClipboard(&pDataObj);
if (!SUCCEEDED(hRet))
{
- fprintf(stderr, "filecontents: get ole clipboard failed.\n");
+ DEBUG_WARN( "filecontents: get ole clipboard failed.\n");
goto error;
}
event->nPositionLow, event->nPositionHigh, event->cbRequested, &uSize);
if (bRet == FALSE)
{
- fprintf(stderr, "get file contents failed.\n");
+ DEBUG_WARN( "get file contents failed.\n");
uSize = 0;
goto error;
}
IDataObject_Release(pDataObj);
pDataObj = NULL;
}
- fprintf(stderr, "filecontents: send failed response.\n");
+ DEBUG_WARN( "filecontents: send failed response.\n");
cliprdr_send_response_filecontents(cliprdr, event->streamId, 0, NULL);
return;
}
BOOL channel_initialized;
HWND hwndClipboard;
- HWND hwndNextViewer;
HANDLE cliprdr_thread;
HANDLE hmem;
// Set maximum window size for resizing
minmax = (MINMAXINFO*) lParam;
- wf_update_canvas_diff(wfc);
+
+ //always use the last determined canvas diff, because it could be
+ //that the window is minimized when this gets called
+ //wf_update_canvas_diff(wfc);
if (!wfc->fullscreen)
{
wfc->client_y = windowRect.top;
}
- wf_size_scrollbars(wfc, LOWORD(lParam), HIWORD(lParam));
+ if (wfc->client_width && wfc->client_height)
+ {
+ wf_size_scrollbars(wfc, LOWORD(lParam), HIWORD(lParam));
- // Workaround: when the window is maximized, the call to "ShowScrollBars" returns TRUE but has no effect.
- if (wParam == SIZE_MAXIMIZED && !wfc->fullscreen)
- SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED);
+ // Workaround: when the window is maximized, the call to "ShowScrollBars" returns TRUE but has no effect.
+ if (wParam == SIZE_MAXIMIZED && !wfc->fullscreen)
+ SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED);
+ }
break;
{
if ((rop2 < 0x01) || (rop2 > 0x10))
{
- fprintf(stderr, "Unsupported ROP2: %d\n", rop2);
+ DEBUG_WARN( "Unsupported ROP2: %d\n", rop2);
return FALSE;
}
RFX_MESSAGE* message;
BITMAPINFO bitmap_info;
- RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfc->rfx_context;
- NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfc->nsc_context;
-
tile_bitmap = (char*) malloc(32);
ZeroMemory(tile_bitmap, 32);
if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX)
{
- message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
+ freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_REMOTEFX);
+ message = rfx_process_message(wfc->codecs->rfx, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
/* blit each tile */
for (i = 0; i < message->numTiles; i++)
wf_invalidate_region(wfc, tx, ty, message->rects[i].width, message->rects[i].height);
}
- rfx_message_free(rfx_context, message);
+ rfx_message_free(wfc->codecs->rfx, message);
}
else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC)
{
- nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
+ freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_NSCODEC);
+ nsc_process_message(wfc->codecs->nsc, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
ZeroMemory(&bitmap_info, sizeof(bitmap_info));
bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmap_info.bmiHeader.biCompression = BI_RGB;
SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height,
- nsc_context->BitmapData, &bitmap_info, DIB_RGB_COLORS);
+ wfc->codecs->nsc->BitmapData, &bitmap_info, DIB_RGB_COLORS);
wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height);
}
}
else
{
- fprintf(stderr, "Unsupported codecID %d\n", surface_bits_command->codecID);
+ DEBUG_WARN( "Unsupported codecID %d\n", surface_bits_command->codecID);
}
if (tile_bitmap != NULL)
#include <winpr/crt.h>
-#include <freerdp/codec/bitmap.h>
+#include <freerdp/codecs.h>
#include "wf_gdi.h"
#include "wf_graphics.h"
}
void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap,
- BYTE* data, int width, int height, int bpp, int length, BOOL compressed, int codec_id)
+ BYTE* data, int width, int height, int bpp, int length, BOOL compressed, int codecId)
{
+ int status;
UINT16 size;
size = width * height * (bpp / 8);
if (compressed)
{
- BOOL status;
+ BYTE* pDstData;
+ UINT32 SrcSize;
- status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
+ SrcSize = (UINT32) length;
+ pDstData = bitmap->data;
- if (status != TRUE)
+ if (bpp < 32)
{
- fprintf(stderr, "Bitmap Decompression Failed\n");
+ 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");
+ }
+ }
+ else
+ {
+ freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_PLANAR);
+
+ status = planar_decompress(wfc->codecs->planar, data, SrcSize, &pDstData,
+ PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height);
+
+ if (status < 0)
+ {
+ DEBUG_WARN("wf_Bitmap_Decompress: Bitmap Decompression Failed\n");
+ }
}
}
else
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
- fprintf(stderr, "Debug console created.\n");
+ DEBUG_WARN( "Debug console created.\n");
return 0;
}
context = instance->context;
wfc = (wfContext*) instance->context;
wfc->instance = instance;
+ wfc->codecs = instance->context->codecs;
settings = instance->settings;
wfc->connectionRdpFile = freerdp_client_rdp_file_new();
- fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile);
+ DEBUG_WARN( "Using connection file: %s\n", settings->ConnectionFile);
freerdp_client_parse_rdp_file(wfc->connectionRdpFile, settings->ConnectionFile);
freerdp_client_populate_settings_from_rdp_file(wfc->connectionRdpFile, settings);
if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64) ||
(settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096))
{
- fprintf(stderr, "wf_pre_connect: invalid dimensions %d %d\n", settings->DesktopWidth, settings->DesktopHeight);
+ DEBUG_WARN( "wf_pre_connect: invalid dimensions %d %d\n", settings->DesktopWidth, settings->DesktopHeight);
return 1;
}
if (settings->RemoteFxCodec)
{
wfc->tile = wf_image_new(wfc, 64, 64, 32, NULL);
- wfc->rfx_context = rfx_context_new(FALSE);
- }
-
- if (settings->NSCodec)
- {
- wfc->nsc_context = nsc_context_new();
}
}
if (settings->EmbeddedWindow)
settings->Decorations = FALSE;
- if (!settings->Decorations)
+ if (wfc->fullscreen)
+ dwStyle = WS_POPUP;
+ else if (!settings->Decorations)
dwStyle = WS_CHILD | WS_BORDER;
else
- dwStyle = 0;
+ dwStyle = WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX;
if (!wfc->hwnd)
{
if (status != NO_ERROR)
{
- fprintf(stderr, "CredUIPromptForCredentials unexpected status: 0x%08X\n", status);
+ DEBUG_WARN( "CredUIPromptForCredentials unexpected status: 0x%08X\n", status);
return FALSE;
}
status = CredUIParseUserNameA(UserName, User, sizeof(User), Domain, sizeof(Domain));
- //fprintf(stderr, "User: %s Domain: %s Password: %s\n", User, Domain, Password);
+ //DEBUG_WARN( "User: %s Domain: %s Password: %s\n", User, Domain, Password);
*username = _strdup(User);
return FALSE;
/* A network disconnect was detected */
- fprintf(stderr, "Network disconnect!\n");
+ DEBUG_WARN( "Network disconnect!\n");
if (!instance->settings->AutoReconnectionEnabled)
{
/* No auto-reconnect - just quit */
return FALSE;
/* Attempt the next reconnect */
- fprintf(stderr, "Attempting reconnect (%u of %u)\n", num_retries, max_retries);
+ DEBUG_WARN( "Attempting reconnect (%u of %u)\n", num_retries, max_retries);
if (freerdp_reconnect(instance))
{
return TRUE;
Sleep(5000);
}
- fprintf(stderr, "Maximum reconnect retries exceeded\n");
+ DEBUG_WARN( "Maximum reconnect retries exceeded\n");
return FALSE;
}
return NULL;
}
-void* wf_update_thread(void* arg)
-{
- int status;
- wMessage message;
- wMessageQueue* queue;
- freerdp* instance = (freerdp*) arg;
-
- assert( NULL != instance);
-
- status = 1;
- queue = freerdp_get_message_queue(instance,
- FREERDP_UPDATE_MESSAGE_QUEUE);
-
- while (MessageQueue_Wait(queue))
- {
- while (MessageQueue_Peek(queue, &message, TRUE))
- {
- status = freerdp_message_queue_process_message(instance,
- FREERDP_UPDATE_MESSAGE_QUEUE, &message);
-
- if (!status)
- break;
- }
-
- if (!status)
- break;
- }
-
- ExitThread(0);
-
- return NULL;
-}
-
void* wf_channels_thread(void* arg)
{
int status;
rdpChannels* channels;
rdpSettings* settings;
- BOOL async_update;
BOOL async_input;
BOOL async_channels;
BOOL async_transport;
- HANDLE update_thread;
HANDLE input_thread;
HANDLE channels_thread;
channels = instance->context->channels;
settings = instance->context->settings;
- async_update = settings->AsyncUpdate;
async_input = settings->AsyncInput;
async_channels = settings->AsyncChannels;
async_transport = settings->AsyncTransport;
- if (async_update)
- {
- update_thread = CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE) wf_update_thread,
- instance, 0, NULL);
- }
-
if (async_input)
{
input_thread = CreateThread(NULL, 0,
{
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
- fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
+ DEBUG_WARN( "Failed to get FreeRDP file descriptor\n");
break;
}
}
if (wf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
- fprintf(stderr, "Failed to get wfreerdp file descriptor\n");
+ DEBUG_WARN( "Failed to get wfreerdp file descriptor\n");
break;
}
{
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
- fprintf(stderr, "Failed to get channel manager file descriptor\n");
+ DEBUG_WARN( "Failed to get channel manager file descriptor\n");
break;
}
}
/* exit if nothing to do */
if (fds_count == 0)
{
- fprintf(stderr, "wfreerdp_run: fds_count is zero\n");
+ DEBUG_WARN( "wfreerdp_run: fds_count is zero\n");
//break;
}
/* do the wait */
if (MsgWaitForMultipleObjects(fds_count, fds, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED)
{
- fprintf(stderr, "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X\n", GetLastError());
+ DEBUG_WARN( "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X\n", GetLastError());
break;
}
if (wf_auto_reconnect(instance))
continue;
- fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
+ DEBUG_WARN( "Failed to check FreeRDP file descriptor\n");
break;
}
}
}
if (wf_check_fds(instance) != TRUE)
{
- fprintf(stderr, "Failed to check wfreerdp file descriptor\n");
+ DEBUG_WARN( "Failed to check wfreerdp file descriptor\n");
break;
}
{
if (freerdp_channels_check_fds(channels, instance) != TRUE)
{
- fprintf(stderr, "Failed to check channel manager file descriptor\n");
+ DEBUG_WARN( "Failed to check channel manager file descriptor\n");
break;
}
/* cleanup */
freerdp_channels_close(channels, instance);
- if (async_update)
- {
- wMessageQueue* update_queue;
-
- update_queue = freerdp_get_message_queue(instance,
- FREERDP_UPDATE_MESSAGE_QUEUE);
- MessageQueue_PostQuit(update_queue, 0);
- WaitForSingleObject(update_thread, INFINITE);
- CloseHandle(update_thread);
- }
-
if (async_input)
{
wMessageQueue* input_queue;
{
if (status == -1)
{
- fprintf(stderr, "keyboard thread error getting message\n");
+ DEBUG_WARN( "keyboard thread error getting message\n");
break;
}
else
}
else
{
- fprintf(stderr, "failed to install keyboard hook\n");
+ DEBUG_WARN( "failed to install keyboard hook\n");
}
printf("Keyboard thread exited.\n");
int freerdp_client_set_window_size(wfContext* wfc, int width, int height)
{
- fprintf(stderr, "freerdp_client_set_window_size %d, %d", width, height);
+ DEBUG_WARN( "freerdp_client_set_window_size %d, %d", width, height);
if ((width != wfc->client_width) || (height != wfc->client_height))
{
freerdp_client_rdp_file_free(wfc->connectionRdpFile);
wfc->connectionRdpFile = freerdp_client_rdp_file_new();
- fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile);
+ DEBUG_WARN( "Using connection file: %s\n", settings->ConnectionFile);
if (!freerdp_client_parse_rdp_file(wfc->connectionRdpFile, settings->ConnectionFile))
{
HGDI_DC hdc;
UINT16 srcBpp;
UINT16 dstBpp;
+ rdpCodecs* codecs;
freerdp* instance;
wfBitmap* primary;
wfBitmap* drawing;
wfBitmap* tile;
DWORD mainThreadId;
DWORD keyboardThreadId;
- RFX_CONTEXT* rfx_context;
- NSC_CONTEXT* nsc_context;
BOOL sw_gdi;
tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
if(NULL == tmp)
{
- fprintf(stderr, "Could not allocate string buffer.");
+ DEBUG_WARN( "Could not allocate string buffer.");
exit(-2);
}
/* Copy character for character and check, if it is necessary to escape. */
tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
if(NULL == tmp)
{
- fprintf(stderr, "Could not reallocate string buffer.");
+ DEBUG_WARN( "Could not reallocate string buffer.");
exit(-3);
}
tmp[cs++] = '&';
tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
if(NULL == tmp)
{
- fprintf(stderr, "Could not reallocate string buffer.");
+ DEBUG_WARN( "Could not reallocate string buffer.");
exit(-4);
}
tmp[cs++] = '&';
tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
if(NULL == tmp)
{
- fprintf(stderr, "Could not reallocate string buffer.");
+ DEBUG_WARN( "Could not reallocate string buffer.");
exit(-5);
}
tmp[cs++] = '&';
tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
if(NULL == tmp)
{
- fprintf(stderr, "Could not reallocate string buffer.");
+ DEBUG_WARN( "Could not reallocate string buffer.");
exit(-6);
}
tmp[cs++] = '&';
tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR));
if(NULL == tmp)
{
- fprintf(stderr, "Could not reallocate string buffer.");
+ DEBUG_WARN( "Could not reallocate string buffer.");
exit(-7);
}
tmp[cs++] = '&';
fp = fopen(fname, "w");
if(NULL == fp)
{
- fprintf(stderr, "Could not open '%s' for writing.", fname);
+ DEBUG_WARN( "Could not open '%s' for writing.", fname);
return -1;
}
/* The tag used as header in the manpage */
* compatible XML */
if(elements < 2)
{
- fprintf(stderr, "The argument array 'args' is empty, writing an empty file.");
+ DEBUG_WARN( "The argument array 'args' is empty, writing an empty file.");
elements = 1;
}
for(x=0; x<elements - 1; x++)
void xf_sw_begin_paint(rdpContext *context)
{
- rdpGdi *gdi = context->gdi;
+ rdpGdi* gdi = context->gdi;
gdi->primary->hdc->hwnd->invalid->null = 1;
gdi->primary->hdc->hwnd->ninvalid = 0;
}
void xf_sw_end_paint(rdpContext *context)
{
- rdpGdi *gdi;
+ int i;
INT32 x, y;
UINT32 w, h;
- xfContext *xfc = (xfContext *) context;
- gdi = context->gdi;
- if(!xfc->remote_app)
+ int ninvalid;
+ HGDI_RGN cinvalid;
+ xfContext* xfc = (xfContext*) context;
+ rdpGdi* gdi = context->gdi;
+
+ x = gdi->primary->hdc->hwnd->invalid->x;
+ y = gdi->primary->hdc->hwnd->invalid->y;
+ w = gdi->primary->hdc->hwnd->invalid->w;
+ h = gdi->primary->hdc->hwnd->invalid->h;
+
+ ninvalid = gdi->primary->hdc->hwnd->ninvalid;
+ cinvalid = gdi->primary->hdc->hwnd->cinvalid;
+
+ if (!xfc->remote_app)
{
- if(!xfc->complex_regions)
+ if (!xfc->complex_regions)
{
- if(gdi->primary->hdc->hwnd->invalid->null)
+ if (gdi->primary->hdc->hwnd->invalid->null)
return;
- x = gdi->primary->hdc->hwnd->invalid->x;
- y = gdi->primary->hdc->hwnd->invalid->y;
- w = gdi->primary->hdc->hwnd->invalid->w;
- h = gdi->primary->hdc->hwnd->invalid->h;
+
xf_lock_x11(xfc, FALSE);
+
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
- if((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
+
+ if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
{
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
}
{
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y);
}
+
xf_unlock_x11(xfc, FALSE);
}
else
{
- int i;
- int ninvalid;
- HGDI_RGN cinvalid;
- if(gdi->primary->hdc->hwnd->ninvalid < 1)
+ if (gdi->primary->hdc->hwnd->ninvalid < 1)
return;
- ninvalid = gdi->primary->hdc->hwnd->ninvalid;
- cinvalid = gdi->primary->hdc->hwnd->cinvalid;
+
xf_lock_x11(xfc, FALSE);
- for(i = 0; i < ninvalid; i++)
+
+ for (i = 0; i < ninvalid; i++)
{
x = cinvalid[i].x;
y = cinvalid[i].y;
w = cinvalid[i].w;
h = cinvalid[i].h;
+
//combine xfc->primary with xfc->image
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
- if((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
+
+ if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
{
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
}
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y);
}
}
+
XFlush(xfc->display);
+
xf_unlock_x11(xfc, FALSE);
}
}
else
{
- if(gdi->primary->hdc->hwnd->invalid->null)
+ if (gdi->primary->hdc->hwnd->invalid->null)
return;
- x = gdi->primary->hdc->hwnd->invalid->x;
- y = gdi->primary->hdc->hwnd->invalid->y;
- w = gdi->primary->hdc->hwnd->invalid->w;
- h = gdi->primary->hdc->hwnd->invalid->h;
+
xf_lock_x11(xfc, FALSE);
+
xf_rail_paint(xfc, context->rail, x, y, x + w - 1, y + h - 1);
+
xf_unlock_x11(xfc, FALSE);
}
}
rdpSettings *settings;
xfContext *xfc = (xfContext *) context;
settings = xfc->instance->settings;
+
xf_lock_x11(xfc, TRUE);
- if(!xfc->fullscreen)
+
+ if (!xfc->fullscreen)
{
rdpGdi *gdi = context->gdi;
gdi_resize(gdi, xfc->width, xfc->height);
- if(xfc->image)
+
+ if (xfc->image)
{
xfc->image->data = NULL;
XDestroyImage(xfc->image);
(char *) gdi->primary_buffer, gdi->width, gdi->height, xfc->scanline_pad, 0);
}
}
+
xf_unlock_x11(xfc, TRUE);
}
pfs = XListPixmapFormats(xfc->display, &pf_count);
if(pfs == NULL)
{
- fprintf(stderr, "xf_get_pixmap_info: XListPixmapFormats failed\n");
+ DEBUG_WARN( "xf_get_pixmap_info: XListPixmapFormats failed\n");
return 1;
}
for(i = 0; i < pf_count; i++)
template.screen = xfc->screen_number;
if(XGetWindowAttributes(xfc->display, RootWindowOfScreen(xfc->screen), &window_attributes) == 0)
{
- fprintf(stderr, "xf_get_pixmap_info: XGetWindowAttributes failed\n");
+ DEBUG_WARN( "xf_get_pixmap_info: XGetWindowAttributes failed\n");
return FALSE;
}
vis = XGetVisualInfo(xfc->display, VisualClassMask | VisualScreenMask, &template, &vi_count);
if(vis == NULL)
{
- fprintf(stderr, "xf_get_pixmap_info: XGetVisualInfo failed\n");
+ DEBUG_WARN( "xf_get_pixmap_info: XGetVisualInfo failed\n");
return FALSE;
}
vi = NULL;
char buf[256];
int do_abort = TRUE;
XGetErrorText(d, ev->error_code, buf, sizeof(buf));
- fprintf(stderr, "%s", buf);
+ DEBUG_WARN( "%s", buf);
if(do_abort)
abort();
_def_error_handler(d, ev);
* @return TRUE if successful. FALSE otherwise.
* Can exit with error code XF_EXIT_PARSE_ARGUMENTS if there is an error in the parameters.
*/
-BOOL xf_pre_connect(freerdp *instance)
+BOOL xf_pre_connect(freerdp* instance)
{
- rdpChannels *channels;
- rdpSettings *settings;
- xfContext *xfc = (xfContext *) instance->context;
+ rdpChannels* channels;
+ rdpSettings* settings;
+ xfContext* xfc = (xfContext*) instance->context;
+
+ xfc->codecs = instance->context->codecs;
xfc->settings = instance->settings;
xfc->instance = instance;
+
settings = instance->settings;
channels = instance->context->channels;
+
settings->OsMajorType = OSMAJORTYPE_UNIX;
settings->OsMinorType = OSMINORTYPE_NATIVE_XSERVER;
+
ZeroMemory(settings->OrderSupport, 32);
settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
{
if(!XInitThreads())
{
- fprintf(stderr, "warning: XInitThreads() failure\n");
+ DEBUG_WARN( "warning: XInitThreads() failure\n");
xfc->UseXThreads = FALSE;
}
}
xfc->display = XOpenDisplay(NULL);
if(!xfc->display)
{
- fprintf(stderr, "xf_pre_connect: failed to open display: %s\n", XDisplayName(NULL));
- fprintf(stderr, "Please check that the $DISPLAY environment variable is properly set.\n");
+ DEBUG_WARN( "xf_pre_connect: failed to open display: %s\n", XDisplayName(NULL));
+ DEBUG_WARN( "Please check that the $DISPLAY environment variable is properly set.\n");
return FALSE;
}
if(xfc->debug)
{
- fprintf(stderr, "Enabling X11 debug mode.\n");
+ DEBUG_WARN( "Enabling X11 debug mode.\n");
XSynchronize(xfc->display, TRUE);
_def_error_handler = XSetErrorHandler(_xf_error_handler);
}
/* Check --authonly has a username and password. */
if(settings->Username == NULL)
{
- fprintf(stderr, "--authonly, but no -u username. Please provide one.\n");
+ DEBUG_WARN( "--authonly, but no -u username. Please provide one.\n");
return FALSE;
}
if(settings->Password == NULL)
{
- fprintf(stderr, "--authonly, but no -p password. Please provide one.\n");
+ DEBUG_WARN( "--authonly, but no -p password. Please provide one.\n");
return FALSE;
}
- fprintf(stderr, "Authentication only. Don't connect to X.\n");
+ DEBUG_WARN( "Authentication only. Don't connect to X.\n");
/* Avoid XWindows initialization and configuration below. */
return TRUE;
}
xfc->fullscreen_toggle = settings->ToggleFullscreen;
xf_detect_monitors(xfc, settings);
xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number);
+
return TRUE;
}
xfc->srcBpp = settings->ColorDepth;
xf_gdi_register_update_callbacks(instance->update);
xfc->hdc = gdi_CreateDC(xfc->clrconv, xfc->bpp);
-
- if (settings->RemoteFxCodec)
- {
- xfc->rfx = rfx_context_new(FALSE);
- }
-
- if (settings->NSCodec)
- {
- xfc->nsc = nsc_context_new();
- }
}
xfc->originalWidth = settings->DesktopWidth;
XFillRectangle(xfc->display, xfc->primary, xfc->gc, 0, 0, xfc->width, xfc->height);
XFlush(xfc->display);
xfc->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
- (char *) xfc->primary_buffer, xfc->width, xfc->height, xfc->scanline_pad, 0);
+ (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)
{
instance->update->BeginPaint = xf_sw_begin_paint;
context->rail = NULL;
}
- if (xfc->rfx)
- {
- rfx_context_free(xfc->rfx);
- xfc->rfx = NULL;
- }
-
- if (xfc->nsc)
- {
- nsc_context_free(xfc->nsc);
- xfc->nsc = NULL;
- }
-
- if (xfc->clear)
- {
- clear_context_free(xfc->clear);
- xfc->clear = NULL;
- }
-
if (xfc->clrconv)
{
freerdp_clrconv_free(xfc->clrconv);
}
}
-void* xf_update_thread(void *arg)
-{
- int status;
- wMessage message;
- wMessageQueue *queue;
- freerdp *instance = (freerdp *) arg;
- assert(NULL != instance);
- status = 1;
- queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
- while(MessageQueue_Wait(queue))
- {
- while(MessageQueue_Peek(queue, &message, TRUE))
- {
- status = freerdp_message_queue_process_message(instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message);
- if(!status)
- break;
- }
- if(!status)
- break;
- }
- ExitThread(0);
- return NULL;
-}
-
void *xf_input_thread(void *arg)
{
xfContext *xfc;
if(freerdp_error_info(instance) != 0)
return FALSE;
/* A network disconnect was detected */
- fprintf(stderr, "Network disconnect!\n");
+ DEBUG_WARN( "Network disconnect!\n");
if(!instance->settings->AutoReconnectionEnabled)
{
/* No auto-reconnect - just quit */
return FALSE;
}
/* Attempt the next reconnect */
- fprintf(stderr, "Attempting reconnect (%u of %u)\n", num_retries, max_retries);
+ DEBUG_WARN( "Attempting reconnect (%u of %u)\n", num_retries, max_retries);
if(freerdp_reconnect(instance))
{
xfc->disconnect = FALSE;
}
sleep(5);
}
- fprintf(stderr, "Maximum reconnect retries exceeded\n");
+ DEBUG_WARN( "Maximum reconnect retries exceeded\n");
return FALSE;
}
int fd_input_event;
HANDLE input_event;
int select_status;
- BOOL async_update;
BOOL async_input;
BOOL async_channels;
BOOL async_transport;
- HANDLE update_thread;
HANDLE input_thread;
HANDLE channels_thread;
rdpChannels *channels;
if(instance->settings->AuthenticationOnly)
{
freerdp_disconnect(instance);
- fprintf(stderr, "Authentication only, exit status %d\n", !status);
+ DEBUG_WARN( "Authentication only, exit status %d\n", !status);
ExitThread(exit_code);
}
if(!status)
}
channels = instance->context->channels;
settings = instance->context->settings;
- async_update = settings->AsyncUpdate;
async_input = settings->AsyncInput;
async_channels = settings->AsyncChannels;
async_transport = settings->AsyncTransport;
- if(async_update)
- {
- update_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_update_thread, instance, 0, NULL);
- }
+
if(async_input)
{
input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_input_thread, instance, 0, NULL);
{
if(freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
- fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
+ DEBUG_WARN( "Failed to get FreeRDP file descriptor\n");
exit_code = XF_EXIT_CONN_FAILED;
break;
}
{
if(freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
- fprintf(stderr, "Failed to get channel manager file descriptor\n");
+ DEBUG_WARN( "Failed to get channel manager file descriptor\n");
exit_code = XF_EXIT_CONN_FAILED;
break;
}
{
if(xf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
- fprintf(stderr, "Failed to get xfreerdp file descriptor\n");
+ DEBUG_WARN( "Failed to get xfreerdp file descriptor\n");
exit_code = XF_EXIT_CONN_FAILED;
break;
}
if(!((errno == EAGAIN) || (errno == EWOULDBLOCK) ||
(errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */
{
- fprintf(stderr, "xfreerdp_run: select failed\n");
+ DEBUG_WARN( "xfreerdp_run: select failed\n");
break;
}
}
{
if(xf_auto_reconnect(instance))
continue;
- fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
+ DEBUG_WARN( "Failed to check FreeRDP file descriptor\n");
break;
}
}
{
if(freerdp_channels_check_fds(channels, instance) != TRUE)
{
- fprintf(stderr, "Failed to check channel manager file descriptor\n");
+ DEBUG_WARN( "Failed to check channel manager file descriptor\n");
break;
}
xf_process_channel_event(channels, instance);
{
if(xf_process_x_events(instance) != TRUE)
{
- fprintf(stderr, "Closed from X11\n");
+ DEBUG_WARN( "Closed from X11\n");
break;
}
}
{
if(!freerdp_message_queue_process_pending_messages(instance, FREERDP_INPUT_MESSAGE_QUEUE))
{
- fprintf(stderr, "User Disconnect\n");
+ DEBUG_WARN( "User Disconnect\n");
xfc->disconnect = TRUE;
break;
}
/* Close the channels first. This will signal the internal message pipes
* that the threads should quit. */
freerdp_channels_close(channels, instance);
- if(async_update)
- {
- wMessageQueue *update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
- MessageQueue_PostQuit(update_queue, 0);
- WaitForSingleObject(update_thread, INFINITE);
- CloseHandle(update_thread);
- }
+
if(async_input)
{
wMessageQueue *input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
rdpSettings *settings = context->settings;
if(!settings->ServerHostname)
{
- fprintf(stderr, "error: server hostname was not specified with /v:<server>[:port]\n");
+ DEBUG_WARN( "error: server hostname was not specified with /v:<server>[:port]\n");
return -1;
}
xfc->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_thread,
}
else
{
- fprintf(stderr, "%s: Error querying X Fixes extension version\n", __FUNCTION__);
+ DEBUG_WARN( "%s: Error querying X Fixes extension version\n", __FUNCTION__);
}
}
else
{
- fprintf(stderr, "%s: Error loading X Fixes extension\n", __FUNCTION__);
+ DEBUG_WARN( "%s: Error loading X Fixes extension\n", __FUNCTION__);
}
#else
- fprintf(stderr, "Warning: Using clipboard redirection without XFIXES extension is strongly discouraged!\n");
+ DEBUG_WARN( "Warning: Using clipboard redirection without XFIXES extension is strongly discouraged!\n");
#endif
n = 0;
Stream_Read_UINT16(s, bpp);
if ((bpp < 1) || (bpp > 32))
{
- fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, bpp);
+ DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, bpp);
return FALSE;
}
{
if ((rop2 < 0x01) || (rop2 > 0x10))
{
- fprintf(stderr, "Unsupported ROP2: %d\n", rop2);
+ DEBUG_WARN( "Unsupported ROP2: %d\n", rop2);
return FALSE;
}
if (function < 0)
{
- fprintf(stderr, "Unsupported ROP3: 0x%08X\n", rop3);
+ DEBUG_WARN( "Unsupported ROP3: 0x%08X\n", rop3);
XSetFunction(xfc->display, xfc->gc, GXclear);
return FALSE;
}
XFree(image);
if (cdata != data)
- free(cdata);
+ _aligned_free(cdata);
XFreeGC(xfc->display, gc);
}
}
else
{
- fprintf(stderr, "unimplemented brush style:%d\n", brush->style);
+ DEBUG_WARN( "unimplemented brush style:%d\n", brush->style);
}
if (xfc->drawing == xfc->primary)
void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid)
{
- fprintf(stderr, "DrawNineGrid\n");
+ DEBUG_WARN( "DrawNineGrid\n");
}
void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
}
else
{
- fprintf(stderr, "Mem3Blt unimplemented brush style:%d\n", brush->style);
+ DEBUG_WARN( "Mem3Blt unimplemented brush style:%d\n", brush->style);
}
XCopyArea(xfc->display, bitmap->pixmap, xfc->drawing, xfc->gc,
break;
default:
- fprintf(stderr, "PolygonSC unknown fillMode: %d\n", polygon_sc->fillMode);
+ DEBUG_WARN( "PolygonSC unknown fillMode: %d\n", polygon_sc->fillMode);
break;
}
break;
default:
- fprintf(stderr, "PolygonCB unknown fillMode: %d\n", polygon_cb->fillMode);
+ DEBUG_WARN( "PolygonCB unknown fillMode: %d\n", polygon_cb->fillMode);
break;
}
}
else
{
- fprintf(stderr, "PolygonCB unimplemented brush style:%d\n", brush->style);
+ DEBUG_WARN( "PolygonCB unimplemented brush style:%d\n", brush->style);
}
XSetFunction(xfc->display, xfc->gc, GXcopy);
void xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
{
- fprintf(stderr, "EllipseSC\n");
+ DEBUG_WARN( "EllipseSC\n");
}
void xf_gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
{
- fprintf(stderr, "EllipseCB\n");
+ DEBUG_WARN( "EllipseCB\n");
+}
+
+void xf_gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker)
+{
+
}
void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX)
{
- message = rfx_process_message(xfc->rfx,
+ message = rfx_process_message(xfc->codecs->rfx,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
XSetFunction(xfc->display, xfc->gc, GXcopy);
}
XSetClipMask(xfc->display, xfc->gc, None);
- rfx_message_free(xfc->rfx, message);
+ rfx_message_free(xfc->codecs->rfx, message);
}
else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC)
{
- nsc_process_message(xfc->nsc, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
+ 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);
XSetFunction(xfc->display, xfc->gc, GXcopy);
xfc->bmp_codec_nsc = (BYTE*) realloc(xfc->bmp_codec_nsc,
surface_bits_command->width * surface_bits_command->height * 4);
- freerdp_image_flip(xfc->nsc->BitmapData, xfc->bmp_codec_nsc,
+ freerdp_image_flip(xfc->codecs->nsc->BitmapData, xfc->bmp_codec_nsc,
surface_bits_command->width, surface_bits_command->height, 32);
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
}
else
{
- fprintf(stderr, "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", surface_bits_command->bitmapDataLength, surface_bits_command->width, surface_bits_command->height);
}
}
else
{
- fprintf(stderr, "Unsupported codecID %d\n", surface_bits_command->codecID);
+ DEBUG_WARN( "Unsupported codecID %d\n", surface_bits_command->codecID);
}
xf_unlock_x11(xfc, FALSE);
update->SurfaceBits = xf_gdi_surface_bits;
update->SurfaceFrameMarker = xf_gdi_surface_frame_marker;
+
+ update->altsec->FrameMarker = xf_gdi_frame_marker;
}
{
xfContext* xfc = (xfContext*) context->custom;
- if (xfc->rfx)
+ if (xfc->codecs->rfx)
{
- rfx_context_free(xfc->rfx);
- xfc->rfx = NULL;
+ rfx_context_free(xfc->codecs->rfx);
+ xfc->codecs->rfx = NULL;
}
- xfc->rfx = rfx_context_new(FALSE);
+ xfc->codecs->rfx = rfx_context_new(FALSE);
- xfc->rfx->width = resetGraphics->width;
- xfc->rfx->height = resetGraphics->height;
- rfx_context_set_pixel_format(xfc->rfx, RDP_PIXEL_FORMAT_B8G8R8A8);
+ 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->nsc)
+ if (xfc->codecs->nsc)
{
- nsc_context_free(xfc->nsc);
- xfc->nsc = NULL;
+ nsc_context_free(xfc->codecs->nsc);
+ xfc->codecs->nsc = NULL;
}
- xfc->nsc = nsc_context_new();
+ xfc->codecs->nsc = nsc_context_new();
- xfc->nsc->width = resetGraphics->width;
- xfc->nsc->height = resetGraphics->height;
- nsc_context_set_pixel_format(xfc->nsc, RDP_PIXEL_FORMAT_B8G8R8A8);
+ 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->clear)
+ if (xfc->codecs->clear)
{
- clear_context_free(xfc->clear);
- xfc->clear = NULL;
+ clear_context_free(xfc->codecs->clear);
+ xfc->codecs->clear = NULL;
}
- xfc->clear = clear_context_new(FALSE);
+ xfc->codecs->clear = clear_context_new(FALSE);
- if (xfc->h264)
+ if (xfc->codecs->h264)
{
- h264_context_free(xfc->h264);
- xfc->h264 = NULL;
+ h264_context_free(xfc->codecs->h264);
+ xfc->codecs->h264 = NULL;
}
- xfc->h264 = h264_context_new(FALSE);
+ 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);
region16_init(&(xfc->invalidRegion));
int xf_OutputExpose(xfContext* xfc, int x, int y, int width, int height)
{
+/** *********************************
+ * to be improved?
+ * *********************************/
RECTANGLE_16 invalidRect;
invalidRect.left = x;
REGION16 clippingRects;
RECTANGLE_16 clippingRect;
+ freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX);
+
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
return -1;
- message = rfx_process_message(xfc->rfx, cmd->data, cmd->length);
+ message = rfx_process_message(xfc->codecs->rfx, cmd->data, cmd->length);
if (!message)
return -1;
region16_uninit(&updateRegion);
}
- rfx_message_free(xfc->rfx, message);
+ rfx_message_free(xfc->codecs->rfx, message);
if (!xfc->inGfxFrame)
xf_OutputUpdate(xfc);
xfGfxSurface* surface;
RECTANGLE_16 invalidRect;
+ freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC);
+
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
DstData = surface->data;
- status = clear_decompress(xfc->clear, cmd->data, cmd->length, &DstData,
+ status = clear_decompress(xfc->codecs->clear, cmd->data, cmd->length, &DstData,
PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height);
if (status < 0)
region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect);
+
if (!xfc->inGfxFrame)
xf_OutputUpdate(xfc);
xfGfxSurface* surface;
RECTANGLE_16 invalidRect;
+ freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR);
+
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
DstData = surface->data;
- status = planar_decompress(NULL, cmd->data, cmd->length, &DstData,
+ status = planar_decompress(xfc->codecs->planar, cmd->data, cmd->length, &DstData,
PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height);
invalidRect.left = cmd->left;
int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
int status;
+ UINT32 i;
BYTE* DstData = NULL;
+ H264_CONTEXT* h264;
xfGfxSurface* surface;
- RECTANGLE_16 invalidRect;
+ RDPGFX_H264_METABLOCK* meta;
+ RDPGFX_H264_BITMAP_STREAM* bs;
- surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
+ freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_H264);
- if (!surface)
+ h264 = xfc->codecs->h264;
+
+ bs = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra;
+
+ if (!bs)
return -1;
- DstData = surface->data;
+ meta = &(bs->meta);
-#if 1
- status = h264_decompress(xfc->h264, cmd->data, cmd->length, &DstData,
- PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height);
-#else
- status = -1;
-#endif
+ surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
- printf("xf_SurfaceCommand_H264: status: %d\n", status);
+ if (!surface)
+ return -1;
-#if 0
- /* fill with red for now to distinguish from the rest */
+ DstData = surface->data;
- freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
- cmd->left, cmd->top, cmd->width, cmd->height, 0xFF0000);
-#endif
+ status = h264_decompress(xfc->codecs->h264, bs->data, bs->length, &DstData,
+ PIXEL_FORMAT_XRGB32, surface->scanline , surface->height, meta->regionRects, meta->numRegionRects);
- invalidRect.left = cmd->left;
- invalidRect.top = cmd->top;
- invalidRect.right = cmd->right;
- invalidRect.bottom = cmd->bottom;
+ if (status < 0)
+ {
+ printf("h264_decompress failure: %d\n",status);
+ return -1;
+ }
- region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect);
+ for (i = 0; i < meta->numRegionRects; i++)
+ {
+ region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), (RECTANGLE_16*) &(meta->regionRects[i]));
+ }
if (!xfc->inGfxFrame)
xf_OutputUpdate(xfc);
xfGfxSurface* surface;
RECTANGLE_16 invalidRect;
+ freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_ALPHACODEC);
+
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
- int status = 0;
+ int i, j;
+ int status;
+ BYTE* DstData;
+ RFX_RECT* rect;
+ int nXDst, nYDst;
+ int nXSrc, nYSrc;
+ int nWidth, nHeight;
+ int nbUpdateRects;
xfGfxSurface* surface;
- RECTANGLE_16 invalidRect;
+ 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(xfc->codecs, FREERDP_CODEC_PROGRESSIVE);
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
return -1;
- printf("xf_SurfaceCommand_Progressive: status: %d\n", status);
+ progressive_create_surface_context(xfc->codecs->progressive, cmd->surfaceId, surface->width, surface->height);
- /* fill with blue for now to distinguish from the rest */
+ DstData = surface->data;
- freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
- cmd->left, cmd->top, cmd->width, cmd->height, 0x0000FF);
+ status = progressive_decompress(xfc->codecs->progressive, cmd->data, cmd->length, &DstData,
+ PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId);
- invalidRect.left = cmd->left;
- invalidRect.top = cmd->top;
- invalidRect.right = cmd->right;
- invalidRect.bottom = cmd->bottom;
+ if (status < 0)
+ {
+ printf("progressive_decompress failure: %d\n", status);
+ return -1;
+ }
- region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect);
+ region = &(xfc->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(&(xfc->invalidRegion), &(xfc->invalidRegion), &updateRects[j]);
+ }
+
+ region16_uninit(&updateRegion);
+ }
if (!xfc->inGfxFrame)
xf_OutputUpdate(xfc);
int xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface)
{
xfGfxSurface* surface = NULL;
+ xfContext* xfc = (xfContext*) context->custom;
surface = (xfGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId);
context->SetSurfaceData(context, deleteSurface->surfaceId, NULL);
+ progressive_delete_surface_context(xfc->codecs->progressive, deleteSurface->surfaceId);
+
return 1;
}
rectSrc = &(surfaceToSurface->rectSrc);
destPt = &surfaceToSurface->destPts[0];
+ /**not needed?*/
surfaceSrc = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdSrc);
invalidRect.top = destPt->y;
invalidRect.right = destPt->x + rectSrc->right;
invalidRect.bottom = destPt->y + rectSrc->bottom;
+
+ /**width,height?*/
region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect);
}
cacheEntry->alpha = surface->alpha;
cacheEntry->scanline = (cacheEntry->width + (cacheEntry->width % 4)) * 4;
- cacheEntry->data = (BYTE*) calloc(1, surface->scanline * surface->height);
+ cacheEntry->data = (BYTE*) calloc(1, cacheEntry->scanline * cacheEntry->height);
if (!cacheEntry->data)
return -1;
void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
BYTE* data, int width, int height, int bpp, int length,
- BOOL compressed, int codec_id)
+ BOOL compressed, int codecId)
{
+ int status;
UINT16 size;
BYTE* src;
BYTE* dst;
int yindex;
int xindex;
- BOOL status;
RFX_MESSAGE* msg;
xfContext* xfc = (xfContext*) context;
else
bitmap->data = (BYTE*) _aligned_realloc(bitmap->data, size, 16);
- switch (codec_id)
+ switch (codecId)
{
case RDP_CODEC_ID_NSCODEC:
- fprintf(stderr, "xf_Bitmap_Decompress: nsc not done\n");
+ freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC);
+ DEBUG_WARN("xf_Bitmap_Decompress: nsc not done\n");
break;
case RDP_CODEC_ID_REMOTEFX:
- rfx_context_set_pixel_format(xfc->rfx, RDP_PIXEL_FORMAT_B8G8R8A8);
- msg = rfx_process_message(xfc->rfx, data, length);
+ 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);
if (!msg)
{
- fprintf(stderr, "xf_Bitmap_Decompress: rfx Decompression Failed\n");
+ DEBUG_WARN("xf_Bitmap_Decompress: rfx Decompression Failed\n");
}
else
{
src++;
}
}
- rfx_message_free(xfc->rfx, msg);
+ rfx_message_free(xfc->codecs->rfx, msg);
}
break;
case RDP_CODEC_ID_JPEG:
if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
{
- fprintf(stderr, "xf_Bitmap_Decompress: jpeg Decompression Failed\n");
+ DEBUG_WARN( "xf_Bitmap_Decompress: jpeg Decompression Failed\n");
}
break;
default:
if (compressed)
{
- status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
+ BYTE* pDstData;
+ UINT32 SrcSize;
- if (!status)
+ SrcSize = (UINT32) length;
+ pDstData = bitmap->data;
+
+ if (bpp < 32)
{
- fprintf(stderr, "xf_Bitmap_Decompress: Bitmap Decompression Failed\n");
+ 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
void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor)
{
- xfContext* context_ = (xfContext*) context;
xfContext* xfc = (xfContext*) context;
bgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color(bgcolor, context->settings->ColorDepth, xfc->clrconv);
}
else if (evtype == XI_TouchUpdate)
{
- printf("TouchUpdate: %d\n", touchId);
+ DEBUG_MSG("TouchUpdate: %d\n", touchId);
contactId = rdpei->TouchUpdate(rdpei, touchId, x, y);
}
else if (evtype == XI_TouchEnd)
if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
{
- fprintf(stderr, "Unknown key with X keycode 0x%02x\n", keycode);
+ DEBUG_WARN( "Unknown key with X keycode 0x%02x\n", keycode);
}
else if (rdp_scancode == RDP_SCANCODE_PAUSE &&
!xf_keyboard_key_pressed(xfc, XK_Control_L) && !xf_keyboard_key_pressed(xfc, XK_Control_R))
{
- /* Pause without Ctrl has to be sent as Ctrl + NumLock. */
+ /* Pause without Ctrl has to be sent as a series of keycodes
+ * in a single input PDU. Pause only happens on "press";
+ * no code is sent on "release".
+ */
if (down)
{
- freerdp_input_send_keyboard_event_ex(input, TRUE, RDP_SCANCODE_LCONTROL);
- freerdp_input_send_keyboard_event_ex(input, TRUE, RDP_SCANCODE_NUMLOCK);
- freerdp_input_send_keyboard_event_ex(input, FALSE, RDP_SCANCODE_LCONTROL);
- freerdp_input_send_keyboard_event_ex(input, FALSE, RDP_SCANCODE_NUMLOCK);
+ freerdp_input_send_keyboard_pause_event(input);
}
}
else
return TRUE;
}
- if (keysym == XK_Return)
+ if(xfc->fullscreen_toggle)
{
- if (mod.Ctrl && mod.Alt)
- {
- /* Ctrl-Alt-Enter: toggle full screen */
- xf_toggle_fullscreen(xfc);
- return TRUE;
- }
+ if (keysym == XK_Return)
+ {
+ if (mod.Ctrl && mod.Alt)
+ {
+ /* Ctrl-Alt-Enter: toggle full screen */
+ xf_toggle_fullscreen(xfc);
+ return TRUE;
+ }
+ }
}
if ((keysym == XK_c) || (keysym == XK_C))
#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>
#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
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))
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)
}
}
-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);
}
{
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;
}
{
xfContext* xfc;
xfWindow* xfw;
-
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
* 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);
}
{
xfContext* xfc;
xfWindow* xfw;
-
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
-
xf_SetWindowText(xfc, xfw, window->title);
}
{
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);
}
{
xfContext* xfc;
xfWindow* xfw;
-
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
-
xf_SetWindowRects(xfc, xfw, window->windowRects, window->numWindowRects);
}
{
xfWindow* xfw;
xfContext* xfc;
-
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
-
xf_SetWindowVisibilityRects(xfc, xfw, window->windowRects, window->numWindowRects);
}
{
xfWindow* xfw;
xfContext* xfc;
-
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
-
xf_DestroyWindow(xfc, xfw);
}
{
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);
}
}
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)
activate.windowId = rail_window->windowId;
activate.enabled = enabled;
-
xf_send_rail_client_event(channels, RailChannel_ClientActivate, &activate);
}
{
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);
}
xfWindow* xfw;
rdpChannels* channels;
RAIL_WINDOW_MOVE_ORDER window_move;
-
xfw = (xfWindow*) window->extra;
channels = ((rdpContext*) xfc)->channels;
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 (window->windowOffsetX < 0)
- offsetX = offsetX - window->windowOffsetX;
-
- if (window->windowOffsetY < 0)
- offsetY = offsetY - window->windowOffsetY;
+ 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->windowOffsetY < 0)
+ offsetY = offsetY - window->windowOffsetY;
/*
* windowOffset corresponds to the window location on the rail server
* 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;
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)
{
- fprintf(stderr, "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
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);
}
}
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);
{
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)
{
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;
if (movesize->isMoveSizeStart)
{
xf_StartLocalMoveSize(xfc, xfw, direction, x, y);
- } else {
+ }
+ else
+ {
xf_EndLocalMoveSize(xfc, xfw);
}
}
{
RAIL_GET_APPID_RESP_ORDER* appid_resp =
(RAIL_GET_APPID_RESP_ORDER*) event->wParam;
-
- fprintf(stderr, "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;
-
- fprintf(stderr, "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)
XFree(attr);
#ifdef WITH_DEBUG_XV
- fprintf(stderr, "xf_tsmf_init: pixel format ");
+ DEBUG_WARN( "xf_tsmf_init: pixel format ");
#endif
fo = XvListImageFormats(xfc->display, xv->xv_port, &ret);
if (ret > 0)
{
xv->xv_pixfmts[i] = fo[i].id;
#ifdef WITH_DEBUG_XV
- fprintf(stderr, "%c%c%c%c ", ((char*)(xv->xv_pixfmts + i))[0], ((char*)(xv->xv_pixfmts + i))[1],
+ DEBUG_WARN( "%c%c%c%c ", ((char*)(xv->xv_pixfmts + i))[0], ((char*)(xv->xv_pixfmts + i))[1],
((char*)(xv->xv_pixfmts + i))[2], ((char*)(xv->xv_pixfmts + i))[3]);
#endif
}
}
XFree(fo);
#ifdef WITH_DEBUG_XV
- fprintf(stderr, "\n");
+ DEBUG_WARN( "\n");
#endif
}
unsigned int i;
va_list argp;
va_start(argp, numArgs);
+
+ ZeroMemory(&xevent, sizeof(XEvent));
xevent.xclient.type = ClientMessage;
xevent.xclient.serial = 0;
xevent.xclient.send_event = False;
#include <freerdp/codec/color.h>
#include <freerdp/codec/bitmap.h>
#include <freerdp/codec/h264.h>
+#include <freerdp/codec/progressive.h>
#include <freerdp/codec/region.h>
struct xf_WorkArea
freerdp* instance;
rdpSettings* settings;
+ rdpCodecs* codecs;
GC gc;
int bpp;
VIRTUAL_SCREEN vscreen;
BYTE* bmp_codec_none;
BYTE* bmp_codec_nsc;
- RFX_CONTEXT* rfx;
- NSC_CONTEXT* nsc;
- CLEAR_CONTEXT* clear;
- H264_CONTEXT* h264;
void* xv_context;
void* clipboard_context;
#include <freerdp/crypto/crypto.h>
#include <freerdp/locale/keyboard.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/client/cmdline.h>
#include <freerdp/version.h>
{ "port", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL, "Server port" },
{ "w", COMMAND_LINE_VALUE_REQUIRED, "<width>", "1024", NULL, -1, NULL, "Width" },
{ "h", COMMAND_LINE_VALUE_REQUIRED, "<height>", "768", NULL, -1, NULL, "Height" },
- { "size", COMMAND_LINE_VALUE_REQUIRED, "<width>x<height>", "1024x768", NULL, -1, NULL, "Screen size" },
+ { "size", COMMAND_LINE_VALUE_REQUIRED, "<width>x<height> or <percent>%", "1024x768", NULL, -1, NULL, "Screen size" },
{ "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Fullscreen mode" },
{ "bpp", COMMAND_LINE_VALUE_REQUIRED, "<depth>", "16", NULL, -1, NULL, "Session bpp (color depth)" },
{ "kbd", COMMAND_LINE_VALUE_REQUIRED, "0x<layout id> or <layout name>", NULL, NULL, -1, NULL, "Keyboard layout" },
}
else
{
- p = strchr(username, '@');
-
- if (p)
- {
- length = (int) (p - username);
- *user = (char*) malloc(length + 1);
- strncpy(*user, username, length);
- (*user)[length] = '\0';
- *domain = _strdup(&p[1]);
- }
- else
- {
- *user = _strdup(username);
- *domain = NULL;
- }
+ /* Do not break up the name for '@'; both credSSP and the
+ * ClientInfo PDU expect 'user@corp.net' to be transmitted
+ * as username 'user@corp.net', domain empty.
+ */
+ *user = _strdup(username);
+ *domain = NULL;
}
return 0;
if (compatibility)
{
- fprintf(stderr, "WARNING: Using deprecated command-line interface!\n");
+ DEBUG_WARN( "WARNING: Using deprecated command-line interface!\n");
return freerdp_client_parse_old_command_line_arguments(argc, argv, settings);
}
else
settings->DesktopWidth = atoi(str);
settings->DesktopHeight = atoi(&p[1]);
}
+ else
+ {
+ p = strchr(str, '%');
+ if(p)
+ {
+ settings->PercentScreen = atoi(str);
+ }
+ }
free(str);
}
}
CommandLineSwitchCase(arg, "kbd")
{
- int id;
+ unsigned long int id;
char* pEnd;
- id = strtol(arg->Value, &pEnd, 16);
+ id = strtoul(arg->Value, &pEnd, 16);
if (pEnd != (arg->Value + strlen(arg->Value)))
id = 0;
if (id == 0)
{
- id = freerdp_map_keyboard_layout_name_to_id(arg->Value);
+ id = (unsigned long int) freerdp_map_keyboard_layout_name_to_id(arg->Value);
if (!id)
{
- fprintf(stderr, "Could not identify keyboard layout: %s\n", arg->Value);
+ DEBUG_WARN( "Could not identify keyboard layout: %s\n", arg->Value);
}
}
- settings->KeyboardLayout = id;
+ settings->KeyboardLayout = (UINT32) id;
}
CommandLineSwitchCase(arg, "kbd-type")
{
CommandLineSwitchCase(arg, "gfx-progressive")
{
settings->GfxProgressive = arg->Value ? TRUE : FALSE;
+ settings->GfxThinClient = settings->GfxProgressive ? FALSE : TRUE;
settings->SupportGraphicsPipeline = TRUE;
}
CommandLineSwitchCase(arg, "gfx-h264")
}
else
{
- fprintf(stderr, "unknown protocol security: %s\n", arg->Value);
+ DEBUG_WARN( "unknown protocol security: %s\n", arg->Value);
}
}
CommandLineSwitchCase(arg, "sec-rdp")
}
else
{
- fprintf(stderr, "reconnect-cookie: invalid base64 '%s'\n",
+ DEBUG_WARN( "reconnect-cookie: invalid base64 '%s'\n",
arg->Value);
}
}
{
if (freerdp_channels_client_load(channels, settings, entry, data) == 0)
{
- fprintf(stderr, "loading channel %s\n", name);
+ DEBUG_WARN( "loading channel %s\n", name);
return 0;
}
}
}
if (settings->DynamicChannelCount)
+ settings->SupportDynamicChannels = TRUE;
+
+ if (settings->SupportDynamicChannels)
{
freerdp_client_load_static_channel_addin(channels, settings, "drdynvc", settings);
}
#include <freerdp/addin.h>
#include <freerdp/settings.h>
#include <freerdp/client/channels.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/locale/keyboard.h>
#include <freerdp/client/cmdline.h>
if (strcmp(args->argv[0], "cliprdr") == 0)
{
settings->RedirectClipboard = TRUE;
- fprintf(stderr, "--plugin cliprdr -> +clipboard\n");
+ DEBUG_WARN( "--plugin cliprdr -> +clipboard\n");
}
else if (strcmp(args->argv[0], "rdpdr") == 0)
{
CommandLineSwitchCase(arg, "0")
{
settings->ConsoleSession = TRUE;
- fprintf(stderr, "-0 -> /admin\n");
+ DEBUG_WARN( "-0 -> /admin\n");
}
CommandLineSwitchCase(arg, "a")
{
settings->ColorDepth = atoi(arg->Value);
- fprintf(stderr, "-a %s -> /bpp:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "-a %s -> /bpp:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "c")
{
settings->ShellWorkingDirectory = _strdup(arg->Value);
- fprintf(stderr, "-c %s -> /shell-dir:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "-c %s -> /shell-dir:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "D")
{
settings->Decorations = FALSE;
- fprintf(stderr, "-D -> -decorations\n");
+ DEBUG_WARN( "-D -> -decorations\n");
}
CommandLineSwitchCase(arg, "T")
{
settings->WindowTitle = _strdup(arg->Value);
- fprintf(stderr, "-T %s -> /title:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "-T %s -> /title:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "d")
{
settings->Domain = _strdup(arg->Value);
- fprintf(stderr, "-d %s -> /d:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "-d %s -> /d:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "f")
{
settings->Fullscreen = TRUE;
- fprintf(stderr, "-f -> /f\n");
+ DEBUG_WARN( "-f -> /f\n");
}
CommandLineSwitchCase(arg, "g")
{
free(str);
- fprintf(stderr, "-g %s -> /size:%s or /w:%d /h:%d\n", arg->Value, arg->Value,
+ DEBUG_WARN( "-g %s -> /size:%s or /w:%d /h:%d\n", arg->Value, arg->Value,
settings->DesktopWidth, settings->DesktopHeight);
}
CommandLineSwitchCase(arg, "k")
{
sscanf(arg->Value, "%X", &(settings->KeyboardLayout));
- fprintf(stderr, "-k %s -> /kbd:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "-k %s -> /kbd:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "K")
{
settings->GrabKeyboard = FALSE;
- fprintf(stderr, "-K -> -grab-keyboard\n");
+ DEBUG_WARN( "-K -> -grab-keyboard\n");
}
CommandLineSwitchCase(arg, "n")
{
settings->ClientHostname = _strdup(arg->Value);
- fprintf(stderr, "-n -> /client-hostname:%s\n", arg->Value);
+ DEBUG_WARN( "-n -> /client-hostname:%s\n", arg->Value);
}
CommandLineSwitchCase(arg, "o")
{
settings->RemoteConsoleAudio = TRUE;
- fprintf(stderr, "-o -> /audio-mode:1\n");
+ DEBUG_WARN( "-o -> /audio-mode:1\n");
}
CommandLineSwitchCase(arg, "p")
{
settings->Password = _strdup(arg->Value);
- fprintf(stderr, "-p ****** -> /p:******\n");
+ DEBUG_WARN( "-p ****** -> /p:******\n");
/* Hide the value from 'ps'. */
FillMemory(arg->Value, strlen(arg->Value), '*');
}
CommandLineSwitchCase(arg, "s")
{
settings->AlternateShell = _strdup(arg->Value);
- fprintf(stderr, "-s %s -> /shell:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "-s %s -> /shell:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "t")
{
settings->ServerPort = atoi(arg->Value);
- fprintf(stderr, "-t %s -> /port:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "-t %s -> /port:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "u")
{
settings->Username = _strdup(arg->Value);
- fprintf(stderr, "-u %s -> /u:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "-u %s -> /u:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "x")
{
freerdp_performance_flags_split(settings);
}
- fprintf(stderr, "-x %s -> /network:", arg->Value);
+ DEBUG_WARN( "-x %s -> /network:", arg->Value);
if (type == CONNECTION_TYPE_MODEM)
- fprintf(stderr, "modem");
+ DEBUG_WARN( "modem");
else if (CONNECTION_TYPE_BROADBAND_HIGH)
- fprintf(stderr, "broadband");
+ DEBUG_WARN( "broadband");
else if (CONNECTION_TYPE_LAN)
- fprintf(stderr, "lan");
+ DEBUG_WARN( "lan");
- fprintf(stderr, "\n");
+ DEBUG_WARN( "\n");
}
CommandLineSwitchCase(arg, "X")
{
settings->ParentWindowId = strtol(arg->Value, NULL, 0);
- fprintf(stderr, "-X %s -> /parent-window:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "-X %s -> /parent-window:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "z")
{
settings->CompressionEnabled = TRUE;
- fprintf(stderr, "-z -> /compression\n");
+ DEBUG_WARN( "-z -> /compression\n");
}
CommandLineSwitchCase(arg, "app")
{
settings->RemoteApplicationMode = TRUE;
- fprintf(stderr, "--app -> /app: + program name or alias\n");
+ DEBUG_WARN( "--app -> /app: + program name or alias\n");
}
CommandLineSwitchCase(arg, "ext")
{
CommandLineSwitchCase(arg, "no-auth")
{
settings->Authentication = FALSE;
- fprintf(stderr, "--no-auth -> -authentication\n");
+ DEBUG_WARN( "--no-auth -> -authentication\n");
}
CommandLineSwitchCase(arg, "authonly")
{
{
settings->FastPathInput = FALSE;
settings->FastPathOutput = FALSE;
- fprintf(stderr, "--no-fastpath -> -fast-path\n");
+ DEBUG_WARN( "--no-fastpath -> -fast-path\n");
}
CommandLineSwitchCase(arg, "no-motion")
{
settings->MouseMotion = FALSE;
- fprintf(stderr, "--no-motion -> -mouse-motion\n");
+ DEBUG_WARN( "--no-motion -> -mouse-motion\n");
}
CommandLineSwitchCase(arg, "gdi")
{
else if (strcmp(arg->Value, "hw") == 0)
settings->SoftwareGdi = FALSE;
- fprintf(stderr, "--gdi %s -> /gdi:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "--gdi %s -> /gdi:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "no-osb")
{
settings->OffscreenSupportLevel = FALSE;
- fprintf(stderr, "--no-osb -> -offscreen-cache\n");
+ DEBUG_WARN( "--no-osb -> -offscreen-cache\n");
}
CommandLineSwitchCase(arg, "no-bmp-cache")
{
settings->BitmapCacheEnabled = FALSE;
- fprintf(stderr, "--no-bmp-cache -> -bitmap-cache\n");
+ DEBUG_WARN( "--no-bmp-cache -> -bitmap-cache\n");
}
CommandLineSwitchCase(arg, "plugin")
{
- fprintf(stderr, "--plugin -> /a, /vc, /dvc and channel-specific options\n");
+ DEBUG_WARN( "--plugin -> /a, /vc, /dvc and channel-specific options\n");
}
CommandLineSwitchCase(arg, "rfx")
{
settings->RemoteFxCodec = TRUE;
- fprintf(stderr, "--rfx -> /rfx\n");
+ DEBUG_WARN( "--rfx -> /rfx\n");
}
CommandLineSwitchCase(arg, "rfx-mode")
{
else if (arg->Value[0] == 'i')
settings->RemoteFxCodecMode = 0x02;
- fprintf(stderr, "--rfx-mode -> /rfx-mode:%s\n", settings->RemoteFxCodecMode ? "image" : "video");
+ DEBUG_WARN( "--rfx-mode -> /rfx-mode:%s\n", settings->RemoteFxCodecMode ? "image" : "video");
}
CommandLineSwitchCase(arg, "nsc")
{
settings->NSCodec = TRUE;
- fprintf(stderr, "--nsc -> /nsc\n");
+ DEBUG_WARN( "--nsc -> /nsc\n");
}
CommandLineSwitchCase(arg, "disable-wallpaper")
{
settings->DisableWallpaper = TRUE;
- fprintf(stderr, "--disable-wallpaper -> -wallpaper\n");
+ DEBUG_WARN( "--disable-wallpaper -> -wallpaper\n");
}
CommandLineSwitchCase(arg, "composition")
{
settings->AllowDesktopComposition = TRUE;
- fprintf(stderr, "--composition -> +composition\n");
+ DEBUG_WARN( "--composition -> +composition\n");
}
CommandLineSwitchCase(arg, "disable-full-window-drag")
{
settings->DisableFullWindowDrag = TRUE;
- fprintf(stderr, "--disable-full-window-drag -> -window-drag\n");
+ DEBUG_WARN( "--disable-full-window-drag -> -window-drag\n");
}
CommandLineSwitchCase(arg, "disable-menu-animations")
{
settings->DisableMenuAnims = TRUE;
- fprintf(stderr, "--disable-menu-animations -> -menu-anims\n");
+ DEBUG_WARN( "--disable-menu-animations -> -menu-anims\n");
}
CommandLineSwitchCase(arg, "disable-theming")
{
settings->DisableThemes = TRUE;
- fprintf(stderr, "--disable-theming -> -themes\n");
+ DEBUG_WARN( "--disable-theming -> -themes\n");
}
CommandLineSwitchCase(arg, "ntlm")
{
CommandLineSwitchCase(arg, "ignore-certificate")
{
settings->IgnoreCertificate = TRUE;
- fprintf(stderr, "--ignore-certificate -> /cert-ignore\n");
+ DEBUG_WARN( "--ignore-certificate -> /cert-ignore\n");
}
CommandLineSwitchCase(arg, "sec")
{
settings->NlaSecurity = TRUE;
}
- fprintf(stderr, "--sec %s -> /sec:%s\n", arg->Value, arg->Value);
+ DEBUG_WARN( "--sec %s -> /sec:%s\n", arg->Value, arg->Value);
}
CommandLineSwitchCase(arg, "no-rdp")
{
settings->RdpSecurity = FALSE;
- fprintf(stderr, "--no-rdp -> -sec-rdp\n");
+ DEBUG_WARN( "--no-rdp -> -sec-rdp\n");
}
CommandLineSwitchCase(arg, "no-tls")
{
settings->TlsSecurity = FALSE;
- fprintf(stderr, "--no-tls -> -sec-tls\n");
+ DEBUG_WARN( "--no-tls -> -sec-tls\n");
}
CommandLineSwitchCase(arg, "no-nla")
{
settings->NlaSecurity = FALSE;
- fprintf(stderr, "--no-nla -> -sec-nla\n");
+ DEBUG_WARN( "--no-nla -> -sec-nla\n");
}
CommandLineSwitchCase(arg, "secure-checksum")
{
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
- fprintf(stderr, "%s -> /v:%s", settings->ServerHostname, settings->ServerHostname);
+ DEBUG_WARN( "%s -> /v:%s", settings->ServerHostname, settings->ServerHostname);
if (settings->ServerPort != 3389)
- fprintf(stderr, " /port:%d", settings->ServerPort);
+ DEBUG_WARN( " /port:%d", settings->ServerPort);
- fprintf(stderr, "\n");
+ DEBUG_WARN( "\n");
return 1;
}
#include "config.h"
#endif
+#include <freerdp/utils/debug.h>
#include <freerdp/client/file.h>
#include <freerdp/client/cmdline.h>
BOOL bStandard = TRUE;
#ifdef DEBUG_CLIENT_FILE
- fprintf(stderr, "%s:i:%d\n", name, value);
+ DEBUG_WARN( "%s:i:%d\n", name, value);
#endif
if (_stricmp(name, "use multimon") == 0)
BOOL bStandard = TRUE;
#ifdef DEBUG_CLIENT_FILE
- fprintf(stderr, "%s:s:%s\n", name, value);
+ DEBUG_WARN( "%s:s:%s\n", name, value);
#endif
if (_stricmp(name, "username") == 0)
if (length < 0)
{
- fprintf(stderr, "freerdp_client_write_rdp_file: error determining buffer size.\n");
+ DEBUG_WARN( "freerdp_client_write_rdp_file: error determining buffer size.\n");
return FALSE;
}
if (freerdp_client_write_rdp_file_buffer(file, buffer, length + 1) != length)
{
- fprintf(stderr, "freerdp_client_write_rdp_file: error writing to output buffer\n");
+ DEBUG_WARN( "freerdp_client_write_rdp_file: error writing to output buffer\n");
free(buffer);
return FALSE;
}
freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, TRUE);
}
+ if (~file->KeyboardHook)
+ {
+ freerdp_set_param_uint32(settings, FreeRDP_KeyboardHook, file->KeyboardHook);
+ }
+
if (file->argc > 1)
{
char* ConnectionFile = settings->ConnectionFile;
-if((CMAKE_SYSTEM_PROCESSOR MATCHES "i386|i686|x86") AND (CMAKE_SIZEOF_VOID_P EQUAL 4))
+if((CMAKE_SYSTEM_PROCESSOR MATCHES "i386|i686|x86|AMD64") AND (CMAKE_SIZEOF_VOID_P EQUAL 4))
set(TARGET_ARCH "x86")
elseif((CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") AND (CMAKE_SIZEOF_VOID_P EQUAL 8))
set(TARGET_ARCH "x64")
#cmakedefine HAVE_POLL_H
#cmakedefine HAVE_PTHREAD_GNU_EXT
#cmakedefine HAVE_VALGRIND_MEMCHECK_H
-
+#cmakedefine HAVE_EXECINFO_H
/* Options */
#cmakedefine WITH_PROFILER
#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;
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;
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;
FREERDP_API BYTE* freerdp_assistance_hex_string_to_bin(const char* str, int* size);
FREERDP_API char* freerdp_assistance_bin_to_hex_string(const BYTE* data, int size);
+FREERDP_API int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file);
+FREERDP_API int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file);
+
+FREERDP_API char* freerdp_assistance_generate_pass_stub(DWORD flags);
FREERDP_API char* freerdp_assistance_construct_expert_blob(const char* name, const char* pass);
FREERDP_API BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub, int* pEncryptedSize);
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Channel log defines
+ *
+ * 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.
+ * 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_CHANNELS_LOG_H
+#define FREERDP_CHANNELS_LOG_H
+
+#include <winpr/wlog.h>
+#include <freerdp/log.h>
+
+#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, ...) 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 */
UINT32 height;
UINT32 length;
BYTE* data;
+ void* extra;
};
typedef struct _RDPGFX_SURFACE_COMMAND RDPGFX_SURFACE_COMMAND;
};
typedef struct _RDPGFX_MAP_SURFACE_TO_WINDOW_PDU RDPGFX_MAP_SURFACE_TO_WINDOW_PDU;
+/* H264 */
+
+struct _RDPGFX_H264_QUANT_QUALITY
+{
+ BYTE qpVal;
+ BYTE qualityVal;
+
+ BYTE qp;
+ BYTE r;
+ BYTE p;
+};
+typedef struct _RDPGFX_H264_QUANT_QUALITY RDPGFX_H264_QUANT_QUALITY;
+
+struct _RDPGFX_H264_METABLOCK
+{
+ UINT32 numRegionRects;
+ RDPGFX_RECT16* regionRects;
+ RDPGFX_H264_QUANT_QUALITY* quantQualityVals;
+};
+typedef struct _RDPGFX_H264_METABLOCK RDPGFX_H264_METABLOCK;
+
+struct _RDPGFX_H264_BITMAP_STREAM
+{
+ RDPGFX_H264_METABLOCK meta;
+ UINT32 length;
+ BYTE* data;
+};
+typedef struct _RDPGFX_H264_BITMAP_STREAM RDPGFX_H264_BITMAP_STREAM;
+
#endif /* FREERDP_CHANNEL_RDPGFX_H */
#define REMDESK_SVC_CHANNEL_NAME "remdesk"
+#define REMDESK_ERROR_NOERROR 0
+#define REMDESK_ERROR_NOINFO 1
+#define REMDESK_ERROR_LOCALNOTERROR 3
+#define REMDESK_ERROR_REMOTEBYUSER 4
+#define REMDESK_ERROR_BYSERVER 5
+#define REMDESK_ERROR_DNSLOOKUPFAILED 6
+#define REMDESK_ERROR_OUTOFMEMORY 7
+#define REMDESK_ERROR_CONNECTIONTIMEDOUT 8
+#define REMDESK_ERROR_SOCKETCONNECTFAILED 9
+#define REMDESK_ERROR_HOSTNOTFOUND 11
+#define REMDESK_ERROR_WINSOCKSENDFAILED 12
+#define REMDESK_ERROR_INVALIDIPADDR 14
+#define REMDESK_ERROR_SOCKETRECVFAILED 15
+#define REMDESK_ERROR_INVALIDENCRYPTION 18
+#define REMDESK_ERROR_GETHOSTBYNAMEFAILED 20
+#define REMDESK_ERROR_LICENSINGFAILED 21
+#define REMDESK_ERROR_ENCRYPTIONERROR 22
+#define REMDESK_ERROR_DECRYPTIONERROR 23
+#define REMDESK_ERROR_INVALIDPARAMETERSTRING 24
+#define REMDESK_ERROR_HELPSESSIONNOTFOUND 25
+#define REMDESK_ERROR_INVALIDPASSWORD 26
+#define REMDESK_ERROR_HELPSESSIONEXPIRED 27
+#define REMDESK_ERROR_CANTOPENRESOLVER 28
+#define REMDESK_ERROR_UNKNOWNSESSMGRERROR 29
+#define REMDESK_ERROR_CANTFORMLINKTOUSERSESSION 30
+#define REMDESK_ERROR_RCPROTOCOLERROR 32
+#define REMDESK_ERROR_RCUNKNOWNERROR 33
+#define REMDESK_ERROR_INTERNALERROR 34
+#define REMDESK_ERROR_HELPEERESPONSEPENDING 35
+#define REMDESK_ERROR_HELPEESAIDYES 36
+#define REMDESK_ERROR_HELPEEALREADYBEINGHELPED 37
+#define REMDESK_ERROR_HELPEECONSIDERINGHELP 38
+#define REMDESK_ERROR_HELPEENEVERRESPONDED 40
+#define REMDESK_ERROR_HELPEESAIDNO 41
+#define REMDESK_ERROR_HELPSESSIONACCESSDENIED 42
+#define REMDESK_ERROR_USERNOTFOUND 43
+#define REMDESK_ERROR_SESSMGRERRORNOTINIT 44
+#define REMDESK_ERROR_SELFHELPNOTSUPPORTED 45
+#define REMDESK_ERROR_INCOMPATIBLEVERSION 47
+#define REMDESK_ERROR_SESSIONNOTCONNECTED 48
+#define REMDESK_ERROR_SYSTEMSHUTDOWN 50
+#define REMDESK_ERROR_STOPLISTENBYUSER 51
+#define REMDESK_ERROR_WINSOCK_FAILED 52
+#define REMDESK_ERROR_MISMATCHPARMS 53
+#define REMDESK_ERROR_PASSWORDS_DONT_MATCH 61
+#define REMDESK_ERROR_SHADOWEND_BASE 300
+#define REMDESK_ERROR_SHADOWEND_CONFIGCHANGE 301
+#define REMDESK_ERROR_SHADOWEND_UNKNOWN 302
+
struct _REMDESK_CHANNEL_HEADER
{
UINT32 DataLength;
#define REMDESK_CTL_RAEXPERT_NAME 11
#define REMDESK_CTL_TOKEN 12
+struct _REMDESK_CTL_RESULT_PDU
+{
+ REMDESK_CTL_HEADER ctlHeader;
+
+ UINT32 result;
+};
+typedef struct _REMDESK_CTL_RESULT_PDU REMDESK_CTL_RESULT_PDU;
+
struct _REMDESK_CTL_VERSION_INFO_PDU
{
REMDESK_CTL_HEADER ctlHeader;
extern "C" {
#endif
-FREERDP_API BOOL bitmap_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size, int srcBpp, int dstBpp);
-
FREERDP_API int freerdp_bitmap_compress(char* in_data, int width, int height,
wStream* s, int bpp, int byte_limit, int start_line, wStream* temp_s, int e);
-#define PLANAR_FORMAT_HEADER_CS (1 << 3)
-#define PLANAR_FORMAT_HEADER_RLE (1 << 4)
-#define PLANAR_FORMAT_HEADER_NA (1 << 5)
-#define PLANAR_FORMAT_HEADER_CLL_MASK 0x07
-
-typedef struct _BITMAP_PLANAR_CONTEXT BITMAP_PLANAR_CONTEXT;
-
-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 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);
-
-FREERDP_API int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcSize,
- BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight);
-
#ifdef __cplusplus
}
#endif
#ifndef FREERDP_CODEC_CLEAR_H
#define FREERDP_CODEC_CLEAR_H
+typedef struct _CLEAR_CONTEXT CLEAR_CONTEXT;
+
#include <freerdp/api.h>
#include <freerdp/types.h>
UINT32 ShortVBarStorageCursor;
CLEAR_VBAR_ENTRY ShortVBarStorage[16384];
};
-typedef struct _CLEAR_CONTEXT CLEAR_CONTEXT;
#ifdef __cplusplus
extern "C" {
#include <freerdp/api.h>
#include <freerdp/types.h>
+#include <freerdp/channels/rdpgfx.h>
-#ifdef WITH_OPENH264
-#include "wels/codec_def.h"
-#include "wels/codec_api.h"
-#endif
+typedef struct _H264_CONTEXT H264_CONTEXT;
+
+typedef BOOL (*pfnH264SubsystemInit)(H264_CONTEXT* h264);
+typedef void (*pfnH264SubsystemUninit)(H264_CONTEXT* h264);
+
+typedef int (*pfnH264SubsystemDecompress)(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize);
+
+struct _H264_CONTEXT_SUBSYSTEM
+{
+ const char* name;
+ pfnH264SubsystemInit Init;
+ pfnH264SubsystemUninit Uninit;
+ pfnH264SubsystemDecompress Decompress;
+};
+typedef struct _H264_CONTEXT_SUBSYSTEM H264_CONTEXT_SUBSYSTEM;
struct _H264_CONTEXT
{
BOOL Compressor;
-#ifdef WITH_OPENH264
- ISVCDecoder* pDecoder;
-#endif
+ UINT32 width;
+ UINT32 height;
+
+ int iStride[3];
+ BYTE* pYUVData[3];
+
+ void* pSystemData;
+ H264_CONTEXT_SUBSYSTEM* subsystem;
};
-typedef struct _H264_CONTEXT H264_CONTEXT;
#ifdef __cplusplus
extern "C" {
FREERDP_API int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize);
FREERDP_API int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
- BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight);
-
-FREERDP_API void h264_context_reset(H264_CONTEXT* h264);
+ BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstHeight, RDPGFX_RECT16* regionRects, int numRegionRect);
FREERDP_API H264_CONTEXT* h264_context_new(BOOL Compressor);
FREERDP_API void h264_context_free(H264_CONTEXT* h264);
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Interleaved RLE Bitmap Codec
+ *
+ * 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_CODEC_INTERLEAVED_H
+#define FREERDP_CODEC_INTERLEAVED_H
+
+typedef struct _BITMAP_INTERLEAVED_CONTEXT BITMAP_INTERLEAVED_CONTEXT;
+
+#include <freerdp/api.h>
+#include <freerdp/types.h>
+
+#include <freerdp/codec/color.h>
+#include <freerdp/codec/bitmap.h>
+
+struct _BITMAP_INTERLEAVED_CONTEXT
+{
+ BOOL Compressor;
+
+ UINT32 FlipSize;
+ BYTE* FlipBuffer;
+};
+
+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 BITMAP_INTERLEAVED_CONTEXT* bitmap_interleaved_context_new(BOOL Compressor);
+FREERDP_API void bitmap_interleaved_context_free(BITMAP_INTERLEAVED_CONTEXT* interleaved);
+
+#endif /* FREERDP_CODEC_INTERLEAVED_H */
+
* limitations under the License.
*/
-#ifndef FREERDP_CODEC_PLANAR_PRIVATE_H
-#define FREERDP_CODEC_PLANAR_PRIVATE_H
+#ifndef FREERDP_CODEC_PLANAR_H
+#define FREERDP_CODEC_PLANAR_H
#include <winpr/crt.h>
+typedef struct _BITMAP_PLANAR_CONTEXT BITMAP_PLANAR_CONTEXT;
+
#include <freerdp/codec/color.h>
#include <freerdp/codec/bitmap.h>
+#define PLANAR_FORMAT_HEADER_CS (1 << 3)
+#define PLANAR_FORMAT_HEADER_RLE (1 << 4)
+#define PLANAR_FORMAT_HEADER_NA (1 << 5)
+#define PLANAR_FORMAT_HEADER_CLL_MASK 0x07
+
#define PLANAR_CONTROL_BYTE(_nRunLength, _cRawBytes) \
(_nRunLength & 0x0F) | ((_cRawBytes & 0x0F) << 4)
FREERDP_API BYTE* freerdp_bitmap_planar_delta_encode_plane(BYTE* inPlane, int width, int height, BYTE* outPlane);
FREERDP_API int freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[4], int width, int height, BYTE* outPlanes[4]);
-#endif /* FREERDP_CODEC_PLANAR_PRIVATE_H */
+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 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);
+
+FREERDP_API int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcSize,
+ BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight);
+
+#endif /* FREERDP_CODEC_PLANAR_H */
+
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Progressive Codec Bitmap Compression
+ *
+ * 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_CODEC_PROGRESSIVE_H
+#define FREERDP_CODEC_PROGRESSIVE_H
+
+typedef struct _PROGRESSIVE_CONTEXT PROGRESSIVE_CONTEXT;
+
+#include <freerdp/api.h>
+#include <freerdp/types.h>
+
+#include <winpr/wlog.h>
+#include <winpr/collections.h>
+
+#include <freerdp/codec/rfx.h>
+#include <freerdp/codec/color.h>
+
+#define RFX_SUBBAND_DIFFING 0x01
+
+#define RFX_TILE_DIFFERENCE 0x01
+
+#define RFX_DWT_REDUCE_EXTRAPOLATE 0x01
+
+#define PROGRESSIVE_WBT_SYNC 0xCCC0
+#define PROGRESSIVE_WBT_FRAME_BEGIN 0xCCC1
+#define PROGRESSIVE_WBT_FRAME_END 0xCCC2
+#define PROGRESSIVE_WBT_CONTEXT 0xCCC3
+#define PROGRESSIVE_WBT_REGION 0xCCC4
+#define PROGRESSIVE_WBT_TILE_SIMPLE 0xCCC5
+#define PROGRESSIVE_WBT_TILE_FIRST 0xCCC6
+#define PROGRESSIVE_WBT_TILE_UPGRADE 0xCCC7
+
+#define PROGRESSIVE_BLOCKS_ALL 0x0001
+#define PROGRESSIVE_BLOCKS_REGION 0x0002
+#define PROGRESSIVE_BLOCKS_TILE 0x0004
+
+struct _RFX_COMPONENT_CODEC_QUANT
+{
+ BYTE LL3;
+ BYTE HL3;
+ BYTE LH3;
+ BYTE HH3;
+ BYTE HL2;
+ BYTE LH2;
+ BYTE HH2;
+ BYTE HL1;
+ BYTE LH1;
+ BYTE HH1;
+};
+typedef struct _RFX_COMPONENT_CODEC_QUANT RFX_COMPONENT_CODEC_QUANT;
+
+struct _RFX_PROGRESSIVE_CODEC_QUANT
+{
+ BYTE quality;
+ RFX_COMPONENT_CODEC_QUANT yQuantValues;
+ RFX_COMPONENT_CODEC_QUANT cbQuantValues;
+ RFX_COMPONENT_CODEC_QUANT crQuantValues;
+};
+typedef struct _RFX_PROGRESSIVE_CODEC_QUANT RFX_PROGRESSIVE_CODEC_QUANT;
+
+struct _PROGRESSIVE_BLOCK
+{
+ UINT16 blockType;
+ UINT32 blockLen;
+};
+typedef struct _PROGRESSIVE_BLOCK PROGRESSIVE_BLOCK;
+
+struct _PROGRESSIVE_BLOCK_SYNC
+{
+ UINT16 blockType;
+ UINT32 blockLen;
+
+ UINT32 magic;
+ UINT16 version;
+};
+typedef struct _PROGRESSIVE_BLOCK_SYNC PROGRESSIVE_BLOCK_SYNC;
+
+struct _PROGRESSIVE_BLOCK_CONTEXT
+{
+ UINT16 blockType;
+ UINT32 blockLen;
+
+ BYTE ctxId;
+ UINT16 tileSize;
+ BYTE flags;
+};
+typedef struct _PROGRESSIVE_BLOCK_CONTEXT PROGRESSIVE_BLOCK_CONTEXT;
+
+struct _PROGRESSIVE_BLOCK_TILE_SIMPLE
+{
+ UINT16 blockType;
+ UINT32 blockLen;
+
+ BYTE quantIdxY;
+ BYTE quantIdxCb;
+ BYTE quantIdxCr;
+ UINT16 xIdx;
+ UINT16 yIdx;
+ BYTE flags;
+ UINT16 yLen;
+ UINT16 cbLen;
+ UINT16 crLen;
+ UINT16 tailLen;
+ BYTE* yData;
+ BYTE* cbData;
+ BYTE* crData;
+ BYTE* tailData;
+};
+typedef struct _PROGRESSIVE_BLOCK_TILE_SIMPLE PROGRESSIVE_BLOCK_TILE_SIMPLE;
+
+struct _PROGRESSIVE_BLOCK_TILE_FIRST
+{
+ UINT16 blockType;
+ UINT32 blockLen;
+
+ BYTE quantIdxY;
+ BYTE quantIdxCb;
+ BYTE quantIdxCr;
+ UINT16 xIdx;
+ UINT16 yIdx;
+ BYTE flags;
+ BYTE quality;
+ UINT16 yLen;
+ UINT16 cbLen;
+ UINT16 crLen;
+ UINT16 tailLen;
+ BYTE* yData;
+ BYTE* cbData;
+ BYTE* crData;
+ BYTE* tailData;
+};
+typedef struct _PROGRESSIVE_BLOCK_TILE_FIRST PROGRESSIVE_BLOCK_TILE_FIRST;
+
+struct _PROGRESSIVE_BLOCK_TILE_UPGRADE
+{
+ UINT16 blockType;
+ UINT32 blockLen;
+
+ BYTE quantIdxY;
+ BYTE quantIdxCb;
+ BYTE quantIdxCr;
+ UINT16 xIdx;
+ UINT16 yIdx;
+ BYTE quality;
+ UINT16 ySrlLen;
+ UINT16 yRawLen;
+ UINT16 cbSrlLen;
+ UINT16 cbRawLen;
+ UINT16 crSrlLen;
+ UINT16 crRawLen;
+ BYTE* ySrlData;
+ BYTE* yRawData;
+ BYTE* cbSrlData;
+ BYTE* cbRawData;
+ BYTE* crSrlData;
+ BYTE* crRawData;
+};
+typedef struct _PROGRESSIVE_BLOCK_TILE_UPGRADE PROGRESSIVE_BLOCK_TILE_UPGRADE;
+
+struct _RFX_PROGRESSIVE_TILE
+{
+ UINT16 blockType;
+ UINT32 blockLen;
+
+ BYTE quantIdxY;
+ BYTE quantIdxCb;
+ BYTE quantIdxCr;
+ UINT16 xIdx;
+ UINT16 yIdx;
+
+ BYTE flags;
+ BYTE quality;
+
+ UINT16 yLen;
+ UINT16 cbLen;
+ UINT16 crLen;
+ UINT16 tailLen;
+ BYTE* yData;
+ BYTE* cbData;
+ BYTE* crData;
+ BYTE* tailData;
+
+ UINT16 ySrlLen;
+ UINT16 yRawLen;
+ UINT16 cbSrlLen;
+ UINT16 cbRawLen;
+ UINT16 crSrlLen;
+ UINT16 crRawLen;
+ BYTE* ySrlData;
+ BYTE* yRawData;
+ BYTE* cbSrlData;
+ BYTE* cbRawData;
+ BYTE* crSrlData;
+ BYTE* crRawData;
+
+ int x;
+ int y;
+ int width;
+ int height;
+ BYTE* data;
+ BYTE* current;
+
+ int pass;
+ BYTE* sign;
+ RFX_COMPONENT_CODEC_QUANT yBitPos;
+ RFX_COMPONENT_CODEC_QUANT cbBitPos;
+ RFX_COMPONENT_CODEC_QUANT crBitPos;
+ RFX_COMPONENT_CODEC_QUANT yQuant;
+ RFX_COMPONENT_CODEC_QUANT cbQuant;
+ RFX_COMPONENT_CODEC_QUANT crQuant;
+ RFX_COMPONENT_CODEC_QUANT yProgQuant;
+ RFX_COMPONENT_CODEC_QUANT cbProgQuant;
+ RFX_COMPONENT_CODEC_QUANT crProgQuant;
+};
+typedef struct _RFX_PROGRESSIVE_TILE RFX_PROGRESSIVE_TILE;
+
+struct _PROGRESSIVE_BLOCK_REGION
+{
+ UINT16 blockType;
+ UINT32 blockLen;
+
+ BYTE tileSize;
+ UINT16 numRects;
+ BYTE numQuant;
+ BYTE numProgQuant;
+ BYTE flags;
+ UINT16 numTiles;
+ UINT32 tileDataSize;
+ RFX_RECT* rects;
+ RFX_COMPONENT_CODEC_QUANT* quantVals;
+ RFX_PROGRESSIVE_CODEC_QUANT* quantProgVals;
+ RFX_PROGRESSIVE_TILE** tiles;
+};
+typedef struct _PROGRESSIVE_BLOCK_REGION PROGRESSIVE_BLOCK_REGION;
+
+struct _PROGRESSIVE_BLOCK_FRAME_BEGIN
+{
+ UINT16 blockType;
+ UINT32 blockLen;
+
+ UINT32 frameIndex;
+ UINT16 regionCount;
+ PROGRESSIVE_BLOCK_REGION* regions;
+};
+typedef struct _PROGRESSIVE_BLOCK_FRAME_BEGIN PROGRESSIVE_BLOCK_FRAME_BEGIN;
+
+struct _PROGRESSIVE_BLOCK_FRAME_END
+{
+ UINT16 blockType;
+ UINT32 blockLen;
+};
+typedef struct _PROGRESSIVE_BLOCK_FRAME_END PROGRESSIVE_BLOCK_FRAME_END;
+
+struct _PROGRESSIVE_SURFACE_CONTEXT
+{
+ UINT16 id;
+ UINT32 width;
+ UINT32 height;
+ UINT32 gridWidth;
+ UINT32 gridHeight;
+ UINT32 gridSize;
+ RFX_PROGRESSIVE_TILE* tiles;
+};
+typedef struct _PROGRESSIVE_SURFACE_CONTEXT PROGRESSIVE_SURFACE_CONTEXT;
+
+struct _PROGRESSIVE_CONTEXT
+{
+ BOOL Compressor;
+
+ wLog* log;
+ wBufferPool* bufferPool;
+
+ UINT32 cRects;
+ RFX_RECT* rects;
+
+ UINT32 cTiles;
+ RFX_PROGRESSIVE_TILE** tiles;
+
+ UINT32 cQuant;
+ RFX_COMPONENT_CODEC_QUANT* quantVals;
+
+ UINT32 cProgQuant;
+ RFX_PROGRESSIVE_CODEC_QUANT* quantProgVals;
+
+ PROGRESSIVE_BLOCK_REGION region;
+ RFX_PROGRESSIVE_CODEC_QUANT quantProgValFull;
+
+ wHashTable* SurfaceContexts;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+FREERDP_API int progressive_compress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize);
+
+FREERDP_API int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize,
+ BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, UINT16 surfaceId);
+
+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 PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor);
+FREERDP_API void progressive_context_free(PROGRESSIVE_CONTEXT* progressive);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_CODEC_PROGRESSIVE_H */
+
#ifndef FREERDP_CODEC_REMOTEFX_H
#define FREERDP_CODEC_REMOTEFX_H
+typedef enum _RLGR_MODE RLGR_MODE;
+typedef struct _RFX_RECT RFX_RECT;
+typedef struct _RFX_TILE RFX_TILE;
+typedef struct _RFX_MESSAGE RFX_MESSAGE;
+typedef struct _RFX_CONTEXT RFX_CONTEXT;
+
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/freerdp.h>
RLGR1,
RLGR3
};
-typedef enum _RLGR_MODE RLGR_MODE;
struct _RFX_RECT
{
UINT16 width;
UINT16 height;
};
-typedef struct _RFX_RECT RFX_RECT;
struct _RFX_TILE
{
BYTE* CrData;
BYTE* YCbCrData;
};
-typedef struct _RFX_TILE RFX_TILE;
struct _RFX_MESSAGE
{
BOOL freeArray;
};
-typedef struct _RFX_MESSAGE RFX_MESSAGE;
typedef struct _RFX_CONTEXT_PRIV RFX_CONTEXT_PRIV;
void (*quantization_encode)(INT16* buffer, const UINT32* quantization_values);
void (*dwt_2d_decode)(INT16* buffer, INT16* dwt_buffer);
void (*dwt_2d_encode)(INT16* buffer, INT16* dwt_buffer);
- int (*rlgr_decode)(RLGR_MODE mode, const BYTE* data, int data_size, INT16* buffer, int buffer_size);
- int (*rlgr_encode)(RLGR_MODE mode, const INT16* data, int data_size, BYTE* buffer, int buffer_size);
/* private definitions */
RFX_CONTEXT_PRIV* priv;
};
-typedef struct _RFX_CONTEXT RFX_CONTEXT;
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);
+
FREERDP_API RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length);
FREERDP_API UINT16 rfx_message_get_tile_count(RFX_MESSAGE* message);
FREERDP_API RFX_TILE* rfx_message_get_tile(RFX_MESSAGE* message, int index);
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * RDP Codecs
+ *
+ * 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_CODECS_H
+#define FREERDP_CODECS_H
+
+#include <freerdp/api.h>
+
+#include <freerdp/codec/color.h>
+
+#include <freerdp/codec/rfx.h>
+#include <freerdp/codec/nsc.h>
+#include <freerdp/codec/h264.h>
+#include <freerdp/codec/clear.h>
+#include <freerdp/codec/planar.h>
+#include <freerdp/codec/interleaved.h>
+#include <freerdp/codec/progressive.h>
+
+#define FREERDP_CODEC_INTERLEAVED 0x00000001
+#define FREERDP_CODEC_PLANAR 0x00000002
+#define FREERDP_CODEC_NSCODEC 0x00000004
+#define FREERDP_CODEC_REMOTEFX 0x00000008
+#define FREERDP_CODEC_CLEARCODEC 0x00000010
+#define FREERDP_CODEC_ALPHACODEC 0x00000020
+#define FREERDP_CODEC_PROGRESSIVE 0x00000040
+#define FREERDP_CODEC_H264 0x00000080
+
+struct rdp_codecs
+{
+ rdpContext* context;
+
+ RFX_CONTEXT* rfx;
+ NSC_CONTEXT* nsc;
+ H264_CONTEXT* h264;
+ CLEAR_CONTEXT* clear;
+ PROGRESSIVE_CONTEXT* progressive;
+ BITMAP_PLANAR_CONTEXT* planar;
+ BITMAP_INTERLEAVED_CONTEXT* interleaved;
+};
+
+FREERDP_API int freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags);
+
+FREERDP_API rdpCodecs* codecs_new(rdpContext* context);
+FREERDP_API void codecs_free(rdpCodecs* codecs);
+
+#endif /* FREERDP_CODECS_H */
+
typedef struct rdp_channels rdpChannels;
typedef struct rdp_graphics rdpGraphics;
typedef struct rdp_metrics rdpMetrics;
+typedef struct rdp_codecs rdpCodecs;
typedef struct rdp_freerdp freerdp;
typedef struct rdp_context rdpContext;
#include <freerdp/types.h>
#include <freerdp/error.h>
#include <freerdp/event.h>
+#include <freerdp/codecs.h>
#include <freerdp/metrics.h>
#include <freerdp/settings.h>
#include <freerdp/extension.h>
ALIGN64 rdpUpdate* update; /* 39 */
ALIGN64 rdpSettings* settings; /* 40 */
ALIGN64 rdpMetrics* metrics; /* 41 */
- UINT64 paddingC[64 - 42]; /* 42 */
+ ALIGN64 rdpCodecs* codecs; /* 42 */
+ UINT64 paddingC[64 - 43]; /* 43 */
UINT64 paddingD[96 - 64]; /* 64 */
UINT64 paddingE[128 - 96]; /* 96 */
int cursor_x;
int cursor_y;
int bytesPerPixel;
+ rdpCodecs* codecs;
HGDI_DC hdc;
HCLRCONV clrconv;
gdiBitmap* drawing;
BYTE* primary_buffer;
GDI_COLOR textColor;
- void* rfx_context;
- void* nsc_context;
gdiBitmap* tile;
gdiBitmap* image;
};
typedef void (*pSynchronizeEvent)(rdpInput* input, UINT32 flags);
typedef void (*pKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code);
+typedef void (*pKeyboardPauseEvent)(rdpInput* input);
typedef void (*pUnicodeKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code);
typedef void (*pMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
typedef void (*pExtendedMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
pMouseEvent MouseEvent; /* 19 */
pExtendedMouseEvent ExtendedMouseEvent; /* 20 */
pFocusInEvent FocusInEvent; /*21 */
+ pKeyboardPauseEvent KeyboardPauseEvent; /* 22 */
- UINT32 paddingB[32 - 22]; /* 22 */
+ UINT32 paddingB[32 - 23]; /* 23 */
/* Internal */
FREERDP_API void freerdp_input_send_synchronize_event(rdpInput* input, UINT32 flags);
FREERDP_API void freerdp_input_send_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code);
FREERDP_API void freerdp_input_send_keyboard_event_ex(rdpInput* input, BOOL down, UINT32 rdp_scancode);
+FREERDP_API void freerdp_input_send_keyboard_pause_event(rdpInput* input);
FREERDP_API void freerdp_input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code);
FREERDP_API void freerdp_input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
FREERDP_API void freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
/**
* FreeRDP: A Remote Desktop Protocol Implementation
- * X11 Server Monitors
+ * FreeRDP log defines
*
- * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.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.
* limitations under the License.
*/
-#ifndef XFREERDP_SERVER_MONITORS_H
-#define XFREERDP_SERVER_MONITORS_H
+#ifndef FREERDP_LOG_H
+#define FREERDP_LOG_H
-#include "xfreerdp.h"
+#include <winpr/wlog.h>
-int xf_list_monitors(xfInfo* xfi);
-
-#endif /* XFREERDP_SERVER_MONITORS_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 */
rdpUpdate* update;
rdpSettings* settings;
+ void* ContextExtra;
size_t ContextSize;
psPeerContextNew ContextNew;
psPeerContextFree ContextFree;
const INT16 *pSrc,
INT16 *pDst,
INT32 len);
+typedef pstatus_t (*__yCbCrToRGB_16s8u_P3AC4R_t)(
+ const INT16* pSrc[3], INT32 srcStep,
+ BYTE* pDst, INT32 dstStep,
+ const prim_size_t* roi);
typedef pstatus_t (*__yCbCrToRGB_16s16s_P3P3_t)(
const INT16 *pSrc[3], INT32 srcStep,
INT16 *pDst[3], INT32 dstStep,
const INT16 *pSrc[3], INT32 srcStep,
BYTE *pDst, INT32 dstStep,
const prim_size_t *roi);
-typedef pstatus_t (*__YCoCgRToRGB_8u_AC4R_t)(
+typedef pstatus_t (*__YCoCgToRGB_8u_AC4R_t)(
const BYTE *pSrc, INT32 srcStep,
BYTE *pDst, INT32 dstStep,
UINT32 width, UINT32 height,
UINT32* pDst, INT32 dstStep,
UINT32 width, UINT32 height,
BOOL alpha, BOOL invert);
+typedef pstatus_t (*__YUV420ToRGB_8u_P3AC4R_t)(
+ const BYTE* pSrc[3], INT32 srcStep[3],
+ BYTE* pDst, INT32 dstStep,
+ const prim_size_t* roi);
typedef pstatus_t (*__andC_32u_t)(
const UINT32 *pSrc,
UINT32 val,
/* Sign */
__sign_16s_t sign_16s;
/* Color conversions */
+ __yCbCrToRGB_16s8u_P3AC4R_t yCbCrToRGB_16s8u_P3AC4R;
__yCbCrToRGB_16s16s_P3P3_t yCbCrToRGB_16s16s_P3P3;
__RGBToYCbCr_16s16s_P3P3_t RGBToYCbCr_16s16s_P3P3;
__RGBToRGB_16s8u_P3AC4R_t RGBToRGB_16s8u_P3AC4R;
- __YCoCgRToRGB_8u_AC4R_t YCoCgRToRGB_8u_AC4R;
+ __YCoCgToRGB_8u_AC4R_t YCoCgToRGB_8u_AC4R;
__RGB565ToARGB_16u32u_C3C4_t RGB565ToARGB_16u32u_C3C4;
+ __YUV420ToRGB_8u_P3AC4R_t YUV420ToRGB_8u_P3AC4R;
} primitives_t;
#ifdef __cplusplus
#ifndef FREERDP_RAIL_GLOBAL_H
#define FREERDP_RAIL_GLOBAL_H
+#include <winpr/wnd.h>
+
#include <freerdp/types.h>
/* RAIL PDU flags */
/* Client Notify Event PDU */
#ifndef _WIN32
-#define WM_LBUTTONDOWN 0x00000201
-#define WM_LBUTTONUP 0x00000202
-#define WM_RBUTTONDOWN 0x00000204
-#define WM_RBUTTONUP 0x00000205
-#define WM_CONTEXTMENU 0x0000007B
-#define WM_LBUTTONDBLCLK 0x00000203
-#define WM_RBUTTONDBLCLK 0x00000206
-
#define NIN_SELECT 0x00000400
#define NIN_KEYSELECT 0x00000401
#define NIN_BALLOONSHOW 0x00000402
#include <freerdp/types.h>
#include <freerdp/channels/wtsvc.h>
-#include <freerdp/client/encomsp.h>
+#include <freerdp/channels/encomsp.h>
/**
* Server Interface
typedef int (*psEncomspStart)(EncomspServerContext* context);
typedef int (*psEncomspStop)(EncomspServerContext* context);
+typedef int (*psEncomspFilterUpdated)(EncomspServerContext* context, ENCOMSP_FILTER_UPDATED_PDU* filterUpdated);
+typedef int (*psEncomspApplicationCreated)(EncomspServerContext* context, ENCOMSP_APPLICATION_CREATED_PDU* applicationCreated);
+typedef int (*psEncomspApplicationRemoved)(EncomspServerContext* context, ENCOMSP_APPLICATION_REMOVED_PDU* applicationRemoved);
+typedef int (*psEncomspWindowCreated)(EncomspServerContext* context, ENCOMSP_WINDOW_CREATED_PDU* windowCreated);
+typedef int (*psEncomspWindowRemoved)(EncomspServerContext* context, ENCOMSP_WINDOW_REMOVED_PDU* windowRemoved);
+typedef int (*psEncomspShowWindow)(EncomspServerContext* context, ENCOMSP_SHOW_WINDOW_PDU* showWindow);
+typedef int (*psEncomspParticipantCreated)(EncomspServerContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated);
+typedef int (*psEncomspParticipantRemoved)(EncomspServerContext* context, ENCOMSP_PARTICIPANT_REMOVED_PDU* participantRemoved);
+typedef int (*psEncomspChangeParticipantControlLevel)(EncomspServerContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* changeParticipantControlLevel);
+typedef int (*psEncomspGraphicsStreamPaused)(EncomspServerContext* context, ENCOMSP_GRAPHICS_STREAM_PAUSED_PDU* graphicsStreamPaused);
+typedef int (*psEncomspGraphicsStreamResumed)(EncomspServerContext* context, ENCOMSP_GRAPHICS_STREAM_RESUMED_PDU* graphicsStreamResumed);
+
struct _encomsp_server_context
{
HANDLE vcm;
+ void* custom;
psEncomspStart Start;
psEncomspStop Stop;
+ psEncomspFilterUpdated FilterUpdated;
+ psEncomspApplicationCreated ApplicationCreated;
+ psEncomspApplicationRemoved ApplicationRemoved;
+ psEncomspWindowCreated WindowCreated;
+ psEncomspWindowRemoved WindowRemoved;
+ psEncomspShowWindow ShowWindow;
+ psEncomspParticipantCreated ParticipantCreated;
+ psEncomspParticipantRemoved ParticipantRemoved;
+ psEncomspChangeParticipantControlLevel ChangeParticipantControlLevel;
+ psEncomspGraphicsStreamPaused GraphicsStreamPaused;
+ psEncomspGraphicsStreamResumed GraphicsStreamResumed;
+
EncomspServerPrivate* priv;
};
struct _remdesk_server_context
{
HANDLE vcm;
+ void* custom;
psRemdeskStart Start;
psRemdeskStop Stop;
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Session Shadowing
+ *
+ * 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_SERVER_SHADOW_H
+#define FREERDP_SERVER_SHADOW_H
+
+#include <freerdp/api.h>
+#include <freerdp/types.h>
+
+#include <freerdp/settings.h>
+#include <freerdp/listener.h>
+
+#include <freerdp/channels/wtsvc.h>
+#include <freerdp/channels/channels.h>
+
+#include <freerdp/server/encomsp.h>
+#include <freerdp/server/remdesk.h>
+
+#include <freerdp/codec/color.h>
+#include <freerdp/codec/region.h>
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/collections.h>
+
+typedef struct rdp_shadow_client rdpShadowClient;
+typedef struct rdp_shadow_server rdpShadowServer;
+typedef struct rdp_shadow_screen rdpShadowScreen;
+typedef struct rdp_shadow_surface rdpShadowSurface;
+typedef struct rdp_shadow_encoder rdpShadowEncoder;
+typedef struct rdp_shadow_capture rdpShadowCapture;
+typedef struct rdp_shadow_subsystem rdpShadowSubsystem;
+
+typedef rdpShadowSubsystem* (*pfnShadowCreateSubsystem)(rdpShadowServer* server);
+
+typedef int (*pfnShadowSubsystemInit)(rdpShadowSubsystem* subsystem);
+typedef int (*pfnShadowSubsystemUninit)(rdpShadowSubsystem* subsystem);
+typedef int (*pfnShadowSubsystemStart)(rdpShadowSubsystem* subsystem);
+typedef int (*pfnShadowSubsystemStop)(rdpShadowSubsystem* subsystem);
+typedef void (*pfnShadowSubsystemFree)(rdpShadowSubsystem* subsystem);
+
+typedef int (*pfnShadowSurfaceCopy)(rdpShadowSubsystem* subsystem);
+typedef int (*pfnShadowSurfaceUpdate)(rdpShadowSubsystem* subsystem, REGION16* region);
+
+typedef int (*pfnShadowSynchronizeEvent)(rdpShadowSubsystem* subsystem, UINT32 flags);
+typedef int (*pfnShadowKeyboardEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 code);
+typedef int (*pfnShadowUnicodeKeyboardEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 code);
+typedef int (*pfnShadowMouseEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y);
+typedef int (*pfnShadowExtendedMouseEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y);
+
+struct rdp_shadow_client
+{
+ rdpContext context;
+
+ HANDLE thread;
+ BOOL activated;
+ BOOL inLobby;
+ BOOL mayView;
+ BOOL mayInteract;
+ HANDLE StopEvent;
+ CRITICAL_SECTION lock;
+ REGION16 invalidRegion;
+ rdpShadowServer* server;
+ rdpShadowSurface* lobby;
+ rdpShadowEncoder* encoder;
+
+ HANDLE vcm;
+ EncomspServerContext* encomsp;
+ RemdeskServerContext* remdesk;
+};
+
+struct rdp_shadow_server
+{
+ void* ext;
+ HANDLE thread;
+ HANDLE StopEvent;
+ wArrayList* clients;
+ rdpShadowScreen* screen;
+ rdpShadowSurface* surface;
+ rdpShadowCapture* capture;
+ rdpShadowSubsystem* subsystem;
+
+ DWORD port;
+ BOOL mayView;
+ BOOL mayInteract;
+ char* ipcSocket;
+ char* ConfigPath;
+ char* CertificateFile;
+ char* PrivateKeyFile;
+ CRITICAL_SECTION lock;
+ freerdp_listener* listener;
+ pfnShadowCreateSubsystem CreateSubsystem;
+};
+
+#define RDP_SHADOW_SUBSYSTEM_COMMON() \
+ HANDLE event; \
+ int monitorCount; \
+ MONITOR_DEF monitors[16]; \
+ MONITOR_DEF virtualScreen; \
+ HANDLE updateEvent; \
+ REGION16 invalidRegion; \
+ SYNCHRONIZATION_BARRIER barrier; \
+ \
+ pfnShadowSubsystemInit Init; \
+ pfnShadowSubsystemUninit Uninit; \
+ pfnShadowSubsystemStart Start; \
+ pfnShadowSubsystemStop Stop; \
+ pfnShadowSubsystemFree Free; \
+ \
+ pfnShadowSurfaceCopy SurfaceCopy; \
+ pfnShadowSurfaceUpdate SurfaceUpdate; \
+ \
+ pfnShadowSynchronizeEvent SynchronizeEvent; \
+ pfnShadowKeyboardEvent KeyboardEvent; \
+ pfnShadowUnicodeKeyboardEvent UnicodeKeyboardEvent; \
+ pfnShadowMouseEvent MouseEvent; \
+ pfnShadowExtendedMouseEvent ExtendedMouseEvent; \
+ \
+ rdpShadowServer* server
+
+struct rdp_shadow_subsystem
+{
+ RDP_SHADOW_SUBSYSTEM_COMMON();
+};
+
+#endif /* FREERDP_SERVER_SHADOW_H */
+
#define LB_CLIENT_TSV_URL 0x00001000
#define LB_SERVER_TSV_CAPABLE 0x00002000
+/* Keyboard Hook */
+#define KEYBOARD_HOOK_LOCAL 0
+#define KEYBOARD_HOOK_REMOTE 1
+#define KEYBOARD_HOOK_FULLSCREEN_ONLY 2
+
struct _TARGET_NET_ADDRESS
{
UINT32 Length;
#define FreeRDP_ServerRandomLength 197
#define FreeRDP_ServerCertificate 198
#define FreeRDP_ServerCertificateLength 199
+#define FreeRDP_ClientRandom 200
+#define FreeRDP_ClientRandomLength 201
#define FreeRDP_ChannelCount 256
#define FreeRDP_ChannelDefArraySize 257
#define FreeRDP_ChannelDefArray 258
#define FreeRDP_FastPathInput 2630
#define FreeRDP_MultiTouchInput 2631
#define FreeRDP_MultiTouchGestures 2632
+#define FreeRDP_KeyboardHook 2633
#define FreeRDP_BrushSupportLevel 2688
#define FreeRDP_GlyphSupportLevel 2752
#define FreeRDP_GlyphCache 2753
ALIGN64 UINT32 ExtEncryptionMethods; /* 194 */
ALIGN64 UINT32 EncryptionLevel; /* 195 */
ALIGN64 BYTE* ServerRandom; /* 196 */
- ALIGN64 DWORD ServerRandomLength; /* 197 */
+ ALIGN64 UINT32 ServerRandomLength; /* 197 */
ALIGN64 BYTE* ServerCertificate; /* 198 */
- ALIGN64 DWORD ServerCertificateLength; /* 199 */
+ ALIGN64 UINT32 ServerCertificateLength; /* 199 */
ALIGN64 BYTE* ClientRandom; /* 200 */
- UINT64 padding0256[256 - 201]; /* 201 */
+ ALIGN64 UINT32 ClientRandomLength; /* 201 */
+ UINT64 padding0256[256 - 202]; /* 202 */
/* Client Network Data */
ALIGN64 UINT32 ChannelCount; /* 256 */
/* Credentials Cache */
ALIGN64 BYTE* Password51; /* 1280 */
- ALIGN64 DWORD Password51Length; /* 1281 */
+ ALIGN64 UINT32 Password51Length; /* 1281 */
UINT64 padding1344[1344 - 1282]; /* 1282 */
/* Kerberos Authentication */
ALIGN64 char* RemoteApplicationFile; /* 2116 */
ALIGN64 char* RemoteApplicationGuid; /* 2117 */
ALIGN64 char* RemoteApplicationCmdLine; /* 2118 */
- ALIGN64 DWORD RemoteApplicationExpandCmdLine; /* 2119 */
- ALIGN64 DWORD RemoteApplicationExpandWorkingDir; /* 2120 */
+ ALIGN64 UINT32 RemoteApplicationExpandCmdLine; /* 2119 */
+ ALIGN64 UINT32 RemoteApplicationExpandWorkingDir; /* 2120 */
ALIGN64 BOOL DisableRemoteAppCapsCheck; /* 2121 */
ALIGN64 UINT32 RemoteAppNumIconCaches; /* 2122 */
ALIGN64 UINT32 RemoteAppNumIconCacheEntries; /* 2123 */
ALIGN64 BOOL FastPathInput; /* 2630 */
ALIGN64 BOOL MultiTouchInput; /* 2631 */
ALIGN64 BOOL MultiTouchGestures; /* 2632 */
- UINT64 padding2688[2688 - 2633]; /* 2633 */
+ ALIGN64 UINT32 KeyboardHook; /* 2633 */
+ UINT64 padding2688[2688 - 2634]; /* 2634 */
/* Brush Capabilities */
ALIGN64 UINT32 BrushSupportLevel; /* 2688 */
ALIGN64 UINT32 DynamicChannelCount; /* 5056 */
ALIGN64 UINT32 DynamicChannelArraySize; /* 5057 */
ALIGN64 ADDIN_ARGV** DynamicChannelArray; /* 5058 */
- UINT64 padding5184[5184 - 5059]; /* 5059 */
+ ALIGN64 BOOL SupportDynamicChannels; /* 5059 */
+ UINT64 padding5184[5184 - 5060]; /* 5060 */
/**
* WARNING: End of ABI stable zone!
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#endif
+struct _PALETTE_ENTRY
+{
+ BYTE red;
+ BYTE green;
+ BYTE blue;
+};
+typedef struct _PALETTE_ENTRY PALETTE_ENTRY;
+
+struct rdp_palette
+{
+ UINT32 count;
+ PALETTE_ENTRY entries[256];
+};
+typedef struct rdp_palette rdpPalette;
+
#include <freerdp/settings.h>
struct _RDP_PLUGIN_DATA
/* Palette Updates */
-struct _PALETTE_ENTRY
-{
- BYTE red;
- BYTE green;
- BYTE blue;
-};
-typedef struct _PALETTE_ENTRY PALETTE_ENTRY;
-
struct _PALETTE_UPDATE
{
UINT32 number;
};
typedef struct _PALETTE_UPDATE PALETTE_UPDATE;
-struct rdp_palette
-{
- UINT32 count;
- PALETTE_ENTRY entries[256];
-};
-typedef struct rdp_palette rdpPalette;
-
/* Play Sound (System Beep) Updates */
struct _PLAY_SOUND_UPDATE
#ifndef FREERDP_UTILS_DEBUG_H
#define FREERDP_UTILS_DEBUG_H
-#define DEBUG_NULL(fmt, ...) do { } while (0)
-
-/* When building for android redirect all debug messages
- * to logcat. */
-#if defined(ANDROID)
-#include <android/log.h>
-
-#define APP_NAME "freerdp-debug"
-
-#define ANDROID_DEBUG_PRINT(_dbg_str, fmt, ...) do { \
- __android_log_print(_dbg_str, fmt, ##__VA_ARGS__); \
- } while( 0 )
-
-#define DEBUG_CLASS(_dbg_class, fmt, ...) \
- ANDROID_DEBUG_PRINT(ANDROID_LOG_DEBUG, APP_NAME, \
- "DBG_" #_dbg_class " %s (%s:%d): " \
- fmt, __FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__)
+#include <winpr/wlog.h>
+
+#define DEBUG_PRINT(level, file, fkt, line, dbg_str, fmt, ...) \
+ do { \
+ wLog *log = WLog_Get("com.freerdp.legacy"); \
+ wLogMessage msg; \
+ \
+ 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 DEBUG_WARN(fmt, ...) \
- ANDROID_DEBUG_PRINT(ANDROID_LOG_WARN, APP_NAME, "Warning %s (%s:%d): " \
- fmt, __FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__)
-
-#else
-/* By default all log messages are written to stdout */
-#include <stdio.h>
-
-#define DEBUG_PRINT(_dbg_str, fmt, ...) do { \
- fprintf(stderr, _dbg_str, __FUNCTION__, __FILE__, __LINE__); \
- fprintf(stderr, fmt, ## __VA_ARGS__); \
- fprintf(stderr, "\n"); \
- } while( 0 )
-
-
-#define DEBUG_CLASS(_dbg_class, fmt, ...) DEBUG_PRINT("DBG_" #_dbg_class " %s (%s:%d): ", fmt, ## __VA_ARGS__)
-#define DEBUG_WARN(fmt, ...) DEBUG_PRINT("Warning %s (%s:%d): ", fmt, ## __VA_ARGS__)
-#endif
+#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__)
+#define DEBUG_MSG(fmt, ...) DEBUG_PRINT(WLOG_DEBUG, __FILE__, __FUNCTION__, \
+ __LINE__, "freerdp", fmt, ## __VA_ARGS__)
+#define DEBUG_WARN(fmt, ...) DEBUG_PRINT(WLOG_ERROR, __FILE__, __FUNCTION__, \
+ __LINE__, "freerdp", fmt, ## __VA_ARGS__)
#endif /* FREERDP_UTILS_DEBUG_H */
#include <freerdp/constants.h>
#include <winpr/stream.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/cache/bitmap.h>
void update_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
if (id > bitmapCache->maxCells)
{
- fprintf(stderr, "get invalid bitmap cell id: %d\n", id);
+ DEBUG_WARN( "get invalid bitmap cell id: %d\n", id);
return NULL;
}
}
else if (index > bitmapCache->cells[id].number)
{
- fprintf(stderr, "get invalid bitmap index %d in cell id: %d\n", index, id);
+ DEBUG_WARN( "get invalid bitmap index %d in cell id: %d\n", index, id);
return NULL;
}
{
if (id > bitmapCache->maxCells)
{
- fprintf(stderr, "put invalid bitmap cell id: %d\n", id);
+ DEBUG_WARN( "put invalid bitmap cell id: %d\n", id);
return;
}
}
else if (index > bitmapCache->cells[id].number)
{
- fprintf(stderr, "put invalid bitmap index %d in cell id: %d\n", index, id);
+ DEBUG_WARN( "put invalid bitmap index %d in cell id: %d\n", index, id);
return;
}
#include <freerdp/freerdp.h>
#include <winpr/stream.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/cache/brush.h>
void update_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
{
if (index >= brushCache->maxMonoEntries)
{
- fprintf(stderr, "invalid brush (%d bpp) index: 0x%04X\n", *bpp, index);
+ DEBUG_WARN( "invalid brush (%d bpp) index: 0x%04X\n", *bpp, index);
return NULL;
}
{
if (index >= brushCache->maxEntries)
{
- fprintf(stderr, "invalid brush (%d bpp) index: 0x%04X\n", *bpp, index);
+ DEBUG_WARN( "invalid brush (%d bpp) index: 0x%04X\n", *bpp, index);
return NULL;
}
if (entry == NULL)
{
- fprintf(stderr, "invalid brush (%d bpp) at index: 0x%04X\n", *bpp, index);
+ DEBUG_WARN( "invalid brush (%d bpp) at index: 0x%04X\n", *bpp, index);
return NULL;
}
{
if (index >= brushCache->maxMonoEntries)
{
- fprintf(stderr, "invalid brush (%d bpp) index: 0x%04X\n", bpp, index);
+ DEBUG_WARN( "invalid brush (%d bpp) index: 0x%04X\n", bpp, index);
if (entry)
free(entry);
{
if (index >= brushCache->maxEntries)
{
- fprintf(stderr, "invalid brush (%d bpp) index: 0x%04X\n", bpp, index);
+ DEBUG_WARN( "invalid brush (%d bpp) index: 0x%04X\n", bpp, index);
if (entry)
free(entry);
#include <freerdp/freerdp.h>
#include <winpr/stream.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/cache/glyph.h>
void update_process_glyph(rdpContext* context, BYTE* data, int* index,
if (id > 9)
{
- fprintf(stderr, "invalid glyph cache id: %d\n", id);
+ DEBUG_WARN( "invalid glyph cache id: %d\n", id);
return NULL;
}
if (index > glyphCache->glyphCache[id].number)
{
- fprintf(stderr, "index %d out of range for cache id: %d\n", index, id);
+ DEBUG_WARN( "index %d out of range for cache id: %d\n", index, id);
return NULL;
}
glyph = glyphCache->glyphCache[id].entries[index];
if (!glyph)
- fprintf(stderr, "no glyph found at cache index: %d in cache id: %d\n", index, id);
+ DEBUG_WARN( "no glyph found at cache index: %d in cache id: %d\n", index, id);
return glyph;
}
if (id > 9)
{
- fprintf(stderr, "invalid glyph cache id: %d\n", id);
+ DEBUG_WARN( "invalid glyph cache id: %d\n", id);
return;
}
if (index > glyphCache->glyphCache[id].number)
{
- fprintf(stderr, "invalid glyph cache index: %d in cache id: %d\n", index, id);
+ DEBUG_WARN( "invalid glyph cache index: %d in cache id: %d\n", index, id);
return;
}
if (index > 255)
{
- fprintf(stderr, "invalid glyph cache fragment index: %d\n", index);
+ DEBUG_WARN( "invalid glyph cache fragment index: %d\n", index);
return NULL;
}
WLog_Print(glyphCache->log, WLOG_DEBUG, "GlyphCacheFragmentGet: index: %d size: %d", index, *size);
if (!fragment)
- fprintf(stderr, "invalid glyph fragment at index:%d\n", index);
+ DEBUG_WARN( "invalid glyph fragment at index:%d\n", index);
return fragment;
}
if (index > 255)
{
- fprintf(stderr, "invalid glyph cache fragment index: %d\n", index);
+ DEBUG_WARN( "invalid glyph cache fragment index: %d\n", index);
return;
}
#include <freerdp/freerdp.h>
#include <winpr/stream.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/cache/nine_grid.h>
void update_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid)
if (index >= nine_grid->maxEntries)
{
- fprintf(stderr, "invalid NineGrid index: 0x%04X\n", index);
+ DEBUG_WARN( "invalid NineGrid index: 0x%04X\n", index);
return NULL;
}
if (entry == NULL)
{
- fprintf(stderr, "invalid NineGrid at index: 0x%04X\n", index);
+ DEBUG_WARN( "invalid NineGrid at index: 0x%04X\n", index);
return NULL;
}
if (index >= nine_grid->maxEntries)
{
- fprintf(stderr, "invalid NineGrid index: 0x%04X\n", index);
+ DEBUG_WARN( "invalid NineGrid index: 0x%04X\n", index);
return;
}
#include <winpr/stream.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/cache/offscreen.h>
void update_gdi_create_offscreen_bitmap(rdpContext* context, CREATE_OFFSCREEN_BITMAP_ORDER* createOffscreenBitmap)
if (index >= offscreenCache->maxEntries)
{
- fprintf(stderr, "invalid offscreen bitmap index: 0x%04X\n", index);
+ DEBUG_WARN( "invalid offscreen bitmap index: 0x%04X\n", index);
return NULL;
}
if (!bitmap)
{
- fprintf(stderr, "invalid offscreen bitmap at index: 0x%04X\n", index);
+ DEBUG_WARN( "invalid offscreen bitmap at index: 0x%04X\n", index);
return NULL;
}
{
if (index >= offscreenCache->maxEntries)
{
- fprintf(stderr, "invalid offscreen bitmap index: 0x%04X\n", index);
+ DEBUG_WARN( "invalid offscreen bitmap index: 0x%04X\n", index);
return;
}
if (index >= offscreenCache->maxEntries)
{
- fprintf(stderr, "invalid offscreen bitmap index (delete): 0x%04X\n", index);
+ DEBUG_WARN( "invalid offscreen bitmap index (delete): 0x%04X\n", index);
return;
}
#include <winpr/crt.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/cache/palette.h>
static void update_gdi_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE_ORDER* cacheColorTable)
if (index >= paletteCache->maxEntries)
{
- fprintf(stderr, "invalid color table index: 0x%04X\n", index);
+ DEBUG_WARN( "invalid color table index: 0x%04X\n", index);
return NULL;
}
if (!entry)
{
- fprintf(stderr, "invalid color table at index: 0x%04X\n", index);
+ DEBUG_WARN( "invalid color table at index: 0x%04X\n", index);
return NULL;
}
{
if (index >= paletteCache->maxEntries)
{
- fprintf(stderr, "invalid color table index: 0x%04X\n", index);
+ DEBUG_WARN( "invalid color table index: 0x%04X\n", index);
if (entry)
free(entry);
#include <winpr/stream.h>
#include <freerdp/cache/pointer.h>
+#include <freerdp/utils/debug.h>
void update_pointer_position(rdpContext* context, POINTER_POSITION_UPDATE* pointer_position)
{
break;
default:
- fprintf(stderr, "Unknown system pointer type (0x%08X)\n", pointer_system->type);
+ DEBUG_WARN( "Unknown system pointer type (0x%08X)\n", pointer_system->type);
break;
}
}
if (index >= pointer_cache->cacheSize)
{
- fprintf(stderr, "invalid pointer index:%d\n", index);
+ DEBUG_WARN( "invalid pointer index:%d\n", index);
return NULL;
}
if (index >= pointer_cache->cacheSize)
{
- fprintf(stderr, "invalid pointer index:%d\n", index);
+ DEBUG_WARN( "invalid pointer index:%d\n", index);
return;
}
color.c
audio.c
planar.c
- planar.h
- bitmap_decode.c
- bitmap_encode.c
+ bitmap.c
+ interleaved.c
+ progressive.c
rfx_bitstream.h
rfx_constants.h
rfx_decode.c
set(FREERDP_OPENH264_LIBS ${OPENH264_LIBRARIES})
endif()
+if(WITH_LIBAVCODEC)
+ add_definitions(-DWITH_LIBAVCODEC)
+ find_library(LIBAVCODEC_LIB avcodec)
+ find_library(LIBAVUTIL_LIB avutil)
+ set(FREERDP_LIBAVCODEC_LIBS ${LIBAVCODEC_LIB} ${LIBAVUTIL_LIB})
+endif()
+
+
add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT"
MONOLITHIC ${MONOLITHIC_BUILD}
SOURCES ${${MODULE_PREFIX}_SRCS}
set(${MODULE_PREFIX}_LIBS
${FREERDP_JPEG_LIBS}
- ${FREERDP_OPENH264_LIBS})
+ ${FREERDP_OPENH264_LIBS}
+ ${FREERDP_LIBAVCODEC_LIBS})
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL
#include <winpr/crt.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/codec/audio.h>
UINT32 rdpsnd_compute_audio_time_length(AUDIO_FORMAT* format, int size)
}
else
{
- fprintf(stderr, "rdpsnd_compute_audio_time_length: invalid WAVE_FORMAT_GSM610 format\n");
+ DEBUG_WARN( "rdpsnd_compute_audio_time_length: invalid WAVE_FORMAT_GSM610 format\n");
}
}
else
{
- fprintf(stderr, "rdpsnd_compute_audio_time_length: unknown format %d\n", format->wFormatTag);
+ DEBUG_WARN( "rdpsnd_compute_audio_time_length: unknown format %d\n", format->wFormatTag);
}
}
void rdpsnd_print_audio_format(AUDIO_FORMAT* format)
{
- fprintf(stderr, "%s:\t wFormatTag: 0x%04X nChannels: %d nSamplesPerSec: %d nAvgBytesPerSec: %d "
+ DEBUG_WARN( "%s:\t wFormatTag: 0x%04X nChannels: %d nSamplesPerSec: %d nAvgBytesPerSec: %d "
"nBlockAlign: %d wBitsPerSample: %d cbSize: %d\n",
rdpsnd_get_audio_tag_string(format->wFormatTag), format->wFormatTag,
format->nChannels, format->nSamplesPerSec, format->nAvgBytesPerSec,
if (formats)
{
- fprintf(stderr, "AUDIO_FORMATS (%d) =\n{\n", count);
+ DEBUG_WARN( "AUDIO_FORMATS (%d) =\n{\n", count);
for (index = 0; index < (int) count; index++)
{
format = &formats[index];
- fprintf(stderr, "\t");
+ DEBUG_WARN( "\t");
rdpsnd_print_audio_format(format);
}
- fprintf(stderr, "}\n");
+ DEBUG_WARN( "}\n");
}
}
#endif
#include <freerdp/codec/bitmap.h>
+#include <freerdp/codec/planar.h>
#define GETPIXEL16(d, x, y, w) (*(((unsigned short*)d) + ((y) * (w) + (x))))
#define GETPIXEL32(d, x, y, w) (*(((unsigned int*)d) + ((y) * (w) + (x))))
if (!glyphData)
return -1010;
- if ((nWidth * nHeight) > glyphEntry->count)
+ if ((nWidth * nHeight) > (int) glyphEntry->count)
return -1011;
nSrcStep = nWidth * 4;
pSrcPixel8 = glyphData;
pDstPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
- for (y = 0; y < nHeight; y++)
+ for (y = 0; y < (UINT32) nHeight; y++)
{
CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep);
pSrcPixel8 += nSrcStep;
subcodecByteCount = *((UINT32*) &pSrcData[offset + 8]);
offset += 12;
- //printf("residualByteCount: %d bandsByteCount: %d subcodecByteCount: %d\n",
+ //DEBUG_MSG("residualByteCount: %d bandsByteCount: %d subcodecByteCount: %d\n",
// residualByteCount, bandsByteCount, subcodecByteCount);
if (residualByteCount > 0)
suboffset = 0;
residualData = &pSrcData[offset];
- if ((nWidth * nHeight * 4) > clear->TempSize)
+ if ((nWidth * nHeight * 4) > (int) clear->TempSize)
{
clear->TempSize = (nWidth * nHeight * 4);
clear->TempBuffer = (BYTE*) realloc(clear->TempBuffer, clear->TempSize);
if (pixelIndex != pixelCount)
return -1019;
- for (y = 0; y < nHeight; y++)
+ for (y = 0; y < (UINT32) nHeight; y++)
{
CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep);
pSrcPixel8 += nSrcStep;
subcodecId = subcodecs[suboffset + 12];
suboffset += 13;
- //printf("bitmapDataByteCount: %d subcodecByteCount: %d suboffset: %d subCodecId: %d\n",
+ //DEBUG_MSG("bitmapDataByteCount: %d subcodecByteCount: %d suboffset: %d subCodecId: %d\n",
// bitmapDataByteCount, subcodecByteCount, suboffset, subcodecId);
if ((subcodecByteCount - suboffset) < bitmapDataByteCount)
if (height > nHeight)
return -1043;
- if ((width * height * 4) > clear->TempSize)
+ if (((UINT32) (width * height * 4)) > clear->TempSize)
{
clear->TempSize = (width * height * 4);
clear->TempBuffer = (BYTE*) realloc(clear->TempBuffer, clear->TempSize);
pDstPixel8 = glyphData;
pSrcPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
- for (y = 0; y < nHeight; y++)
+ for (y = 0; y < (UINT32) nHeight; y++)
{
CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep);
pDstPixel8 += nSrcStep;
#include <winpr/print.h>
#include <winpr/bitstream.h>
-#include <freerdp/codec/color.h>
+#include <freerdp/primitives.h>
#include <freerdp/codec/h264.h>
-#define USE_GRAY_SCALE 0
-#define USE_UPCONVERT 0
+/**
+ * Dummy subsystem
+ */
-static BYTE clip(int x)
+static int dummy_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize)
{
- if (x < 0) return 0;
- if (x > 255) return 255;
- return (BYTE)x;
+ return -1;
}
-static UINT32 YUV_to_RGB(BYTE Y, BYTE U, BYTE V)
+static void dummy_uninit(H264_CONTEXT* h264)
{
- BYTE R, G, B;
-#if USE_GRAY_SCALE
- /*
- * Displays the Y plane as a gray-scale image.
- */
- R = Y;
- G = Y;
- B = Y;
-#else
- int C, D, E;
+}
-#if 0
- /*
- * Documented colorspace conversion from YUV to RGB.
- * See http://msdn.microsoft.com/en-us/library/ms893078.aspx
- */
+static BOOL dummy_init(H264_CONTEXT* h264)
+{
+ return TRUE;
+}
- C = Y - 16;
- D = U - 128;
- E = V - 128;
+static H264_CONTEXT_SUBSYSTEM g_Subsystem_dummy =
+{
+ "dummy",
+ dummy_init,
+ dummy_uninit,
+ dummy_decompress
+};
- R = clip(( 298 * C + 409 * E + 128) >> 8);
- G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8);
- B = clip(( 298 * C + 516 * D + 128) >> 8);
-#endif
+/**
+ * OpenH264 subsystem
+ */
+
+#ifdef WITH_OPENH264
+
+#include "wels/codec_def.h"
+#include "wels/codec_api.h"
+
+struct _H264_CONTEXT_OPENH264
+{
+ ISVCDecoder* pDecoder;
+};
+typedef struct _H264_CONTEXT_OPENH264 H264_CONTEXT_OPENH264;
+
+static BOOL g_openh264_trace_enabled = FALSE;
+
+static void openh264_trace_callback(H264_CONTEXT* h264, int level, const char* message)
+{
+ printf("%d - %s\n", level, message);
+}
+
+static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize)
+{
+ DECODING_STATE state;
+ SBufferInfo sBufferInfo;
+ SSysMEMBuffer* pSystemBuffer;
+ H264_CONTEXT_OPENH264* sys = (H264_CONTEXT_OPENH264*) h264->pSystemData;
+
+ if (!sys->pDecoder)
+ return -1;
-#if 0
/*
- * These coefficients produce better results.
- * See http://www.microchip.com/forums/m599060.aspx
+ * Decompress the image. The RDP host only seems to send I420 format.
*/
- C = Y;
- D = U - 128;
- E = V - 128;
+ h264->pYUVData[0] = NULL;
+ h264->pYUVData[1] = NULL;
+ h264->pYUVData[2] = NULL;
- R = clip(( 256 * C + 359 * E + 128) >> 8);
- G = clip(( 256 * C - 88 * D - 183 * E + 128) >> 8);
- B = clip(( 256 * C + 454 * D + 128) >> 8);
-#endif
+ ZeroMemory(&sBufferInfo, sizeof(sBufferInfo));
-#if 1
- /*
- * These coefficients produce excellent results.
+ state = (*sys->pDecoder)->DecodeFrame2(
+ sys->pDecoder,
+ pSrcData,
+ SrcSize,
+ h264->pYUVData,
+ &sBufferInfo);
+
+ /**
+ * Calling DecodeFrame2 twice apparently works around Openh264 issue #1136:
+ * https://github.com/cisco/openh264/issues/1136
+ *
+ * This is a hack, but it works and it is only necessary for the first frame.
*/
- C = Y;
- D = U - 128;
- E = V - 128;
+ if (sBufferInfo.iBufferStatus != 1)
+ state = (*sys->pDecoder)->DecodeFrame2(sys->pDecoder, NULL, 0, h264->pYUVData, &sBufferInfo);
- R = clip(( 256 * C + 403 * E + 128) >> 8);
- G = clip(( 256 * C - 48 * D - 120 * E + 128) >> 8);
- B = clip(( 256 * C + 475 * D + 128) >> 8);
-#endif
+ pSystemBuffer = &sBufferInfo.UsrData.sSystemBuffer;
+#if 0
+ printf("h264_decompress: state=%u, pYUVData=[%p,%p,%p], bufferStatus=%d, width=%d, height=%d, format=%d, stride=[%d,%d]\n",
+ state, h264->pYUVData[0], h264->pYUVData[1], h264->pYUVData[2], sBufferInfo.iBufferStatus,
+ pSystemBuffer->iWidth, pSystemBuffer->iHeight, pSystemBuffer->iFormat,
+ pSystemBuffer->iStride[0], pSystemBuffer->iStride[1]);
#endif
- return RGB32(R, G, B);
-}
+ if (state != 0)
+ return -1;
-#if USE_UPCONVERT
-static BYTE* convert_420_to_444(BYTE* chroma420, int chroma420Width, int chroma420Height, int chroma420Stride)
-{
- BYTE *chroma444, *src, *dst;
- int chroma444Width;
- int chroma444Height;
- int i, j;
+ if (sBufferInfo.iBufferStatus != 1)
+ return -2;
- chroma444Width = chroma420Width * 2;
- chroma444Height = chroma420Height * 2;
+ if (pSystemBuffer->iFormat != videoFormatI420)
+ return -1;
- chroma444 = (BYTE*) malloc(chroma444Width * chroma444Height);
+ if (!h264->pYUVData[0] || !h264->pYUVData[1] || !h264->pYUVData[2])
+ return -1;
- if (!chroma444)
- return NULL;
+ h264->iStride[0] = pSystemBuffer->iStride[0];
+ h264->iStride[1] = pSystemBuffer->iStride[1];
+ h264->iStride[2] = pSystemBuffer->iStride[1];
- /* Upconvert in the horizontal direction. */
+ h264->width = pSystemBuffer->iWidth;
+ h264->height = pSystemBuffer->iHeight;
- for (j = 0; j < chroma420Height; j++)
+ return 1;
+}
+
+static void openh264_uninit(H264_CONTEXT* h264)
+{
+ H264_CONTEXT_OPENH264* sys = (H264_CONTEXT_OPENH264*) h264->pSystemData;
+
+ if (sys)
{
- src = chroma420 + j * chroma420Stride;
- dst = chroma444 + j * chroma444Width;
- dst[0] = src[0];
- for (i = 1; i < chroma420Width; i++)
+ if (sys->pDecoder)
{
- dst[2*i-1] = (3 * src[i-1] + src[i] + 2) >> 2;
- dst[2*i] = (src[i-1] + 3 * src[i] + 2) >> 2;
+ (*sys->pDecoder)->Uninitialize(sys->pDecoder);
+ WelsDestroyDecoder(sys->pDecoder);
+ sys->pDecoder = NULL;
}
- dst[chroma444Width-1] = src[chroma420Width-1];
+
+ free(sys);
+ h264->pSystemData = NULL;
+ }
+}
+
+static BOOL openh264_init(H264_CONTEXT* h264)
+{
+ long status;
+ SDecodingParam sDecParam;
+ H264_CONTEXT_OPENH264* sys;
+ static int traceLevel = WELS_LOG_DEBUG;
+ static EVideoFormatType videoFormat = videoFormatI420;
+ static WelsTraceCallback traceCallback = (WelsTraceCallback) openh264_trace_callback;
+
+ sys = (H264_CONTEXT_OPENH264*) calloc(1, sizeof(H264_CONTEXT_OPENH264));
+
+ if (!sys)
+ {
+ goto EXCEPTION;
}
- /* Upconvert in the vertical direction (in-place, bottom-up). */
+ h264->pSystemData = (void*) sys;
+
+ WelsCreateDecoder(&sys->pDecoder);
- for (i = 0; i < chroma444Width; i++)
+ if (!sys->pDecoder)
{
- src = chroma444 + i + (chroma420Height-2) * chroma444Width;
- dst = chroma444 + i + (2*(chroma420Height-2)+1) * chroma444Width;
- dst[2*chroma444Width] = src[chroma444Width];
- for (j = chroma420Height - 2; j >= 0; j--)
+ printf("Failed to create OpenH264 decoder\n");
+ goto EXCEPTION;
+ }
+
+ ZeroMemory(&sDecParam, sizeof(sDecParam));
+ sDecParam.iOutputColorFormat = videoFormatI420;
+ sDecParam.uiEcActiveFlag = 1;
+ sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
+
+ status = (*sys->pDecoder)->Initialize(sys->pDecoder, &sDecParam);
+
+ if (status != 0)
+ {
+ printf("Failed to initialize OpenH264 decoder (status=%ld)\n", status);
+ goto EXCEPTION;
+ }
+
+ status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_DATAFORMAT, &videoFormat);
+
+ if (status != 0)
+ {
+ printf("Failed to set data format option on OpenH264 decoder (status=%ld)\n", status);
+ }
+
+ if (g_openh264_trace_enabled)
+ {
+ status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_TRACE_LEVEL, &traceLevel);
+
+ if (status != 0)
+ {
+ printf("Failed to set trace level option on OpenH264 decoder (status=%ld)\n", status);
+ }
+
+ status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_TRACE_CALLBACK, &traceCallback);
+
+ if (status != 0)
+ {
+ printf("Failed to set trace callback option on OpenH264 decoder (status=%ld)\n", status);
+ }
+
+ status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_TRACE_CALLBACK_CONTEXT, &h264);
+
+ if (status != 0)
{
- dst[chroma444Width] = (src[0] + 3 * src[chroma444Width] + 2) >> 2;
- dst[0] = (3 * src[0] + src[chroma444Width] + 2) >> 2;
- dst -= 2 * chroma444Width;
- src -= chroma444Width;
+ printf("Failed to set trace callback context option on OpenH264 decoder (status=%ld)\n", status);
}
}
- return chroma444;
+ return TRUE;
+
+EXCEPTION:
+ openh264_uninit(h264);
+
+ return FALSE;
}
+
+static H264_CONTEXT_SUBSYSTEM g_Subsystem_OpenH264 =
+{
+ "OpenH264",
+ openh264_init,
+ openh264_uninit,
+ openh264_decompress
+};
+
#endif
-int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
- BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight)
+/**
+ * libavcodec subsystem
+ */
+
+#ifdef WITH_LIBAVCODEC
+
+#include <libavcodec/avcodec.h>
+#include <libavutil/avutil.h>
+
+struct _H264_CONTEXT_LIBAVCODEC
{
-#ifdef WITH_OPENH264
- DECODING_STATE state;
- SBufferInfo sBufferInfo;
- SSysMEMBuffer* pSystemBuffer;
- UINT32 UncompressedSize;
- BYTE* pDstData;
- BYTE* pYUVData[3];
- BYTE* pY;
- BYTE* pU;
- BYTE* pV;
- int Y, U, V;
- int i, j;
-
- if (!h264 || !h264->pDecoder)
+ AVCodec* codec;
+ AVCodecContext* codecContext;
+ AVCodecParserContext* codecParser;
+ AVFrame* videoFrame;
+};
+typedef struct _H264_CONTEXT_LIBAVCODEC H264_CONTEXT_LIBAVCODEC;
+
+static int libavcodec_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize)
+{
+ int status;
+ int gotFrame = 0;
+ AVPacket packet;
+ H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*) h264->pSystemData;
+
+ av_init_packet(&packet);
+
+ packet.data = pSrcData;
+ packet.size = SrcSize;
+
+ status = avcodec_decode_video2(sys->codecContext, sys->videoFrame, &gotFrame, &packet);
+
+ if (status < 0)
+ {
+ printf("Failed to decode video frame (status=%d)\n", status);
return -1;
+ }
#if 0
- printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, DstFormat=%lx, nDstStep=%d, nXDst=%d, nYDst=%d, nWidth=%d, nHeight=%d)\n",
- pSrcData, SrcSize, *ppDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight);
+ printf("libavcodec_decompress: frame decoded (status=%d, gotFrame=%d, width=%d, height=%d, Y=[%p,%d], U=[%p,%d], V=[%p,%d])\n",
+ status, gotFrame, sys->videoFrame->width, sys->videoFrame->height,
+ sys->videoFrame->data[0], sys->videoFrame->linesize[0],
+ sys->videoFrame->data[1], sys->videoFrame->linesize[1],
+ sys->videoFrame->data[2], sys->videoFrame->linesize[2]);
#endif
- /* Allocate a destination buffer (if needed). */
+ if (gotFrame)
+ {
+ h264->pYUVData[0] = sys->videoFrame->data[0];
+ h264->pYUVData[1] = sys->videoFrame->data[1];
+ h264->pYUVData[2] = sys->videoFrame->data[2];
- UncompressedSize = nWidth * nHeight * 4;
+ h264->iStride[0] = sys->videoFrame->linesize[0];
+ h264->iStride[1] = sys->videoFrame->linesize[1];
+ h264->iStride[2] = sys->videoFrame->linesize[2];
- if (UncompressedSize == 0)
- return -1;
+ h264->width = sys->videoFrame->width;
+ h264->height = sys->videoFrame->height;
+ }
+ else
+ return -2;
- pDstData = *ppDstData;
+ return 1;
+}
+
+static void libavcodec_uninit(H264_CONTEXT* h264)
+{
+ H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*) h264->pSystemData;
- if (!pDstData)
+ if (!sys)
+ return;
+
+ if (sys->videoFrame)
{
- pDstData = (BYTE*) malloc(UncompressedSize);
+ av_free(sys->videoFrame);
+ }
- if (!pDstData)
- return -1;
+ if (sys->codecParser)
+ {
+ av_parser_close(sys->codecParser);
+ }
- *ppDstData = pDstData;
+ if (sys->codecContext)
+ {
+ avcodec_close(sys->codecContext);
+ av_free(sys->codecContext);
}
- /*
- * Decompress the image. The RDP host only seems to send I420 format.
- */
+ free(sys);
+ h264->pSystemData = NULL;
+}
- pYUVData[0] = NULL;
- pYUVData[1] = NULL;
- pYUVData[2] = NULL;
+static BOOL libavcodec_init(H264_CONTEXT* h264)
+{
+ H264_CONTEXT_LIBAVCODEC* sys;
- ZeroMemory(&sBufferInfo, sizeof(sBufferInfo));
+ sys = (H264_CONTEXT_LIBAVCODEC*) calloc(1, sizeof(H264_CONTEXT_LIBAVCODEC));
- state = (*h264->pDecoder)->DecodeFrame2(
- h264->pDecoder,
- pSrcData,
- SrcSize,
- pYUVData,
- &sBufferInfo);
+ if (!sys)
+ {
+ goto EXCEPTION;
+ }
- pSystemBuffer = &sBufferInfo.UsrData.sSystemBuffer;
+ h264->pSystemData = (void*) sys;
+
+ avcodec_register_all();
+
+ sys->codec = avcodec_find_decoder(CODEC_ID_H264);
+
+ if (!sys->codec)
+ {
+ printf("Failed to find libav H.264 codec\n");
+ goto EXCEPTION;
+ }
+
+ sys->codecContext = avcodec_alloc_context3(sys->codec);
+
+ if (!sys->codecContext)
+ {
+ printf("Failed to allocate libav codec context\n");
+ goto EXCEPTION;
+ }
+
+ if (sys->codec->capabilities & CODEC_CAP_TRUNCATED)
+ {
+ sys->codecContext->flags |= CODEC_FLAG_TRUNCATED;
+ }
+
+ if (avcodec_open2(sys->codecContext, sys->codec, NULL) < 0)
+ {
+ printf("Failed to open libav codec\n");
+ goto EXCEPTION;
+ }
+
+ sys->codecParser = av_parser_init(CODEC_ID_H264);
+
+ if (!sys->codecParser)
+ {
+ printf("Failed to initialize libav parser\n");
+ goto EXCEPTION;
+ }
+
+ sys->videoFrame = avcodec_alloc_frame();
+
+ if (!sys->videoFrame)
+ {
+ printf("Failed to allocate libav frame\n");
+ goto EXCEPTION;
+ }
+
+ return TRUE;
+
+EXCEPTION:
+ libavcodec_uninit(h264);
+
+ return FALSE;
+}
+
+static H264_CONTEXT_SUBSYSTEM g_Subsystem_libavcodec =
+{
+ "libavcodec",
+ libavcodec_init,
+ libavcodec_uninit,
+ libavcodec_decompress
+};
-#if 0
- printf("h264_decompress: state=%u, pYUVData=[%p,%p,%p], bufferStatus=%d, width=%d, height=%d, format=%d, stride=[%d,%d]\n",
- state, pYUVData[0], pYUVData[1], pYUVData[2], sBufferInfo.iBufferStatus,
- pSystemBuffer->iWidth, pSystemBuffer->iHeight, pSystemBuffer->iFormat,
- pSystemBuffer->iStride[0], pSystemBuffer->iStride[1]);
#endif
- if (state != 0)
+int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
+ BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstHeight, RDPGFX_RECT16* regionRects, int numRegionRects)
+{
+ int index;
+ int status;
+ int* iStride;
+ BYTE* pDstData;
+ BYTE* pDstPoint;
+ prim_size_t roi;
+ BYTE** pYUVData;
+ int width, height;
+ BYTE* pYUVPoint[3];
+ RDPGFX_RECT16* rect;
+ int UncompressedSize;
+ primitives_t *prims = primitives_get();
+
+ if (!h264)
return -1;
- if (!pYUVData[0] || !pYUVData[1] || !pYUVData[2])
- return -1;
+#if 0
+ printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, nDstStep=%d, nDstHeight=%d, numRegionRects=%d\n",
+ pSrcData, SrcSize, *ppDstData, nDstStep, nDstHeight, numRegionRects);
+#endif
- if (sBufferInfo.iBufferStatus != 1)
+ if (!(pDstData = *ppDstData))
return -1;
- if (pSystemBuffer->iFormat != videoFormatI420)
- return -1;
+ if ((status = h264->subsystem->Decompress(h264, pSrcData, SrcSize)) < 0)
+ return status;
- /* Convert I420 (same as IYUV) to XRGB. */
+ UncompressedSize = h264->width * h264->height * 4;
- pY = pYUVData[0];
- pU = pYUVData[1];
- pV = pYUVData[2];
+ if (UncompressedSize > (nDstStep * nDstHeight))
+ return -1;
-#if USE_UPCONVERT
- /* Convert 4:2:0 YUV to 4:4:4 YUV. */
- pU = convert_420_to_444(pU, pSystemBuffer->iWidth / 2, pSystemBuffer->iHeight / 2, pSystemBuffer->iStride[1]);
- pV = convert_420_to_444(pV, pSystemBuffer->iWidth / 2, pSystemBuffer->iHeight / 2, pSystemBuffer->iStride[1]);
-#endif
+ pYUVData = h264->pYUVData;
+ iStride = h264->iStride;
- for (j = 0; j < nHeight; j++)
+ for (index = 0; index < numRegionRects; index++)
{
- BYTE *pXRGB = pDstData + ((nYDst + j) * nDstStep) + (nXDst * 4);
- int y = nYDst + j;
+ rect = &(regionRects[index]);
- for (i = 0; i < nWidth; i++)
- {
- int x = nXDst + i;
-
- Y = pY[(y * pSystemBuffer->iStride[0]) + x];
-#if USE_UPCONVERT
- U = pU[(y * pSystemBuffer->iWidth) + x];
- V = pV[(y * pSystemBuffer->iWidth) + x];
-#else
- U = pU[(y/2) * pSystemBuffer->iStride[1] + (x/2)];
- V = pV[(y/2) * pSystemBuffer->iStride[1] + (x/2)];
-#endif
-
- *(UINT32*)pXRGB = YUV_to_RGB(Y, U, V);
+ width = rect->right - rect->left;
+ height = rect->bottom - rect->top;
- pXRGB += 4;
- }
- }
+ pDstPoint = pDstData + rect->top * nDstStep + rect->left * 4;
+ pYUVPoint[0] = pYUVData[0] + rect->top * iStride[0] + rect->left;
-#if USE_UPCONVERT
- free(pU);
- free(pV);
-#endif
+ pYUVPoint[1] = pYUVData[1] + rect->top/2 * iStride[1] + rect->left/2;
+ pYUVPoint[2] = pYUVData[2] + rect->top/2 * iStride[2] + rect->left/2;
+
+#if 0
+ printf("regionRect: x: %d y: %d width: %d height: %d\n",
+ rect->left, rect->top, width, height);
#endif
+ roi.width = width;
+ roi.height = height;
+
+ prims->YUV420ToRGB_8u_P3AC4R((const BYTE**) pYUVPoint, iStride, pDstPoint, nDstStep, &roi);
+ }
+
return 1;
}
return 1;
}
-void h264_context_reset(H264_CONTEXT* h264)
+BOOL h264_context_init(H264_CONTEXT* h264)
{
+#ifdef WITH_LIBAVCODEC
+ if (g_Subsystem_libavcodec.Init(h264))
+ {
+ h264->subsystem = &g_Subsystem_libavcodec;
+ return TRUE;
+ }
+#endif
+#ifdef WITH_OPENH264
+ if (g_Subsystem_OpenH264.Init(h264))
+ {
+ h264->subsystem = &g_Subsystem_OpenH264;
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
}
H264_CONTEXT* h264_context_new(BOOL Compressor)
{
h264->Compressor = Compressor;
-#ifdef WITH_OPENH264
+ h264->subsystem = &g_Subsystem_dummy;
+
+ if (!h264_context_init(h264))
{
- static EVideoFormatType videoFormat = videoFormatI420;
-
- SDecodingParam sDecParam;
- long status;
-
- WelsCreateDecoder(&h264->pDecoder);
-
- if (!h264->pDecoder)
- {
- printf("Failed to create OpenH264 decoder\n");
- goto EXCEPTION;
- }
-
- ZeroMemory(&sDecParam, sizeof(sDecParam));
- sDecParam.iOutputColorFormat = videoFormatARGB;
- status = (*h264->pDecoder)->Initialize(h264->pDecoder, &sDecParam);
- if (status != 0)
- {
- printf("Failed to initialize OpenH264 decoder (status=%ld)\n", status);
- goto EXCEPTION;
- }
-
- status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_DATAFORMAT, &videoFormat);
- if (status != 0)
- {
- printf("Failed to set data format option on OpenH264 decoder (status=%ld)\n", status);
- }
+ free(h264);
+ return NULL;
}
-#endif
-
- h264_context_reset(h264);
}
return h264;
-
-EXCEPTION:
-#ifdef WITH_OPENH264
- if (h264->pDecoder)
- {
- WelsDestroyDecoder(h264->pDecoder);
- }
-#endif
-
- free(h264);
-
- return NULL;
}
void h264_context_free(H264_CONTEXT* h264)
{
if (h264)
{
-#ifdef WITH_OPENH264
- if (h264->pDecoder)
- {
- (*h264->pDecoder)->Uninitialize(h264->pDecoder);
- WelsDestroyDecoder(h264->pDecoder);
- }
-#endif
+ h264->subsystem->Uninit(h264);
free(h264);
}
/**
* FreeRDP: A Remote Desktop Protocol Implementation
- * Bitmap Decompression
+ * Interleaved RLE Bitmap Codec
*
- * Copyright 2011 Jay Sorg <jay.sorg@gmail.com>
+ * 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.
#include "config.h"
#endif
-#include <winpr/crt.h>
-#include <winpr/stream.h>
-
-#include "planar.h"
-
-#include <freerdp/codec/color.h>
-
-#include <freerdp/codec/bitmap.h>
+#include <freerdp/codec/interleaved.h>
/*
RLE Compressed Bitmap Stream (RLE_BITMAP_STREAM)
#define RLEEXTRA
#include "include/bitmap.c"
-/**
- * bitmap decompression routine
- */
-BOOL bitmap_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size, int srcBpp, int dstBpp)
+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;
- BYTE* TmpBfr;
+ BOOL vFlip;
+ int scanline;
BYTE* pDstData;
+ UINT32 BufferSize;
+ int dstBitsPerPixel;
+ int dstBytesPerPixel;
- if (srcBpp == 16 && dstBpp == 16)
- {
- TmpBfr = (BYTE*) _aligned_malloc(width * height * 2, 16);
- RleDecompress16to16(srcData, size, TmpBfr, width * 2, width, height);
- freerdp_bitmap_flip(TmpBfr, dstData, width * 2, height);
- _aligned_free(TmpBfr);
- }
- else if (srcBpp == 32 && dstBpp == 32)
+ pDstData = *ppDstData;
+ dstBitsPerPixel = FREERDP_PIXEL_FORMAT_DEPTH(DstFormat);
+ dstBytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(DstFormat) / 8);
+ vFlip = FREERDP_PIXEL_FORMAT_FLIP(DstFormat) ? TRUE : FALSE;
+
+ if (!interleaved)
+ return -1;
+
+ if (bpp == 24)
{
- pDstData = dstData;
+ scanline = nWidth * 3;
+ BufferSize = scanline * nHeight;
+
+ if (BufferSize > interleaved->FlipSize)
+ {
+ interleaved->FlipBuffer = _aligned_realloc(interleaved->FlipBuffer, BufferSize, 16);
+ interleaved->FlipSize = BufferSize;
+ }
- status = planar_decompress(NULL, srcData, size, &pDstData,
- PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height);
+ if (!interleaved->FlipBuffer)
+ return -1;
- if (status < 0)
- return FALSE;
+ RleDecompress24to24(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight);
+ freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight);
}
- else if (srcBpp == 15 && dstBpp == 15)
+ else if ((bpp == 16) || (bpp == 15))
{
- TmpBfr = (BYTE*) _aligned_malloc(width * height * 2, 16);
- RleDecompress16to16(srcData, size, TmpBfr, width * 2, width, height);
- freerdp_bitmap_flip(TmpBfr, dstData, width * 2, height);
- _aligned_free(TmpBfr);
+ scanline = nWidth * 2;
+ BufferSize = scanline * nHeight;
+
+ if (BufferSize > interleaved->FlipSize)
+ {
+ interleaved->FlipBuffer = _aligned_realloc(interleaved->FlipBuffer, BufferSize, 16);
+ interleaved->FlipSize = BufferSize;
+ }
+
+ if (!interleaved->FlipBuffer)
+ return -1;
+
+ RleDecompress16to16(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight);
+ freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight);
}
- else if (srcBpp == 8 && dstBpp == 8)
+ else if (bpp == 8)
{
- TmpBfr = (BYTE*) _aligned_malloc(width * height, 16);
- RleDecompress8to8(srcData, size, TmpBfr, width, width, height);
- freerdp_bitmap_flip(TmpBfr, dstData, width, height);
- _aligned_free(TmpBfr);
+ scanline = nWidth;
+ BufferSize = scanline * nHeight;
+
+ if (BufferSize > interleaved->FlipSize)
+ {
+ interleaved->FlipBuffer = _aligned_realloc(interleaved->FlipBuffer, BufferSize, 16);
+ interleaved->FlipSize = BufferSize;
+ }
+
+ if (!interleaved->FlipBuffer)
+ return -1;
+
+ RleDecompress8to8(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight);
+ freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight);
}
- else if (srcBpp == 24 && dstBpp == 24)
+ else
{
- TmpBfr = (BYTE*) _aligned_malloc(width * height * 3, 16);
- RleDecompress24to24(srcData, size, TmpBfr, width * 3, width, height);
- freerdp_bitmap_flip(TmpBfr, dstData, width * 3, height);
- _aligned_free(TmpBfr);
+ return -1;
}
- else
+
+ return 1;
+}
+
+BITMAP_INTERLEAVED_CONTEXT* bitmap_interleaved_context_new(BOOL Compressor)
+{
+ BITMAP_INTERLEAVED_CONTEXT* interleaved;
+
+ interleaved = (BITMAP_INTERLEAVED_CONTEXT*) calloc(1, sizeof(BITMAP_INTERLEAVED_CONTEXT));
+
+ if (interleaved)
{
- return FALSE;
+ interleaved->FlipSize = 64 * 64 * 3;
+ interleaved->FlipBuffer = _aligned_malloc(interleaved->FlipSize, 16);
}
- return TRUE;
+ return interleaved;
+}
+
+void bitmap_interleaved_context_free(BITMAP_INTERLEAVED_CONTEXT* interleaved)
+{
+ if (!interleaved)
+ return;
+
+ _aligned_free(interleaved->FlipBuffer);
+
+ free(interleaved);
}
}
#ifdef DEBUG_MPPC
- printf("<%d,%d>\n", (int) CopyOffset, (int) LengthOfMatch);
+ DEBUG_MSG("<%d,%d>\n", (int) CopyOffset, (int) LengthOfMatch);
#endif
SrcPtr = HistoryPtr - CopyOffset;
accumulator = Sym1;
#ifdef DEBUG_MPPC
- printf("%c", accumulator);
+ DEBUG_MSG("%c", accumulator);
#endif
if (accumulator < 0x80)
}
#ifdef DEBUG_MPPC
- printf("<%d,%d>", (int) CopyOffset, (int) LengthOfMatch);
+ DEBUG_MSG("<%d,%d>", (int) CopyOffset, (int) LengthOfMatch);
#endif
/* Encode CopyOffset */
accumulator = *pSrcPtr;
#ifdef DEBUG_MPPC
- printf("%c", accumulator);
+ DEBUG_MSG("%c", accumulator);
#endif
if (accumulator < 0x80)
mppc->HistoryOffset = HistoryPtr - HistoryBuffer;
#ifdef DEBUG_MPPC
- printf("\n");
+ DEBUG_MSG("\n");
#endif
return 1;
#include <winpr/print.h>
#include <winpr/bitstream.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/codec/ncrush.h>
UINT16 HuffTableLEC[8192] =
if (HistoryPtr >= HistoryBufferEnd)
{
- fprintf(stderr, "ncrush_decompress error: HistoryPtr (%p) >= HistoryBufferEnd (%p)\n",
+ DEBUG_WARN( "ncrush_decompress error: HistoryPtr (%p) >= HistoryBufferEnd (%p)\n",
HistoryPtr, HistoryBufferEnd);
return -1003;
}
if (ncrush->HistoryBufferFence != 0xABABABAB)
{
- fprintf(stderr, "NCrushDecompress: history buffer fence was overwritten, potential buffer overflow detected!\n");
+ DEBUG_WARN( "NCrushDecompress: history buffer fence was overwritten, potential buffer overflow detected!\n");
return -1007;
}
ncrush->HistoryPtr = &(ncrush->HistoryBuffer[ncrush->HistoryOffset]);
if (ncrush_generate_tables(ncrush) < 0)
- printf("ncrush_context_new: failed to initialize tables\n");
+ DEBUG_MSG("ncrush_context_new: failed to initialize tables\n");
ncrush_context_reset(ncrush, FALSE);
}
#include <winpr/crt.h>
#include <winpr/print.h>
-#include <freerdp/codec/bitmap.h>
#include <freerdp/primitives.h>
+#include <freerdp/utils/debug.h>
+#include <freerdp/codec/bitmap.h>
+#include <freerdp/codec/planar.h>
+
+static int planar_skip_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, int nWidth, int nHeight)
+{
+ int x, y;
+ int cRawBytes;
+ int nRunLength;
+ BYTE controlByte;
+ const BYTE* pRLE = pSrcData;
+ const BYTE* pEnd = &pSrcData[SrcSize];
+
+ for (y = 0; y < nHeight; y++)
+ {
+ for (x = 0; x < nWidth; )
+ {
+ if (pRLE >= pEnd)
+ return -1;
+
+ controlByte = *pRLE++;
+
+ nRunLength = PLANAR_CONTROL_BYTE_RUN_LENGTH(controlByte);
+ cRawBytes = PLANAR_CONTROL_BYTE_RAW_BYTES(controlByte);
+
+ if (nRunLength == 1)
+ {
+ nRunLength = cRawBytes + 16;
+ cRawBytes = 0;
+ }
+ else if (nRunLength == 2)
+ {
+ nRunLength = cRawBytes + 32;
+ cRawBytes = 0;
+ }
+
+ pRLE += cRawBytes;
+ x += cRawBytes;
+ cRawBytes = 0;
+
+ x += nRunLength;
+ nRunLength = 0;
+
+ if (x > nWidth)
+ return -1;
+
+ if (pRLE > pEnd)
+ return -1;
+ }
+ }
-#include "planar.h"
+ return (int) (pRLE - pSrcData);
+}
-static int planar_decompress_plane_rle(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData,
+static int planar_decompress_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData,
int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, int nChannel, BOOL vFlip)
{
int x, y;
- BYTE* srcp;
BYTE* dstp;
UINT32 pixel;
int cRawBytes;
BYTE controlByte;
BYTE* currentScanline;
BYTE* previousScanline;
+ const BYTE* srcp = pSrcData;
- srcp = pSrcData;
dstp = pDstData;
previousScanline = NULL;
if ((srcp - pSrcData) > SrcSize)
{
- fprintf(stderr, "planar_decompress_plane_rle: error reading input buffer\n");
+ DEBUG_WARN( "planar_decompress_plane_rle: error reading input buffer\n");
return -1;
}
if (((dstp + (cRawBytes + nRunLength)) - currentScanline) > nWidth * 4)
{
- fprintf(stderr, "planar_decompress_plane_rle: too many pixels in scanline\n");
+ DEBUG_WARN( "planar_decompress_plane_rle: too many pixels in scanline\n");
return -1;
}
return (int) (srcp - pSrcData);
}
-static int planar_decompress_plane_raw(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData,
- int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, int nChannel, BOOL vFlip)
+static int planar_decompress_planes_raw(const BYTE* pSrcData[4], int nSrcStep, BYTE* pDstData,
+ int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, BOOL alpha, BOOL vFlip)
{
int x, y;
int beg, end, inc;
- BYTE* dstp = NULL;
- BYTE* srcp = pSrcData;
+ BYTE* pRGB = pDstData;
+ const BYTE* pR = pSrcData[0];
+ const BYTE* pG = pSrcData[1];
+ const BYTE* pB = pSrcData[2];
+ const BYTE* pA = pSrcData[3];
if (vFlip)
{
inc = 1;
}
- for (y = beg; y != end; y += inc)
+ if (alpha)
{
- dstp = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4) + nChannel];
+ for (y = beg; y != end; y += inc)
+ {
+ pRGB = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
- for (x = 0; x < nWidth; x++)
+ for (x = 0; x < nWidth; x++)
+ {
+ *pRGB++ = *pB++;
+ *pRGB++ = *pG++;
+ *pRGB++ = *pR++;
+ *pRGB++ = *pA++;
+ }
+ }
+ }
+ else
+ {
+ for (y = beg; y != end; y += inc)
{
- *dstp = *srcp;
- dstp += 4;
- srcp++;
+ pRGB = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
+
+ for (x = 0; x < nWidth; x++)
+ {
+ *pRGB++ = *pB++;
+ *pRGB++ = *pG++;
+ *pRGB++ = *pR++;
+ *pRGB++ = 0xFF;
+ }
}
}
- return (int) (srcp - pSrcData);
+ return 1;
}
int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight)
{
+ BOOL cs;
+ BOOL rle;
+ UINT32 cll;
+ BOOL alpha;
int status;
BYTE* srcp;
BOOL vFlip;
+ int subSize;
+ int subWidth;
+ int subHeight;
+ int planeSize;
+ BYTE* pDstData;
+ int rleSizes[4];
+ int rawSizes[4];
+ int rawWidths[4];
+ int rawHeights[4];
BYTE FormatHeader;
- BYTE* pDstData = NULL;
+ const BYTE* planes[4];
UINT32 UncompressedSize;
+ const primitives_t* prims = primitives_get();
if ((nWidth * nHeight) <= 0)
return -1;
*ppDstData = pDstData;
}
- FormatHeader = *srcp;
- srcp++;
+ FormatHeader = *srcp++;
- /* AlphaPlane */
+ cll = (FormatHeader & PLANAR_FORMAT_HEADER_CLL_MASK);
+ cs = (FormatHeader & PLANAR_FORMAT_HEADER_CS) ? TRUE : FALSE;
+ rle = (FormatHeader & PLANAR_FORMAT_HEADER_RLE) ? TRUE : FALSE;
+ alpha = (FormatHeader & PLANAR_FORMAT_HEADER_NA) ? FALSE : TRUE;
- if (!(FormatHeader & PLANAR_FORMAT_HEADER_NA))
+ //printf("CLL: %d CS: %d RLE: %d ALPHA: %d\n", cll, cs, rle, alpha);
+
+ if (!cll && cs)
+ return -1; /* Chroma subsampling requires YCoCg */
+
+ subWidth = (nWidth / 2) + (nWidth % 2);
+ subHeight = (nHeight / 2) + (nHeight % 2);
+
+ planeSize = nWidth * nHeight;
+ subSize = subWidth * subHeight;
+
+ if (!cs)
{
- if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
+ rawSizes[0] = planeSize; /* LumaOrRedPlane */
+ rawWidths[0] = nWidth;
+ rawHeights[0] = nHeight;
+
+ rawSizes[1] = planeSize; /* OrangeChromaOrGreenPlane */
+ rawWidths[1] = nWidth;
+ rawHeights[1] = nHeight;
+
+ rawSizes[2] = planeSize; /* GreenChromaOrBluePlane */
+ rawWidths[2] = nWidth;
+ rawHeights[2] = nHeight;
+
+ rawSizes[3] = planeSize; /* AlphaPlane */
+ rawWidths[3] = nWidth;
+ rawHeights[3] = nHeight;
+ }
+ else /* Chroma Subsampling */
+ {
+ rawSizes[0] = planeSize; /* LumaOrRedPlane */
+ rawWidths[0] = nWidth;
+ rawHeights[0] = nHeight;
+
+ rawSizes[1] = subSize; /* OrangeChromaOrGreenPlane */
+ rawWidths[1] = subWidth;
+ rawHeights[1] = subHeight;
+
+ rawSizes[2] = subSize; /* GreenChromaOrBluePlane */
+ rawWidths[2] = subWidth;
+ rawHeights[2] = subHeight;
+
+ rawSizes[3] = planeSize; /* AlphaPlane */
+ rawWidths[3] = nWidth;
+ rawHeights[3] = nHeight;
+ }
+
+ if (!rle) /* RAW */
+ {
+ if (alpha)
{
- status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData),
- pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 3, vFlip);
+ planes[3] = srcp; /* AlphaPlane */
+ planes[0] = planes[3] + rawSizes[3]; /* LumaOrRedPlane */
+ planes[1] = planes[0] + rawSizes[0]; /* OrangeChromaOrGreenPlane */
+ planes[2] = planes[1] + rawSizes[1]; /* GreenChromaOrBluePlane */
- if (status < 0)
+ if ((planes[2] + rawSizes[2]) > &pSrcData[SrcSize])
return -1;
-
- srcp += status;
}
else
{
- status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData),
- pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 3, vFlip);
-
- if (status < 0)
+ if ((SrcSize - (srcp - pSrcData)) < (planeSize * 3))
return -1;
- srcp += status;
+ planes[0] = srcp; /* LumaOrRedPlane */
+ planes[1] = planes[0] + rawSizes[0]; /* OrangeChromaOrGreenPlane */
+ planes[2] = planes[1] + rawSizes[1]; /* GreenChromaOrBluePlane */
+
+ if ((planes[2] + rawSizes[2]) > &pSrcData[SrcSize])
+ return -1;
}
}
-
- if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
+ else /* RLE */
{
- /* LumaOrRedPlane */
+ if (alpha)
+ {
+ planes[3] = srcp;
+ rleSizes[3] = planar_skip_plane_rle(planes[3], SrcSize - (planes[3] - pSrcData),
+ rawWidths[3], rawHeights[3]); /* AlphaPlane */
- status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData),
- pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip);
+ if (rleSizes[3] < 0)
+ return -1;
- if (status < 0)
- return -1;
+ planes[0] = planes[3] + rleSizes[3];
+ rleSizes[0] = planar_skip_plane_rle(planes[0], SrcSize - (planes[0] - pSrcData),
+ rawWidths[0], rawHeights[0]); /* RedPlane */
- srcp += status;
+ if (rleSizes[0] < 0)
+ return -1;
- /* OrangeChromaOrGreenPlane */
+ planes[1] = planes[0] + rleSizes[0];
+ rleSizes[1] = planar_skip_plane_rle(planes[1], SrcSize - (planes[1] - pSrcData),
+ rawWidths[1], rawHeights[1]); /* GreenPlane */
- status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData),
- pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip);
+ if (rleSizes[1] < 1)
+ return -1;
- if (status < 0)
- return -1;
+ planes[2] = planes[1] + rleSizes[1];
+ rleSizes[2] = planar_skip_plane_rle(planes[2], SrcSize - (planes[2] - pSrcData),
+ rawWidths[2], rawHeights[2]); /* BluePlane */
- srcp += status;
+ if (rleSizes[2] < 1)
+ return -1;
+ }
+ else
+ {
+ planes[0] = srcp;
+ rleSizes[0] = planar_skip_plane_rle(planes[0], SrcSize - (planes[0] - pSrcData),
+ rawWidths[0], rawHeights[0]); /* RedPlane */
- /* GreenChromeOrBluePlane */
+ if (rleSizes[0] < 0)
+ return -1;
- status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData),
- pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip);
+ planes[1] = planes[0] + rleSizes[0];
+ rleSizes[1] = planar_skip_plane_rle(planes[1], SrcSize - (planes[1] - pSrcData),
+ rawWidths[1], rawHeights[1]); /* GreenPlane */
- if (status < 0)
- return -1;
+ if (rleSizes[1] < 1)
+ return -1;
+
+ planes[2] = planes[1] + rleSizes[1];
+ rleSizes[2] = planar_skip_plane_rle(planes[2], SrcSize - (planes[2] - pSrcData),
+ rawWidths[2], rawHeights[2]); /* BluePlane */
- srcp += status;
+ if (rleSizes[2] < 1)
+ return -1;
+ }
}
- else
- {
- /* LumaOrRedPlane */
- status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData),
- pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip);
+ if (!cll) /* RGB */
+ {
+ if (!rle) /* RAW */
+ {
+ if (alpha)
+ {
+ planar_decompress_planes_raw(planes, nWidth, pDstData, nDstStep,
+ nXDst, nYDst, nWidth, nHeight, alpha, vFlip);
- if (status < 0)
- return -1;
+ srcp += rawSizes[0] + rawSizes[1] + rawSizes[2] + rawSizes[3];
+ }
+ else /* NoAlpha */
+ {
+ planar_decompress_planes_raw(planes, nWidth, pDstData, nDstStep,
+ nXDst, nYDst, nWidth, nHeight, alpha, vFlip);
- srcp += status;
+ srcp += rawSizes[0] + rawSizes[1] + rawSizes[2];
+ }
- /* OrangeChromaOrGreenPlane */
+ if ((SrcSize - (srcp - pSrcData)) == 1)
+ srcp++; /* pad */
+ }
+ else /* RLE */
+ {
+ if (alpha)
+ {
+ status = planar_decompress_plane_rle(planes[3], rleSizes[3],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 3, vFlip); /* AlphaPlane */
- status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData),
- pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip);
+ status = planar_decompress_plane_rle(planes[0], rleSizes[0],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip); /* RedPlane */
- if (status < 0)
- return -1;
+ status = planar_decompress_plane_rle(planes[1], rleSizes[1],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip); /* GreenPlane */
- srcp += status;
+ status = planar_decompress_plane_rle(planes[2], rleSizes[2],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip); /* BluePlane */
- /* GreenChromeOrBluePlane */
+ srcp += rleSizes[0] + rleSizes[1] + rleSizes[2] + rleSizes[3];
+ }
+ else /* NoAlpha */
+ {
+ status = planar_decompress_plane_rle(planes[0], rleSizes[0],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip); /* RedPlane */
- status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData),
- pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip);
+ status = planar_decompress_plane_rle(planes[1], rleSizes[1],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip); /* GreenPlane */
- if (status < 0)
- return -1;
+ status = planar_decompress_plane_rle(planes[2], rleSizes[2],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip); /* BluePlane */
- srcp += status;
- srcp++;
+ srcp += rleSizes[0] + rleSizes[1] + rleSizes[2];
+ }
+ }
}
-
- if (FormatHeader & PLANAR_FORMAT_HEADER_CLL_MASK)
+ else /* YCoCg */
{
- /* The data is in YCoCg colorspace rather than RGB. */
- if (FormatHeader & PLANAR_FORMAT_HEADER_CS)
+ if (cs)
{
- static BOOL been_warned = FALSE;
- if (!been_warned)
- fprintf(stderr, "Chroma-Subsampling is not implemented.\n");
- been_warned = TRUE;
+ fprintf(stderr, "Chroma subsampling unimplemented\n");
+ return -1;
}
- else
+
+ if (!rle) /* RAW */
{
- BOOL alpha;
- int cll;
-
- alpha = (FormatHeader & PLANAR_FORMAT_HEADER_NA) ? FALSE : TRUE;
- cll = FormatHeader & PLANAR_FORMAT_HEADER_CLL_MASK;
- primitives_get()->YCoCgRToRGB_8u_AC4R(
- pDstData, nDstStep, pDstData, nDstStep,
- nWidth, nHeight, cll, alpha, FALSE);
+ if (alpha)
+ {
+ planar_decompress_planes_raw(planes, nWidth, pDstData, nDstStep,
+ nXDst, nYDst, nWidth, nHeight, alpha, vFlip);
+
+ srcp += rawSizes[0] + rawSizes[1] + rawSizes[2] + rawSizes[3];
+ }
+ else /* NoAlpha */
+ {
+ planar_decompress_planes_raw(planes, nWidth, pDstData, nDstStep,
+ nXDst, nYDst, nWidth, nHeight, alpha, vFlip);
+
+ srcp += rawSizes[0] + rawSizes[1] + rawSizes[2];
+ }
+
+ if ((SrcSize - (srcp - pSrcData)) == 1)
+ srcp++; /* pad */
}
+ else /* RLE */
+ {
+ if (alpha)
+ {
+ status = planar_decompress_plane_rle(planes[3], rleSizes[3],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 3, vFlip); /* AlphaPlane */
+
+ status = planar_decompress_plane_rle(planes[0], rleSizes[0],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip); /* LumaPlane */
+
+ status = planar_decompress_plane_rle(planes[1], rleSizes[1],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip); /* OrangeChromaPlane */
+
+ status = planar_decompress_plane_rle(planes[2], rleSizes[2],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip); /* GreenChromaPlane */
+
+ srcp += rleSizes[0] + rleSizes[1] + rleSizes[2] + rleSizes[3];
+ }
+ else /* NoAlpha */
+ {
+ status = planar_decompress_plane_rle(planes[0], rleSizes[0],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip); /* LumaPlane */
+
+ status = planar_decompress_plane_rle(planes[1], rleSizes[1],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip); /* OrangeChromaPlane */
+
+ status = planar_decompress_plane_rle(planes[2], rleSizes[2],
+ pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip); /* GreenChromaPlane */
+
+ srcp += rleSizes[0] + rleSizes[1] + rleSizes[2];
+ }
+ }
+
+ prims->YCoCgToRGB_8u_AC4R(pDstData, nDstStep, pDstData, nDstStep, nWidth, nHeight, cll, alpha, FALSE);
}
status = (SrcSize == (srcp - pSrcData)) ? 1 : -1;
context->rlePlanes[3] = &context->rlePlanesBuffer[offset];
offset += dstSizes[3];
- //printf("R: [%d/%d] G: [%d/%d] B: [%d/%d]\n",
+ //DEBUG_MSG("R: [%d/%d] G: [%d/%d] B: [%d/%d]\n",
// dstSizes[1], planeSize, dstSizes[2], planeSize, dstSizes[3], planeSize);
}
}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Progressive Codec Bitmap Compression
+ *
+ * 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 <winpr/crt.h>
+#include <winpr/print.h>
+#include <winpr/bitstream.h>
+
+#include <freerdp/primitives.h>
+#include <freerdp/codec/color.h>
+#include <freerdp/codec/progressive.h>
+
+#include "rfx_differential.h"
+#include "rfx_quantization.h"
+
+const char* progressive_get_block_type_string(UINT16 blockType)
+{
+ switch (blockType)
+ {
+ case PROGRESSIVE_WBT_SYNC:
+ return "PROGRESSIVE_WBT_SYNC";
+ break;
+
+ case PROGRESSIVE_WBT_FRAME_BEGIN:
+ return "PROGRESSIVE_WBT_FRAME_BEGIN";
+ break;
+
+ case PROGRESSIVE_WBT_FRAME_END:
+ return "PROGRESSIVE_WBT_FRAME_END";
+ break;
+
+ case PROGRESSIVE_WBT_CONTEXT:
+ return "PROGRESSIVE_WBT_CONTEXT";
+ break;
+
+ case PROGRESSIVE_WBT_REGION:
+ return "PROGRESSIVE_WBT_REGION";
+ break;
+
+ case PROGRESSIVE_WBT_TILE_SIMPLE:
+ return "PROGRESSIVE_WBT_TILE_SIMPLE";
+ break;
+
+ case PROGRESSIVE_WBT_TILE_FIRST:
+ return "PROGRESSIVE_WBT_TILE_FIRST";
+ break;
+
+ case PROGRESSIVE_WBT_TILE_UPGRADE:
+ return "PROGRESSIVE_WBT_TILE_UPGRADE";
+ break;
+
+ default:
+ return "PROGRESSIVE_WBT_UNKNOWN";
+ break;
+ }
+
+ return "PROGRESSIVE_WBT_UNKNOWN";
+}
+
+void progressive_component_codec_quant_read(BYTE* block, RFX_COMPONENT_CODEC_QUANT* quantVal)
+{
+ quantVal->LL3 = block[0] & 0x0F;
+ quantVal->HL3 = block[0] >> 4;
+ quantVal->LH3 = block[1] & 0x0F;
+ quantVal->HH3 = block[1] >> 4;
+ quantVal->HL2 = block[2] & 0x0F;
+ quantVal->LH2 = block[2] >> 4;
+ quantVal->HH2 = block[3] & 0x0F;
+ quantVal->HL1 = block[3] >> 4;
+ quantVal->LH1 = block[4] & 0x0F;
+ quantVal->HH1 = block[4] >> 4;
+}
+
+void progressive_rfx_quant_ladd(RFX_COMPONENT_CODEC_QUANT* q, int val)
+{
+ q->HL1 += val; /* HL1 */
+ q->LH1 += val; /* LH1 */
+ q->HH1 += val; /* HH1 */
+ q->HL2 += val; /* HL2 */
+ q->LH2 += val; /* LH2 */
+ q->HH2 += val; /* HH2 */
+ q->HL3 += val; /* HL3 */
+ q->LH3 += val; /* LH3 */
+ q->HH3 += val; /* HH3 */
+ q->LL3 += val; /* LL3 */
+}
+
+void progressive_rfx_quant_add(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONENT_CODEC_QUANT* q2, RFX_COMPONENT_CODEC_QUANT* dst)
+{
+ dst->HL1 = q1->HL1 + q2->HL1; /* HL1 */
+ dst->LH1 = q1->LH1 + q2->LH1; /* LH1 */
+ dst->HH1 = q1->HH1 + q2->HH1; /* HH1 */
+ dst->HL2 = q1->HL2 + q2->HL2; /* HL2 */
+ dst->LH2 = q1->LH2 + q2->LH2; /* LH2 */
+ dst->HH2 = q1->HH2 + q2->HH2; /* HH2 */
+ dst->HL3 = q1->HL3 + q2->HL3; /* HL3 */
+ dst->LH3 = q1->LH3 + q2->LH3; /* LH3 */
+ dst->HH3 = q1->HH3 + q2->HH3; /* HH3 */
+ dst->LL3 = q1->LL3 + q2->LL3; /* LL3 */
+}
+
+void progressive_rfx_quant_lsub(RFX_COMPONENT_CODEC_QUANT* q, int val)
+{
+ q->HL1 -= val; /* HL1 */
+ q->LH1 -= val; /* LH1 */
+ q->HH1 -= val; /* HH1 */
+ q->HL2 -= val; /* HL2 */
+ q->LH2 -= val; /* LH2 */
+ q->HH2 -= val; /* HH2 */
+ q->HL3 -= val; /* HL3 */
+ q->LH3 -= val; /* LH3 */
+ q->HH3 -= val; /* HH3 */
+ q->LL3 -= val; /* LL3 */
+}
+
+void progressive_rfx_quant_sub(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONENT_CODEC_QUANT* q2, RFX_COMPONENT_CODEC_QUANT* dst)
+{
+ dst->HL1 = q1->HL1 - q2->HL1; /* HL1 */
+ dst->LH1 = q1->LH1 - q2->LH1; /* LH1 */
+ dst->HH1 = q1->HH1 - q2->HH1; /* HH1 */
+ dst->HL2 = q1->HL2 - q2->HL2; /* HL2 */
+ dst->LH2 = q1->LH2 - q2->LH2; /* LH2 */
+ dst->HH2 = q1->HH2 - q2->HH2; /* HH2 */
+ dst->HL3 = q1->HL3 - q2->HL3; /* HL3 */
+ dst->LH3 = q1->LH3 - q2->LH3; /* LH3 */
+ dst->HH3 = q1->HH3 - q2->HH3; /* HH3 */
+ dst->LL3 = q1->LL3 - q2->LL3; /* LL3 */
+}
+
+BOOL progressive_rfx_quant_lcmp_less_equal(RFX_COMPONENT_CODEC_QUANT* q, int val)
+{
+ if (q->HL1 > val) return FALSE; /* HL1 */
+ if (q->LH1 > val) return FALSE; /* LH1 */
+ if (q->HH1 > val) return FALSE; /* HH1 */
+ if (q->HL2 > val) return FALSE; /* HL2 */
+ if (q->LH2 > val) return FALSE; /* LH2 */
+ if (q->HH2 > val) return FALSE; /* HH2 */
+ if (q->HL3 > val) return FALSE; /* HL3 */
+ if (q->LH3 > val) return FALSE; /* LH3 */
+ if (q->HH3 > val) return FALSE; /* HH3 */
+ if (q->LL3 > val) return FALSE; /* LL3 */
+ return TRUE;
+}
+
+BOOL progressive_rfx_quant_cmp_less_equal(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONENT_CODEC_QUANT* q2)
+{
+ if (q1->HL1 > q2->HL1) return FALSE; /* HL1 */
+ if (q1->LH1 > q2->LH1) return FALSE; /* LH1 */
+ if (q1->HH1 > q2->HH1) return FALSE; /* HH1 */
+ if (q1->HL2 > q2->HL2) return FALSE; /* HL2 */
+ if (q1->LH2 > q2->LH2) return FALSE; /* LH2 */
+ if (q1->HH2 > q2->HH2) return FALSE; /* HH2 */
+ if (q1->HL3 > q2->HL3) return FALSE; /* HL3 */
+ if (q1->LH3 > q2->LH3) return FALSE; /* LH3 */
+ if (q1->HH3 > q2->HH3) return FALSE; /* HH3 */
+ if (q1->LL3 > q2->LL3) return FALSE; /* LL3 */
+ return TRUE;
+}
+
+BOOL progressive_rfx_quant_lcmp_greater_equal(RFX_COMPONENT_CODEC_QUANT* q, int val)
+{
+ if (q->HL1 < val) return FALSE; /* HL1 */
+ if (q->LH1 < val) return FALSE; /* LH1 */
+ if (q->HH1 < val) return FALSE; /* HH1 */
+ if (q->HL2 < val) return FALSE; /* HL2 */
+ if (q->LH2 < val) return FALSE; /* LH2 */
+ if (q->HH2 < val) return FALSE; /* HH2 */
+ if (q->HL3 < val) return FALSE; /* HL3 */
+ if (q->LH3 < val) return FALSE; /* LH3 */
+ if (q->HH3 < val) return FALSE; /* HH3 */
+ if (q->LL3 < val) return FALSE; /* LL3 */
+ return TRUE;
+}
+
+BOOL progressive_rfx_quant_cmp_greater_equal(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONENT_CODEC_QUANT* q2)
+{
+ if (q1->HL1 < q2->HL1) return FALSE; /* HL1 */
+ if (q1->LH1 < q2->LH1) return FALSE; /* LH1 */
+ if (q1->HH1 < q2->HH1) return FALSE; /* HH1 */
+ if (q1->HL2 < q2->HL2) return FALSE; /* HL2 */
+ if (q1->LH2 < q2->LH2) return FALSE; /* LH2 */
+ if (q1->HH2 < q2->HH2) return FALSE; /* HH2 */
+ if (q1->HL3 < q2->HL3) return FALSE; /* HL3 */
+ if (q1->LH3 < q2->LH3) return FALSE; /* LH3 */
+ if (q1->HH3 < q2->HH3) return FALSE; /* HH3 */
+ if (q1->LL3 < q2->LL3) return FALSE; /* LL3 */
+ return TRUE;
+}
+
+BOOL progressive_rfx_quant_cmp_equal(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONENT_CODEC_QUANT* q2)
+{
+ if (q1->HL1 != q2->HL1) return FALSE; /* HL1 */
+ if (q1->LH1 != q2->LH1) return FALSE; /* LH1 */
+ if (q1->HH1 != q2->HH1) return FALSE; /* HH1 */
+ if (q1->HL2 != q2->HL2) return FALSE; /* HL2 */
+ if (q1->LH2 != q2->LH2) return FALSE; /* LH2 */
+ if (q1->HH2 != q2->HH2) return FALSE; /* HH2 */
+ if (q1->HL3 != q2->HL3) return FALSE; /* HL3 */
+ if (q1->LH3 != q2->LH3) return FALSE; /* LH3 */
+ if (q1->HH3 != q2->HH3) return FALSE; /* HH3 */
+ if (q1->LL3 != q2->LL3) return FALSE; /* LL3 */
+ return TRUE;
+}
+
+int progressive_set_surface_data(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, void* pData)
+{
+ ULONG_PTR key;
+
+ key = ((ULONG_PTR) surfaceId) + 1;
+
+ if (pData)
+ HashTable_Add(progressive->SurfaceContexts, (void*) key, pData);
+ else
+ HashTable_Remove(progressive->SurfaceContexts, (void*) key);
+
+ return 1;
+}
+
+void* progressive_get_surface_data(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId)
+{
+ ULONG_PTR key;
+ void* pData = NULL;
+
+ key = ((ULONG_PTR) surfaceId) + 1;
+
+ pData = HashTable_GetItemValue(progressive->SurfaceContexts, (void*) key);
+
+ return pData;
+}
+
+int progressive_create_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, UINT32 width, UINT32 height)
+{
+ PROGRESSIVE_SURFACE_CONTEXT* surface;
+
+ surface = (PROGRESSIVE_SURFACE_CONTEXT*) progressive_get_surface_data(progressive, surfaceId);
+
+ if (!surface)
+ {
+ surface = (PROGRESSIVE_SURFACE_CONTEXT*) malloc(sizeof(PROGRESSIVE_SURFACE_CONTEXT));
+
+ 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);
+ }
+
+ return 1;
+}
+
+int progressive_delete_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId)
+{
+ PROGRESSIVE_SURFACE_CONTEXT* surface;
+
+ surface = (PROGRESSIVE_SURFACE_CONTEXT*) progressive_get_surface_data(progressive, surfaceId);
+
+ if (surface)
+ {
+ progressive_set_surface_data(progressive, surfaceId, NULL);
+
+ free(surface->tiles);
+ free(surface);
+ }
+
+ return 1;
+}
+
+/*
+ * Band Offset Dimensions Size
+ *
+ * HL1 0 31x33 1023
+ * LH1 1023 33x31 1023
+ * HH1 2046 31x31 961
+ *
+ * HL2 3007 16x17 272
+ * LH2 3279 17x16 272
+ * HH2 3551 16x16 256
+ *
+ * HL3 3807 8x9 72
+ * LH3 3879 9x8 72
+ * HH3 3951 8x8 64
+ *
+ * LL3 4015 9x9 81
+ */
+
+static void progressive_rfx_idwt_x(INT16* pLowBand, int nLowStep, INT16* pHighBand, int nHighStep,
+ INT16* pDstBand, int nDstStep, int nLowCount, int nHighCount, int nDstCount)
+{
+ int i, j;
+ INT16 L0;
+ INT16 H0, H1;
+ INT16 X0, X1, X2;
+ INT16 *pL, *pH, *pX;
+
+ for (i = 0; i < nDstCount; i++)
+ {
+ pL = pLowBand;
+ pH = pHighBand;
+ pX = pDstBand;
+
+ H0 = *pH;
+ pH++;
+
+ L0 = *pL;
+ pL++;
+
+ X0 = L0 - H0;
+ X2 = L0 - H0;
+
+ for (j = 0; j < (nHighCount - 1); j++)
+ {
+ H1 = *pH;
+ pH++;
+
+ L0 = *pL;
+ pL++;
+
+ X2 = L0 - ((H0 + H1) / 2);
+ X1 = ((X0 + X2) / 2) + (2 * H0);
+
+ pX[0] = X0;
+ pX[1] = X1;
+ pX += 2;
+
+ X0 = X2;
+ H0 = H1;
+ }
+
+ if (nLowCount <= (nHighCount + 1))
+ {
+ if (nLowCount <= nHighCount)
+ {
+ pX[0] = X2;
+ pX[1] = X2 + (2 * H0);
+ }
+ else
+ {
+ L0 = *pL;
+ pL++;
+
+ X0 = L0 - H0;
+
+ pX[0] = X2;
+ pX[1] = ((X0 + X2) / 2) + (2 * H0);
+ pX[2] = X0;
+ }
+ }
+ else
+ {
+ L0 = *pL;
+ pL++;
+
+ X0 = L0 - (H0 / 2);
+
+ pX[0] = X2;
+ pX[1] = ((X0 + X2) / 2) + (2 * H0);
+ pX[2] = X0;
+
+ L0 = *pL;
+ pL++;
+
+ pX[3] = (X0 + L0) / 2;
+ }
+
+ pLowBand += nLowStep;
+ pHighBand += nHighStep;
+ pDstBand += nDstStep;
+ }
+}
+
+static void progressive_rfx_idwt_y(INT16* pLowBand, int nLowStep, INT16* pHighBand, int nHighStep,
+ INT16* pDstBand, int nDstStep, int nLowCount, int nHighCount, int nDstCount)
+{
+ int i, j;
+ INT16 L0;
+ INT16 H0, H1;
+ INT16 X0, X1, X2;
+ INT16 *pL, *pH, *pX;
+
+ for (i = 0; i < nDstCount; i++)
+ {
+ pL = pLowBand;
+ pH = pHighBand;
+ pX = pDstBand;
+
+ H0 = *pH;
+ pH += nHighStep;
+
+ L0 = *pL;
+ pL += nLowStep;
+
+ X0 = L0 - H0;
+ X2 = L0 - H0;
+
+ for (j = 0; j < (nHighCount - 1); j++)
+ {
+ H1 = *pH;
+ pH += nHighStep;
+
+ L0 = *pL;
+ pL += nLowStep;
+
+ X2 = L0 - ((H0 + H1) / 2);
+ X1 = ((X0 + X2) / 2) + (2 * H0);
+
+ *pX = X0;
+ pX += nDstStep;
+
+ *pX = X1;
+ pX += nDstStep;
+
+ X0 = X2;
+ H0 = H1;
+ }
+
+ if (nLowCount <= (nHighCount + 1))
+ {
+ if (nLowCount <= nHighCount)
+ {
+ *pX = X2;
+ pX += nDstStep;
+
+ *pX = X2 + (2 * H0);
+ pX += nDstStep;
+ }
+ else
+ {
+ L0 = *pL;
+ pL += nLowStep;
+
+ X0 = L0 - H0;
+
+ *pX = X2;
+ pX += nDstStep;
+
+ *pX = ((X0 + X2) / 2) + (2 * H0);
+ pX += nDstStep;
+
+ *pX = X0;
+ pX += nDstStep;
+ }
+ }
+ else
+ {
+ L0 = *pL;
+ pL += nLowStep;
+
+ X0 = L0 - (H0 / 2);
+
+ *pX = X2;
+ pX += nDstStep;
+
+ *pX = ((X0 + X2) / 2) + (2 * H0);
+ pX += nDstStep;
+
+ *pX = X0;
+ pX += nDstStep;
+
+ L0 = *pL;
+ pL += nLowStep;
+
+ *pX = (X0 + L0) / 2;
+ pX += nDstStep;
+ }
+
+ pLowBand++;
+ pHighBand++;
+ pDstBand++;
+ }
+}
+
+static int progressive_rfx_get_band_l_count(int level)
+{
+ return (64 >> level) + 1;
+}
+
+static int progressive_rfx_get_band_h_count(int level)
+{
+ if (level == 1)
+ return (64 >> 1) - 1;
+ else
+ return (64 + (1 << (level - 1))) >> level;
+}
+
+static void progressive_rfx_dwt_2d_decode_block(INT16* buffer, INT16* temp, int level)
+{
+ int offset;
+ int nBandL;
+ int nBandH;
+ int nDstStepX;
+ int nDstStepY;
+ INT16 *HL, *LH;
+ INT16 *HH, *LL;
+ INT16 *L, *H, *LLx;
+ INT16* pLowBand[3];
+ INT16* pHighBand[3];
+ INT16* pDstBand[3];
+ int nLowStep[3];
+ int nHighStep[3];
+ int nDstStep[3];
+ int nLowCount[3];
+ int nHighCount[3];
+ int nDstCount[3];
+
+ nBandL = progressive_rfx_get_band_l_count(level);
+ nBandH = progressive_rfx_get_band_h_count(level);
+
+ offset = 0;
+
+ HL = &buffer[offset];
+ offset += (nBandH * nBandL);
+
+ LH = &buffer[offset];
+ offset += (nBandL * nBandH);
+
+ HH = &buffer[offset];
+ offset += (nBandH * nBandH);
+
+ LL = &buffer[offset];
+ offset += (nBandL * nBandL);
+
+ nDstStepX = (nBandL + nBandH);
+ nDstStepY = (nBandL + nBandH);
+
+ offset = 0;
+
+ L = &temp[offset];
+ offset += (nBandL * nDstStepX);
+
+ H = &temp[offset];
+ offset += (nBandH * nDstStepX);
+
+ LLx = &buffer[0];
+
+ /* horizontal (LL + HL -> L) */
+
+ pLowBand[0] = LL;
+ nLowStep[0] = nBandL;
+ pHighBand[0] = HL;
+ nHighStep[0] = nBandH;
+ pDstBand[0] = L;
+ nDstStep[0] = nDstStepX;
+ nLowCount[0] = nBandL;
+ nHighCount[0] = nBandH;
+ nDstCount[0] = nBandL;
+
+ progressive_rfx_idwt_x(pLowBand[0], nLowStep[0], pHighBand[0], nHighStep[0], pDstBand[0], nDstStep[0], nLowCount[0], nHighCount[0], nDstCount[0]);
+
+ /* horizontal (LH + HH -> H) */
+
+ pLowBand[1] = LH;
+ nLowStep[1] = nBandL;
+ pHighBand[1] = HH;
+ nHighStep[1] = nBandH;
+ pDstBand[1] = H;
+ nDstStep[1] = nDstStepX;
+ nLowCount[1] = nBandL;
+ nHighCount[1] = nBandH;
+ nDstCount[1] = nBandH;
+
+ progressive_rfx_idwt_x(pLowBand[1], nLowStep[1], pHighBand[1], nHighStep[1], pDstBand[1], nDstStep[1], nLowCount[1], nHighCount[1], nDstCount[1]);
+
+ /* vertical (L + H -> LL) */
+
+ pLowBand[2] = pDstBand[0];
+ nLowStep[2] = nDstStep[0];
+ pHighBand[2] = pDstBand[1];
+ nHighStep[2] = nDstStep[1];
+ pDstBand[2] = LLx;
+ nDstStep[2] = nDstStepY;
+ nLowCount[2] = nBandL;
+ nHighCount[2] = nBandH;
+ nDstCount[2] = nBandL + nBandH;
+
+ progressive_rfx_idwt_y(pLowBand[2], nLowStep[2], pHighBand[2], nHighStep[2], pDstBand[2], nDstStep[2], nLowCount[2], nHighCount[2], nDstCount[2]);
+}
+
+void progressive_rfx_dwt_2d_decode(INT16* buffer, INT16* temp, INT16* current, INT16* sign, BOOL diff)
+{
+ const primitives_t* prims = primitives_get();
+
+ if (diff)
+ prims->add_16s(buffer, current, buffer, 4096);
+
+ CopyMemory(current, buffer, 4096 * 2);
+
+ progressive_rfx_dwt_2d_decode_block(&buffer[3807], temp, 3);
+ progressive_rfx_dwt_2d_decode_block(&buffer[3007], temp, 2);
+ progressive_rfx_dwt_2d_decode_block(&buffer[0], temp, 1);
+}
+
+void progressive_rfx_decode_block(const primitives_t* prims, INT16* buffer, int length, UINT32 shift)
+{
+ if (!shift)
+ return;
+
+ prims->lShiftC_16s(buffer, shift, buffer, length);
+}
+
+int progressive_rfx_decode_component(PROGRESSIVE_CONTEXT* progressive, RFX_COMPONENT_CODEC_QUANT* shift,
+ const BYTE* data, int length, INT16* buffer, INT16* current, INT16* sign, BOOL diff)
+{
+ int status;
+ INT16* temp;
+ const primitives_t* prims = primitives_get();
+
+ status = rfx_rlgr_decode(data, length, buffer, 4096, 1);
+
+ if (status < 0)
+ return status;
+
+ CopyMemory(sign, buffer, 4096 * 2);
+
+ rfx_differential_decode(&buffer[4015], 81); /* LL3 */
+
+ progressive_rfx_decode_block(prims, &buffer[0], 1023, shift->HL1); /* HL1 */
+ progressive_rfx_decode_block(prims, &buffer[1023], 1023, shift->LH1); /* LH1 */
+ progressive_rfx_decode_block(prims, &buffer[2046], 961, shift->HH1); /* HH1 */
+ progressive_rfx_decode_block(prims, &buffer[3007], 272, shift->HL2); /* HL2 */
+ progressive_rfx_decode_block(prims, &buffer[3279], 272, shift->LH2); /* LH2 */
+ progressive_rfx_decode_block(prims, &buffer[3551], 256, shift->HH2); /* HH2 */
+ progressive_rfx_decode_block(prims, &buffer[3807], 72, shift->HL3); /* HL3 */
+ progressive_rfx_decode_block(prims, &buffer[3879], 72, shift->LH3); /* LH3 */
+ progressive_rfx_decode_block(prims, &buffer[3951], 64, shift->HH3); /* HH3 */
+ progressive_rfx_decode_block(prims, &buffer[4015], 81, shift->LL3); /* LL3 */
+
+ temp = (INT16*) BufferPool_Take(progressive->bufferPool, -1); /* DWT buffer */
+
+ progressive_rfx_dwt_2d_decode(buffer, temp, current, sign, diff);
+
+ BufferPool_Return(progressive->bufferPool, temp);
+
+ return 1;
+}
+
+int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progressive, RFX_PROGRESSIVE_TILE* tile)
+{
+ BOOL diff;
+ BYTE* pBuffer;
+ INT16* pSign[3];
+ INT16* pSrcDst[3];
+ INT16* pCurrent[3];
+ PROGRESSIVE_BLOCK_REGION* region;
+ RFX_COMPONENT_CODEC_QUANT shiftY;
+ RFX_COMPONENT_CODEC_QUANT shiftCb;
+ RFX_COMPONENT_CODEC_QUANT shiftCr;
+ RFX_COMPONENT_CODEC_QUANT* quantY;
+ RFX_COMPONENT_CODEC_QUANT* quantCb;
+ RFX_COMPONENT_CODEC_QUANT* quantCr;
+ RFX_COMPONENT_CODEC_QUANT* quantProgY;
+ RFX_COMPONENT_CODEC_QUANT* quantProgCb;
+ RFX_COMPONENT_CODEC_QUANT* quantProgCr;
+ RFX_PROGRESSIVE_CODEC_QUANT* quantProgVal;
+ static const prim_size_t roi_64x64 = { 64, 64 };
+ const primitives_t* prims = primitives_get();
+
+ tile->pass = 1;
+
+ diff = tile->flags & RFX_TILE_DIFFERENCE;
+
+#if 0
+ printf("ProgressiveTileFirst: quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d flags: 0x%02X quality: %d yLen: %d cbLen: %d crLen: %d tailLen: %d\n",
+ tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, tile->yIdx, tile->flags, tile->quality, tile->yLen, tile->cbLen, tile->crLen, tile->tailLen);
+#endif
+
+ region = &(progressive->region);
+
+ if (tile->quantIdxY >= region->numQuant)
+ return -1;
+
+ quantY = &(region->quantVals[tile->quantIdxY]);
+
+ if (tile->quantIdxCb >= region->numQuant)
+ return -1;
+
+ quantCb = &(region->quantVals[tile->quantIdxCb]);
+
+ if (tile->quantIdxCr >= region->numQuant)
+ return -1;
+
+ quantCr = &(region->quantVals[tile->quantIdxCr]);
+
+ if (tile->quality == 0xFF)
+ {
+ quantProgVal = &(progressive->quantProgValFull);
+ }
+ else
+ {
+ if (tile->quality >= region->numProgQuant)
+ return -1;
+
+ quantProgVal = &(region->quantProgVals[tile->quality]);
+ }
+
+ quantProgY = &(quantProgVal->yQuantValues);
+ quantProgCb = &(quantProgVal->cbQuantValues);
+ quantProgCr = &(quantProgVal->crQuantValues);
+
+ CopyMemory(&(tile->yQuant), quantY, sizeof(RFX_COMPONENT_CODEC_QUANT));
+ CopyMemory(&(tile->cbQuant), quantCb, sizeof(RFX_COMPONENT_CODEC_QUANT));
+ CopyMemory(&(tile->crQuant), quantCr, sizeof(RFX_COMPONENT_CODEC_QUANT));
+
+ CopyMemory(&(tile->yProgQuant), quantProgY, sizeof(RFX_COMPONENT_CODEC_QUANT));
+ CopyMemory(&(tile->cbProgQuant), quantProgCb, sizeof(RFX_COMPONENT_CODEC_QUANT));
+ CopyMemory(&(tile->crProgQuant), quantProgCr, sizeof(RFX_COMPONENT_CODEC_QUANT));
+
+ progressive_rfx_quant_add(quantY, quantProgY, &(tile->yBitPos));
+ progressive_rfx_quant_add(quantCb, quantProgCb, &(tile->cbBitPos));
+ progressive_rfx_quant_add(quantCr, quantProgCr, &(tile->crBitPos));
+
+ progressive_rfx_quant_add(quantY, quantProgY, &shiftY);
+ progressive_rfx_quant_lsub(&shiftY, 1); /* -6 + 5 = -1 */
+ progressive_rfx_quant_add(quantCb, quantProgCb, &shiftCb);
+ progressive_rfx_quant_lsub(&shiftCb, 1); /* -6 + 5 = -1 */
+ progressive_rfx_quant_add(quantCr, quantProgCr, &shiftCr);
+ progressive_rfx_quant_lsub(&shiftCr, 1); /* -6 + 5 = -1 */
+
+ if (!tile->data)
+ {
+ tile->data = (BYTE*) _aligned_malloc(64 * 64 * 4, 16);
+ }
+
+ if (!tile->sign)
+ {
+ tile->sign = (BYTE*) _aligned_malloc((8192 + 32) * 3, 16);
+ }
+
+ if (!tile->current)
+ {
+ tile->current = (BYTE*) _aligned_malloc((8192 + 32) * 3, 16);
+ }
+
+ pBuffer = tile->sign;
+ pSign[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */
+ pSign[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */
+ pSign[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */
+
+ pBuffer = tile->current;
+ pCurrent[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */
+ pCurrent[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */
+ pCurrent[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */
+
+ pBuffer = (BYTE*) BufferPool_Take(progressive->bufferPool, -1);
+ pSrcDst[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */
+ pSrcDst[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */
+ pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */
+
+ progressive_rfx_decode_component(progressive, &shiftY, tile->yData, tile->yLen, pSrcDst[0], pCurrent[0], pSign[0], diff); /* Y */
+ progressive_rfx_decode_component(progressive, &shiftCb, tile->cbData, tile->cbLen, pSrcDst[1], pCurrent[1], pSign[1], diff); /* Cb */
+ progressive_rfx_decode_component(progressive, &shiftCr, tile->crData, tile->crLen, pSrcDst[2], pCurrent[2], pSign[2], diff); /* Cr */
+
+ prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2,
+ tile->data, 64 * 4, &roi_64x64);
+
+ BufferPool_Return(progressive->bufferPool, pBuffer);
+
+ //WLog_Image(progressive->log, WLOG_TRACE, tile->data, 64, 64, 32);
+
+ return 1;
+}
+
+struct _RFX_PROGRESSIVE_UPGRADE_STATE
+{
+ BOOL nonLL;
+ wBitStream* srl;
+ wBitStream* raw;
+
+ /* SRL state */
+
+ int kp;
+ int nz;
+ BOOL mode;
+};
+typedef struct _RFX_PROGRESSIVE_UPGRADE_STATE RFX_PROGRESSIVE_UPGRADE_STATE;
+
+INT16 progressive_rfx_srl_read(RFX_PROGRESSIVE_UPGRADE_STATE* state, UINT32 numBits)
+{
+ int k;
+ UINT32 bit;
+ UINT32 max;
+ UINT32 mag;
+ UINT32 sign;
+ wBitStream* bs = state->srl;
+
+ if (state->nz)
+ {
+ state->nz--;
+ return 0;
+ }
+
+ k = state->kp / 8;
+
+ if (!state->mode)
+ {
+ /* zero encoding */
+
+ bit = (bs->accumulator & 0x80000000) ? 1 : 0;
+ BitStream_Shift(bs, 1);
+
+ if (!bit)
+ {
+ /* '0' bit, nz >= (1 << k), nz = (1 << k) */
+
+ state->nz = (1 << k);
+
+ state->kp += 4;
+
+ if (state->kp > 80)
+ state->kp = 80;
+
+ state->nz--;
+ return 0;
+ }
+ else
+ {
+ /* '1' bit, nz < (1 << k), nz = next k bits */
+
+ state->nz = 0;
+ state->mode = 1; /* unary encoding is next */
+
+ if (k)
+ {
+ bs->mask = ((1 << k) - 1);
+ state->nz = ((bs->accumulator >> (32 - k)) & bs->mask);
+ BitStream_Shift(bs, k);
+ }
+
+ if (state->nz)
+ {
+ state->nz--;
+ return 0;
+ }
+ }
+ }
+
+ state->mode = 0; /* zero encoding is next */
+
+ /* unary encoding */
+
+ /* read sign bit */
+
+ sign = (bs->accumulator & 0x80000000) ? 1 : 0;
+ BitStream_Shift(bs, 1);
+
+ state->kp -= 6;
+
+ if (state->kp < 0)
+ state->kp = 0;
+
+ if (numBits == 1)
+ return sign ? -1 : 1;
+
+ mag = 1;
+ max = (1 << numBits) - 1;
+
+ while (mag < max)
+ {
+ bit = (bs->accumulator & 0x80000000) ? 1 : 0;
+ BitStream_Shift(bs, 1);
+
+ if (bit)
+ break;
+
+ mag++;
+ }
+
+ return sign ? -mag : mag;
+}
+
+int progressive_rfx_upgrade_state_finish(RFX_PROGRESSIVE_UPGRADE_STATE* state)
+{
+ int pad;
+ wBitStream* srl;
+ wBitStream* raw;
+
+ srl = state->srl;
+ raw = state->raw;
+
+ /* Read trailing bits from RAW/SRL bit streams */
+
+ pad = (raw->position % 8) ? (8 - (raw->position % 8)) : 0;
+
+ if (pad)
+ BitStream_Shift(raw, pad);
+
+ pad = (srl->position % 8) ? (8 - (srl->position % 8)) : 0;
+
+ if (pad)
+ BitStream_Shift(srl, pad);
+
+ if (BitStream_GetRemainingLength(srl) == 8)
+ BitStream_Shift(srl, 8);
+
+ return 1;
+}
+
+int progressive_rfx_upgrade_block(RFX_PROGRESSIVE_UPGRADE_STATE* state, INT16* buffer,
+ INT16* sign, int length, UINT32 shift, UINT32 bitPos, UINT32 numBits)
+{
+ int index;
+ INT16 input;
+ wBitStream* srl;
+ wBitStream* raw;
+
+ if (!numBits)
+ return 1;
+
+ srl = state->srl;
+ raw = state->raw;
+
+ if (!state->nonLL)
+ {
+ for (index = 0; index < length; index++)
+ {
+ raw->mask = ((1 << numBits) - 1);
+ input = (INT16) ((raw->accumulator >> (32 - numBits)) & raw->mask);
+ BitStream_Shift(raw, numBits);
+
+ buffer[index] += (input << shift);
+ }
+
+ return 1;
+ }
+
+ for (index = 0; index < length; index++)
+ {
+ if (sign[index] > 0)
+ {
+ /* sign > 0, read from raw */
+
+ raw->mask = ((1 << numBits) - 1);
+ input = (INT16) ((raw->accumulator >> (32 - numBits)) & raw->mask);
+ BitStream_Shift(raw, numBits);
+ }
+ else if (sign[index] < 0)
+ {
+ /* sign < 0, read from raw */
+
+ raw->mask = ((1 << numBits) - 1);
+ input = (INT16) ((raw->accumulator >> (32 - numBits)) & raw->mask);
+ BitStream_Shift(raw, numBits);
+
+ input *= -1;
+ }
+ else
+ {
+ /* sign == 0, read from srl */
+
+ input = progressive_rfx_srl_read(state, numBits);
+
+ sign[index] = input;
+ }
+
+ buffer[index] += (input << shift);
+ }
+
+ return 1;
+}
+
+int progressive_rfx_upgrade_component(PROGRESSIVE_CONTEXT* progressive, RFX_COMPONENT_CODEC_QUANT* shift,
+ RFX_COMPONENT_CODEC_QUANT* bitPos, RFX_COMPONENT_CODEC_QUANT* numBits, INT16* buffer,
+ INT16* current, INT16* sign, const BYTE* srlData, int srlLen, const BYTE* rawData, int rawLen)
+{
+ INT16* temp;
+ int aRawLen;
+ int aSrlLen;
+ wBitStream s_srl;
+ wBitStream s_raw;
+ RFX_PROGRESSIVE_UPGRADE_STATE state;
+
+ ZeroMemory(&s_srl, sizeof(wBitStream));
+ ZeroMemory(&s_raw, sizeof(wBitStream));
+ ZeroMemory(&state, sizeof(RFX_PROGRESSIVE_UPGRADE_STATE));
+
+ state.kp = 8;
+ state.mode = 0;
+ state.srl = &s_srl;
+ state.raw = &s_raw;
+
+ BitStream_Attach(state.srl, srlData, srlLen);
+ BitStream_Fetch(state.srl);
+
+ BitStream_Attach(state.raw, rawData, rawLen);
+ BitStream_Fetch(state.raw);
+
+ state.nonLL = TRUE;
+ progressive_rfx_upgrade_block(&state, ¤t[0], &sign[0], 1023, shift->HL1, bitPos->HL1, numBits->HL1); /* HL1 */
+ progressive_rfx_upgrade_block(&state, ¤t[1023], &sign[1023], 1023, shift->LH1, bitPos->LH1, numBits->LH1); /* LH1 */
+ progressive_rfx_upgrade_block(&state, ¤t[2046], &sign[2046], 961, shift->HH1, bitPos->HH1, numBits->HH1); /* HH1 */
+ progressive_rfx_upgrade_block(&state, ¤t[3007], &sign[3007], 272, shift->HL2, bitPos->HL2, numBits->HL2); /* HL2 */
+ progressive_rfx_upgrade_block(&state, ¤t[3279], &sign[3279], 272, shift->LH2, bitPos->LH2, numBits->LH2); /* LH2 */
+ progressive_rfx_upgrade_block(&state, ¤t[3551], &sign[3551], 256, shift->HH2, bitPos->HH2, numBits->HH2); /* HH2 */
+ progressive_rfx_upgrade_block(&state, ¤t[3807], &sign[3807], 72, shift->HL3, bitPos->HL3, numBits->HL3); /* HL3 */
+ progressive_rfx_upgrade_block(&state, ¤t[3879], &sign[3879], 72, shift->LH3, bitPos->LH3, numBits->LH3); /* LH3 */
+ progressive_rfx_upgrade_block(&state, ¤t[3951], &sign[3951], 64, shift->HH3, bitPos->HH3, numBits->HH3); /* HH3 */
+
+ state.nonLL = FALSE;
+ progressive_rfx_upgrade_block(&state, ¤t[4015], &sign[4015], 81, shift->LL3, bitPos->LL3, numBits->LL3); /* LL3 */
+ progressive_rfx_upgrade_state_finish(&state);
+
+ aRawLen = (state.raw->position + 7) / 8;
+ aSrlLen = (state.srl->position + 7) / 8;
+
+ if ((aRawLen != rawLen) || (aSrlLen != srlLen))
+ {
+ int pRawLen = 0;
+ int pSrlLen = 0;
+
+ if (rawLen)
+ pRawLen = (int) ((((float) aRawLen) / ((float) rawLen)) * 100.0f);
+
+ if (srlLen)
+ pSrlLen = (int) ((((float) aSrlLen) / ((float) srlLen)) * 100.0f);
+
+ printf("RAW: %d/%d %d%% (%d/%d:%d)\tSRL: %d/%d %d%% (%d/%d:%d)\n",
+ aRawLen, rawLen, pRawLen, state.raw->position, rawLen * 8,
+ (rawLen * 8) - state.raw->position,
+ aSrlLen, srlLen, pSrlLen, state.srl->position, srlLen * 8,
+ (srlLen * 8) - state.srl->position);
+
+ return -1;
+ }
+
+ temp = (INT16*) BufferPool_Take(progressive->bufferPool, -1); /* DWT buffer */
+
+ CopyMemory(buffer, current, 4096 * 2);
+
+ progressive_rfx_dwt_2d_decode_block(&buffer[3807], temp, 3);
+ progressive_rfx_dwt_2d_decode_block(&buffer[3007], temp, 2);
+ progressive_rfx_dwt_2d_decode_block(&buffer[0], temp, 1);
+
+ BufferPool_Return(progressive->bufferPool, temp);
+
+ return 1;
+}
+
+int progressive_decompress_tile_upgrade(PROGRESSIVE_CONTEXT* progressive, RFX_PROGRESSIVE_TILE* tile)
+{
+ int status;
+ BYTE* pBuffer;
+ INT16* pSign[3];
+ INT16* pSrcDst[3];
+ INT16* pCurrent[3];
+ PROGRESSIVE_BLOCK_REGION* region;
+ RFX_COMPONENT_CODEC_QUANT shiftY;
+ RFX_COMPONENT_CODEC_QUANT shiftCb;
+ RFX_COMPONENT_CODEC_QUANT shiftCr;
+ RFX_COMPONENT_CODEC_QUANT yBitPos;
+ RFX_COMPONENT_CODEC_QUANT cbBitPos;
+ RFX_COMPONENT_CODEC_QUANT crBitPos;
+ RFX_COMPONENT_CODEC_QUANT yNumBits;
+ RFX_COMPONENT_CODEC_QUANT cbNumBits;
+ RFX_COMPONENT_CODEC_QUANT crNumBits;
+ RFX_COMPONENT_CODEC_QUANT* quantY;
+ RFX_COMPONENT_CODEC_QUANT* quantCb;
+ RFX_COMPONENT_CODEC_QUANT* quantCr;
+ RFX_COMPONENT_CODEC_QUANT* quantProgY;
+ RFX_COMPONENT_CODEC_QUANT* quantProgCb;
+ RFX_COMPONENT_CODEC_QUANT* quantProgCr;
+ RFX_PROGRESSIVE_CODEC_QUANT* quantProg;
+ static const prim_size_t roi_64x64 = { 64, 64 };
+ const primitives_t* prims = primitives_get();
+
+ tile->pass++;
+
+#if 0
+ printf("ProgressiveTileUpgrade: pass: %d quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d quality: %d ySrlLen: %d yRawLen: %d cbSrlLen: %d cbRawLen: %d crSrlLen: %d crRawLen: %d\n",
+ tile->pass, tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, tile->yIdx, tile->quality, tile->ySrlLen, tile->yRawLen, tile->cbSrlLen, tile->cbRawLen, tile->crSrlLen, tile->crRawLen);
+#endif
+
+ region = &(progressive->region);
+
+ if (tile->quantIdxY >= region->numQuant)
+ return -1;
+
+ quantY = &(region->quantVals[tile->quantIdxY]);
+
+ if (tile->quantIdxCb >= region->numQuant)
+ return -1;
+
+ quantCb = &(region->quantVals[tile->quantIdxCb]);
+
+ if (tile->quantIdxCr >= region->numQuant)
+ return -1;
+
+ quantCr = &(region->quantVals[tile->quantIdxCr]);
+
+ if (tile->quality == 0xFF)
+ {
+ quantProg = &(progressive->quantProgValFull);
+ }
+ else
+ {
+ if (tile->quality >= region->numProgQuant)
+ return -1;
+
+ quantProg = &(region->quantProgVals[tile->quality]);
+ }
+
+ quantProgY = &(quantProg->yQuantValues);
+ quantProgCb = &(quantProg->cbQuantValues);
+ quantProgCr = &(quantProg->crQuantValues);
+
+ if (!progressive_rfx_quant_cmp_equal(quantY, &(tile->yQuant)))
+ printf("warning: non-progressive quantY has changed!\n");
+ if (!progressive_rfx_quant_cmp_equal(quantCb, &(tile->cbQuant)))
+ printf("warning: non-progressive quantCb has changed!\n");
+ if (!progressive_rfx_quant_cmp_equal(quantCr, &(tile->crQuant)))
+ printf("warning: non-progressive quantCr has changed!\n");
+
+ progressive_rfx_quant_add(quantY, quantProgY, &yBitPos);
+ progressive_rfx_quant_add(quantCb, quantProgCb, &cbBitPos);
+ progressive_rfx_quant_add(quantCr, quantProgCr, &crBitPos);
+
+ progressive_rfx_quant_sub(&(tile->yBitPos), &yBitPos, &yNumBits);
+ progressive_rfx_quant_sub(&(tile->cbBitPos), &cbBitPos, &cbNumBits);
+ progressive_rfx_quant_sub(&(tile->crBitPos), &crBitPos, &crNumBits);
+
+ progressive_rfx_quant_add(quantY, quantProgY, &shiftY);
+ progressive_rfx_quant_lsub(&shiftY, 1); /* -6 + 5 = -1 */
+ progressive_rfx_quant_add(quantCb, quantProgCb, &shiftCb);
+ progressive_rfx_quant_lsub(&shiftCb, 1); /* -6 + 5 = -1 */
+ progressive_rfx_quant_add(quantCr, quantProgCr, &shiftCr);
+ progressive_rfx_quant_lsub(&shiftCr, 1); /* -6 + 5 = -1 */
+
+ CopyMemory(&(tile->yBitPos), &yBitPos, sizeof(RFX_COMPONENT_CODEC_QUANT));
+ CopyMemory(&(tile->cbBitPos), &cbBitPos, sizeof(RFX_COMPONENT_CODEC_QUANT));
+ CopyMemory(&(tile->crBitPos), &crBitPos, sizeof(RFX_COMPONENT_CODEC_QUANT));
+
+ CopyMemory(&(tile->yQuant), quantY, sizeof(RFX_COMPONENT_CODEC_QUANT));
+ CopyMemory(&(tile->cbQuant), quantCb, sizeof(RFX_COMPONENT_CODEC_QUANT));
+ CopyMemory(&(tile->crQuant), quantCr, sizeof(RFX_COMPONENT_CODEC_QUANT));
+
+ CopyMemory(&(tile->yProgQuant), quantProgY, sizeof(RFX_COMPONENT_CODEC_QUANT));
+ CopyMemory(&(tile->cbProgQuant), quantProgCb, sizeof(RFX_COMPONENT_CODEC_QUANT));
+ CopyMemory(&(tile->crProgQuant), quantProgCr, sizeof(RFX_COMPONENT_CODEC_QUANT));
+
+ pBuffer = tile->sign;
+ pSign[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */
+ pSign[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */
+ pSign[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */
+
+ pBuffer = tile->current;
+ pCurrent[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */
+ pCurrent[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */
+ pCurrent[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */
+
+ pBuffer = (BYTE*) BufferPool_Take(progressive->bufferPool, -1);
+ pSrcDst[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */
+ pSrcDst[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */
+ pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */
+
+ status = progressive_rfx_upgrade_component(progressive, &shiftY, quantProgY, &yNumBits,
+ pSrcDst[0], pCurrent[0], pSign[0], tile->ySrlData, tile->ySrlLen, tile->yRawData, tile->yRawLen); /* Y */
+
+ if (status < 0)
+ return -1;
+
+ status = progressive_rfx_upgrade_component(progressive, &shiftCb, quantProgCb, &cbNumBits,
+ pSrcDst[1], pCurrent[1], pSign[1], tile->cbSrlData, tile->cbSrlLen, tile->cbRawData, tile->cbRawLen); /* Cb */
+
+ if (status < 0)
+ return -1;
+
+ status = progressive_rfx_upgrade_component(progressive, &shiftCr, quantProgCr, &crNumBits,
+ pSrcDst[2], pCurrent[2], pSign[2], tile->crSrlData, tile->crSrlLen, tile->crRawData, tile->crRawLen); /* Cr */
+
+ if (status < 0)
+ return -1;
+
+ prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2,
+ tile->data, 64 * 4, &roi_64x64);
+
+ BufferPool_Return(progressive->bufferPool, pBuffer);
+
+ //WLog_Image(progressive->log, WLOG_TRACE, tile->data, 64, 64, 32);
+
+ return 1;
+}
+
+int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UINT32 blocksLen, PROGRESSIVE_SURFACE_CONTEXT* surface)
+{
+ int status;
+ BYTE* block;
+ UINT16 xIdx;
+ UINT16 yIdx;
+ UINT16 zIdx;
+ UINT16 index;
+ UINT32 boffset;
+ UINT16 blockType;
+ UINT32 blockLen;
+ UINT32 count = 0;
+ UINT32 offset = 0;
+ RFX_PROGRESSIVE_TILE* tile;
+ RFX_PROGRESSIVE_TILE** tiles;
+ PROGRESSIVE_BLOCK_REGION* region;
+
+ region = &(progressive->region);
+
+ tiles = region->tiles;
+
+ while ((blocksLen - offset) >= 6)
+ {
+ boffset = 0;
+ block = &blocks[offset];
+
+ blockType = *((UINT16*) &block[boffset + 0]); /* blockType (2 bytes) */
+ blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */
+ boffset += 6;
+
+ //printf("%s\n", progressive_get_block_type_string(blockType));
+
+ if ((blocksLen - offset) < blockLen)
+ return -1003;
+
+ switch (blockType)
+ {
+ case PROGRESSIVE_WBT_TILE_SIMPLE:
+
+ if ((blockLen - boffset) < 16)
+ return -1022;
+
+ xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */
+ yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */
+
+ zIdx = (yIdx * surface->gridWidth) + xIdx;
+
+ if (zIdx >= surface->gridSize)
+ return -1;
+
+ tiles[count] = tile = &(surface->tiles[zIdx]);
+
+ tile->blockType = blockType;
+ tile->blockLen = blockLen;
+
+ tile->quality = 0xFF; /* simple tiles use no progressive techniques */
+
+ tile->quantIdxY = block[boffset + 0]; /* quantIdxY (1 byte) */
+ tile->quantIdxCb = block[boffset + 1]; /* quantIdxCb (1 byte) */
+ tile->quantIdxCr = block[boffset + 2]; /* quantIdxCr (1 byte) */
+ tile->xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */
+ tile->yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */
+ tile->flags = block[boffset + 7] & 1; /* flags (1 byte) */
+ tile->yLen = *((UINT16*) &block[boffset + 8]); /* yLen (2 bytes) */
+ tile->cbLen = *((UINT16*) &block[boffset + 10]); /* cbLen (2 bytes) */
+ tile->crLen = *((UINT16*) &block[boffset + 12]); /* crLen (2 bytes) */
+ tile->tailLen = *((UINT16*) &block[boffset + 14]); /* tailLen (2 bytes) */
+ boffset += 16;
+
+ if ((tile->blockLen - boffset) < tile->yLen)
+ return -1023;
+
+ tile->yData = &block[boffset];
+ boffset += tile->yLen;
+
+ if ((tile->blockLen - boffset) < tile->cbLen)
+ return -1024;
+
+ tile->cbData = &block[boffset];
+ boffset += tile->cbLen;
+
+ if ((tile->blockLen - boffset) < tile->crLen)
+ return -1025;
+
+ tile->crData = &block[boffset];
+ boffset += tile->crLen;
+
+ if ((tile->blockLen - boffset) < tile->tailLen)
+ return -1026;
+
+ tile->tailData = &block[boffset];
+ boffset += tile->tailLen;
+
+ tile->width = 64;
+ tile->height = 64;
+ tile->x = tile->xIdx * 64;
+ tile->y = tile->yIdx * 64;
+
+ tile->flags &= 1;
+
+ break;
+
+ case PROGRESSIVE_WBT_TILE_FIRST:
+
+ if ((blockLen - boffset) < 17)
+ return -1027;
+
+ xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */
+ yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */
+
+ zIdx = (yIdx * surface->gridWidth) + xIdx;
+
+ if (zIdx >= surface->gridSize)
+ return -1;
+
+ tiles[count] = tile = &(surface->tiles[zIdx]);
+
+ tile->blockType = blockType;
+ tile->blockLen = blockLen;
+
+ tile->quantIdxY = block[boffset + 0]; /* quantIdxY (1 byte) */
+ tile->quantIdxCb = block[boffset + 1]; /* quantIdxCb (1 byte) */
+ tile->quantIdxCr = block[boffset + 2]; /* quantIdxCr (1 byte) */
+ tile->xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */
+ tile->yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */
+ tile->flags = block[boffset + 7] & 1; /* flags (1 byte) */
+ tile->quality = block[boffset + 8]; /* quality (1 byte) */
+ tile->yLen = *((UINT16*) &block[boffset + 9]); /* yLen (2 bytes) */
+ tile->cbLen = *((UINT16*) &block[boffset + 11]); /* cbLen (2 bytes) */
+ tile->crLen = *((UINT16*) &block[boffset + 13]); /* crLen (2 bytes) */
+ tile->tailLen = *((UINT16*) &block[boffset + 15]); /* tailLen (2 bytes) */
+ boffset += 17;
+
+ if ((tile->blockLen - boffset) < tile->yLen)
+ return -1028;
+
+ tile->yData = &block[boffset];
+ boffset += tile->yLen;
+
+ if ((tile->blockLen - boffset) < tile->cbLen)
+ return -1029;
+
+ tile->cbData = &block[boffset];
+ boffset += tile->cbLen;
+
+ if ((tile->blockLen - boffset) < tile->crLen)
+ return -1030;
+
+ tile->crData = &block[boffset];
+ boffset += tile->crLen;
+
+ if ((tile->blockLen - boffset) < tile->tailLen)
+ return -1031;
+
+ tile->tailData = &block[boffset];
+ boffset += tile->tailLen;
+
+ tile->width = 64;
+ tile->height = 64;
+ tile->x = tile->xIdx * 64;
+ tile->y = tile->yIdx * 64;
+
+ break;
+
+ case PROGRESSIVE_WBT_TILE_UPGRADE:
+
+ if ((blockLen - boffset) < 20)
+ return -1032;
+
+ xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */
+ yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */
+
+ zIdx = (yIdx * surface->gridWidth) + xIdx;
+
+ if (zIdx >= surface->gridSize)
+ return -1;
+
+ tiles[count] = tile = &(surface->tiles[zIdx]);
+
+ tile->blockType = blockType;
+ tile->blockLen = blockLen;
+
+ tile->flags = 0;
+
+ tile->quantIdxY = block[boffset + 0]; /* quantIdxY (1 byte) */
+ tile->quantIdxCb = block[boffset + 1]; /* quantIdxCb (1 byte) */
+ tile->quantIdxCr = block[boffset + 2]; /* quantIdxCr (1 byte) */
+ tile->xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */
+ tile->yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */
+ tile->quality = block[boffset + 7]; /* quality (1 byte) */
+ tile->ySrlLen = *((UINT16*) &block[boffset + 8]); /* ySrlLen (2 bytes) */
+ tile->yRawLen = *((UINT16*) &block[boffset + 10]); /* yRawLen (2 bytes) */
+ tile->cbSrlLen = *((UINT16*) &block[boffset + 12]); /* cbSrlLen (2 bytes) */
+ tile->cbRawLen = *((UINT16*) &block[boffset + 14]); /* cbRawLen (2 bytes) */
+ tile->crSrlLen = *((UINT16*) &block[boffset + 16]); /* crSrlLen (2 bytes) */
+ tile->crRawLen = *((UINT16*) &block[boffset + 18]); /* crRawLen (2 bytes) */
+ boffset += 20;
+
+ if ((tile->blockLen - boffset) < tile->ySrlLen)
+ return -1033;
+
+ tile->ySrlData = &block[boffset];
+ boffset += tile->ySrlLen;
+
+ if ((tile->blockLen - boffset) < tile->yRawLen)
+ return -1034;
+
+ tile->yRawData = &block[boffset];
+ boffset += tile->yRawLen;
+
+ if ((tile->blockLen - boffset) < tile->cbSrlLen)
+ return -1035;
+
+ tile->cbSrlData = &block[boffset];
+ boffset += tile->cbSrlLen;
+
+ if ((tile->blockLen - boffset) < tile->cbRawLen)
+ return -1036;
+
+ tile->cbRawData = &block[boffset];
+ boffset += tile->cbRawLen;
+
+ if ((tile->blockLen - boffset) < tile->crSrlLen)
+ return -1037;
+
+ tile->crSrlData = &block[boffset];
+ boffset += tile->crSrlLen;
+
+ if ((tile->blockLen - boffset) < tile->crRawLen)
+ return -1038;
+
+ tile->crRawData = &block[boffset];
+ boffset += tile->crRawLen;
+
+ tile->width = 64;
+ tile->height = 64;
+ tile->x = tile->xIdx * 64;
+ tile->y = tile->yIdx * 64;
+
+ break;
+
+ default:
+ return -1039;
+ break;
+ }
+
+ if (boffset != blockLen)
+ return -1040;
+
+ offset += blockLen;
+ count++;
+ }
+
+ if (offset != blocksLen)
+ return -1041;
+
+ for (index = 0; index < region->numTiles; index++)
+ {
+ tile = tiles[index];
+
+ switch (tile->blockType)
+ {
+ case PROGRESSIVE_WBT_TILE_SIMPLE:
+ case PROGRESSIVE_WBT_TILE_FIRST:
+ status = progressive_decompress_tile_first(progressive, tile);
+ break;
+
+ case PROGRESSIVE_WBT_TILE_UPGRADE:
+ status = progressive_decompress_tile_upgrade(progressive, tile);
+ break;
+ }
+
+ if (status < 0)
+ return -1;
+ }
+
+ return (int) offset;
+}
+
+int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize,
+ BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, UINT16 surfaceId)
+{
+ int status;
+ BYTE* block;
+ BYTE* blocks;
+ UINT16 index;
+ UINT32 boffset;
+ UINT16 blockType;
+ UINT32 blockLen;
+ UINT32 blocksLen;
+ UINT32 count = 0;
+ UINT32 offset = 0;
+ RFX_RECT* rect = NULL;
+ PROGRESSIVE_BLOCK_SYNC sync;
+ PROGRESSIVE_BLOCK_REGION* region;
+ PROGRESSIVE_BLOCK_CONTEXT context;
+ PROGRESSIVE_BLOCK_FRAME_BEGIN frameBegin;
+ PROGRESSIVE_BLOCK_FRAME_END frameEnd;
+ PROGRESSIVE_SURFACE_CONTEXT* surface;
+ RFX_COMPONENT_CODEC_QUANT* quantVal;
+ RFX_PROGRESSIVE_CODEC_QUANT* quantProgVal;
+
+ surface = (PROGRESSIVE_SURFACE_CONTEXT*) progressive_get_surface_data(progressive, surfaceId);
+
+ if (!surface)
+ return -1001;
+
+ blocks = pSrcData;
+ blocksLen = SrcSize;
+
+ region = &(progressive->region);
+
+ while ((blocksLen - offset) >= 6)
+ {
+ boffset = 0;
+ block = &blocks[offset];
+
+ blockType = *((UINT16*) &block[boffset + 0]); /* blockType (2 bytes) */
+ blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */
+ boffset += 6;
+
+ //printf("%s\n", progressive_get_block_type_string(blockType));
+
+ if ((blocksLen - offset) < blockLen)
+ return -1003;
+
+ switch (blockType)
+ {
+ case PROGRESSIVE_WBT_SYNC:
+
+ sync.blockType = blockType;
+ sync.blockLen = blockLen;
+
+ if ((blockLen - boffset) != 6)
+ return -1004;
+
+ sync.magic = (UINT32) *((UINT32*) &block[boffset + 0]); /* magic (4 bytes) */
+ sync.version = (UINT32) *((UINT16*) &block[boffset + 4]); /* version (2 bytes) */
+ boffset += 6;
+
+ if (sync.magic != 0xCACCACCA)
+ return -1005;
+
+ if (sync.version != 0x0100)
+ return -1006;
+
+ break;
+
+ case PROGRESSIVE_WBT_FRAME_BEGIN:
+
+ frameBegin.blockType = blockType;
+ frameBegin.blockLen = blockLen;
+
+ if ((blockLen - boffset) < 6)
+ return -1007;
+
+ frameBegin.frameIndex = (UINT32) *((UINT32*) &block[boffset + 0]); /* frameIndex (4 bytes) */
+ frameBegin.regionCount = (UINT32) *((UINT16*) &block[boffset + 4]); /* regionCount (2 bytes) */
+ boffset += 6;
+
+ /**
+ * If the number of elements specified by the regionCount field is
+ * larger than the actual number of elements in the regions field,
+ * the decoder SHOULD ignore this inconsistency.
+ */
+
+ break;
+
+ case PROGRESSIVE_WBT_FRAME_END:
+
+ frameEnd.blockType = blockType;
+ frameEnd.blockLen = blockLen;
+
+ if ((blockLen - boffset) != 0)
+ return -1008;
+
+ break;
+
+ case PROGRESSIVE_WBT_CONTEXT:
+
+ context.blockType = blockType;
+ context.blockLen = blockLen;
+
+ if ((blockLen - boffset) != 4)
+ return -1009;
+
+ context.ctxId = block[boffset + 0]; /* ctxId (1 byte) */
+ context.tileSize = *((UINT16*) &block[boffset + 1]); /* tileSize (2 bytes) */
+ context.flags = block[boffset + 3]; /* flags (1 byte) */
+ boffset += 4;
+
+ if (context.tileSize != 64)
+ return -1010;
+
+ break;
+
+ case PROGRESSIVE_WBT_REGION:
+
+ region->blockType = blockType;
+ region->blockLen = blockLen;
+
+ if ((blockLen - boffset) < 12)
+ return -1011;
+
+ region->tileSize = block[boffset + 0]; /* tileSize (1 byte) */
+ region->numRects = *((UINT16*) &block[boffset + 1]); /* numRects (2 bytes) */
+ region->numQuant = block[boffset + 3]; /* numQuant (1 byte) */
+ region->numProgQuant = block[boffset + 4]; /* numProgQuant (1 byte) */
+ region->flags = block[boffset + 5]; /* flags (1 byte) */
+ region->numTiles = *((UINT16*) &block[boffset + 6]); /* numTiles (2 bytes) */
+ region->tileDataSize = *((UINT32*) &block[boffset + 8]); /* tileDataSize (4 bytes) */
+ boffset += 12;
+
+ if (region->tileSize != 64)
+ return -1012;
+
+ if (region->numRects < 1)
+ return -1013;
+
+ if (region->numQuant > 7)
+ return -1014;
+
+ if ((blockLen - boffset) < (region->numRects * 8))
+ return -1015;
+
+ if (region->numRects > progressive->cRects)
+ {
+ progressive->rects = (RFX_RECT*) realloc(progressive->rects, region->numRects * sizeof(RFX_RECT));
+ progressive->cRects = region->numRects;
+ }
+
+ region->rects = progressive->rects;
+
+ if (!region->rects)
+ return -1016;
+
+ for (index = 0; index < region->numRects; index++)
+ {
+ rect = &(region->rects[index]);
+ rect->x = *((UINT16*) &block[boffset + 0]);
+ rect->y = *((UINT16*) &block[boffset + 2]);
+ rect->width = *((UINT16*) &block[boffset + 4]);
+ rect->height = *((UINT16*) &block[boffset + 6]);
+ boffset += 8;
+ }
+
+ if ((blockLen - boffset) < (region->numQuant * 5))
+ return -1017;
+
+ if (region->numQuant > progressive->cQuant)
+ {
+ progressive->quantVals = (RFX_COMPONENT_CODEC_QUANT*) realloc(progressive->quantVals,
+ region->numQuant * sizeof(RFX_COMPONENT_CODEC_QUANT));
+ progressive->cQuant = region->numQuant;
+ }
+
+ region->quantVals = progressive->quantVals;
+
+ if (!region->quantVals)
+ return -1018;
+
+ for (index = 0; index < region->numQuant; index++)
+ {
+ quantVal = &(region->quantVals[index]);
+ progressive_component_codec_quant_read(&block[boffset], quantVal);
+ boffset += 5;
+
+ if (!progressive_rfx_quant_lcmp_greater_equal(quantVal, 6))
+ return -1;
+
+ if (!progressive_rfx_quant_lcmp_less_equal(quantVal, 15))
+ return -1;
+ }
+
+ if ((blockLen - boffset) < (region->numProgQuant * 16))
+ return -1019;
+
+ if (region->numProgQuant > progressive->cProgQuant)
+ {
+ progressive->quantProgVals = (RFX_PROGRESSIVE_CODEC_QUANT*) realloc(progressive->quantProgVals,
+ region->numProgQuant * sizeof(RFX_PROGRESSIVE_CODEC_QUANT));
+ progressive->cProgQuant = region->numProgQuant;
+ }
+
+ region->quantProgVals = progressive->quantProgVals;
+
+ if (!region->quantProgVals)
+ return -1020;
+
+ for (index = 0; index < region->numProgQuant; index++)
+ {
+ quantProgVal = &(region->quantProgVals[index]);
+ quantProgVal->quality = block[boffset + 0];
+
+ progressive_component_codec_quant_read(&block[boffset + 1], &(quantProgVal->yQuantValues));
+ progressive_component_codec_quant_read(&block[boffset + 6], &(quantProgVal->cbQuantValues));
+ progressive_component_codec_quant_read(&block[boffset + 11], &(quantProgVal->crQuantValues));
+ boffset += 16;
+ }
+
+ if ((blockLen - boffset) < region->tileDataSize)
+ return -1021;
+
+ if (region->numTiles > progressive->cTiles)
+ {
+ progressive->tiles = (RFX_PROGRESSIVE_TILE**) realloc(progressive->tiles,
+ region->numTiles * sizeof(RFX_PROGRESSIVE_TILE*));
+ progressive->cTiles = region->numTiles;
+ }
+
+ region->tiles = progressive->tiles;
+
+ if (!region->tiles)
+ return -1;
+
+ //printf("numRects: %d numTiles: %d numQuant: %d numProgQuant: %d\n",
+ // region->numRects, region->numTiles, region->numQuant, region->numProgQuant);
+
+ status = progressive_process_tiles(progressive, &block[boffset], region->tileDataSize, surface);
+
+ if (status < 0)
+ return status;
+
+ boffset += (UINT32) status;
+
+ break;
+
+ default:
+ return -1039;
+ break;
+ }
+
+ if (boffset != blockLen)
+ return -1040;
+
+ offset += blockLen;
+ count++;
+ }
+
+ if (offset != blocksLen)
+ return -1041;
+
+ return 1;
+}
+
+int progressive_compress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize)
+{
+ return 1;
+}
+
+void progressive_context_reset(PROGRESSIVE_CONTEXT* progressive)
+{
+
+}
+
+PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor)
+{
+ PROGRESSIVE_CONTEXT* progressive;
+
+ progressive = (PROGRESSIVE_CONTEXT*) calloc(1, sizeof(PROGRESSIVE_CONTEXT));
+
+ if (progressive)
+ {
+ progressive->Compressor = Compressor;
+
+ progressive->log = WLog_Get("com.freerdp.codec.progressive");
+
+ progressive->bufferPool = BufferPool_New(TRUE, (8192 + 32) * 3, 16);
+
+ progressive->cRects = 64;
+ progressive->rects = (RFX_RECT*) malloc(progressive->cRects * sizeof(RFX_RECT));
+
+ if (!progressive->rects)
+ return NULL;
+
+ progressive->cTiles = 64;
+ progressive->tiles = (RFX_PROGRESSIVE_TILE**) malloc(progressive->cTiles * sizeof(RFX_PROGRESSIVE_TILE*));
+
+ if (!progressive->tiles)
+ return NULL;
+
+ progressive->cQuant = 8;
+ progressive->quantVals = (RFX_COMPONENT_CODEC_QUANT*) malloc(progressive->cQuant * sizeof(RFX_COMPONENT_CODEC_QUANT));
+
+ if (!progressive->quantVals)
+ return NULL;
+
+ progressive->cProgQuant = 8;
+ progressive->quantProgVals = (RFX_PROGRESSIVE_CODEC_QUANT*) malloc(progressive->cProgQuant * sizeof(RFX_PROGRESSIVE_CODEC_QUANT));
+
+ if (!progressive->quantProgVals)
+ return NULL;
+
+ ZeroMemory(&(progressive->quantProgValFull), sizeof(RFX_PROGRESSIVE_CODEC_QUANT));
+ progressive->quantProgValFull.quality = 100;
+
+ progressive->SurfaceContexts = HashTable_New(TRUE);
+
+ progressive_context_reset(progressive);
+ }
+
+ return progressive;
+}
+
+void progressive_context_free(PROGRESSIVE_CONTEXT* progressive)
+{
+ if (!progressive)
+ return;
+
+ BufferPool_Free(progressive->bufferPool);
+
+ free(progressive->rects);
+ free(progressive->tiles);
+ free(progressive->quantVals);
+ free(progressive->quantProgVals);
+
+ HashTable_Free(progressive->SurfaceContexts);
+
+ free(progressive);
+}
+
#include <assert.h>
#include <winpr/memory.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/codec/region.h>
/*
int currentBandY = -1;
rects = region16_rects(region, &nbRects);
- fprintf(stderr, "nrects=%d", nbRects);
+ DEBUG_WARN( "nrects=%d", nbRects);
for (i = 0; i < nbRects; i++, rects++)
{
if (rects->top != currentBandY)
{
currentBandY = rects->top;
- fprintf(stderr, "\nband %d: ", currentBandY);
+ DEBUG_WARN( "\nband %d: ", currentBandY);
}
- fprintf(stderr, "(%d,%d-%d,%d)", rects->left, rects->top, rects->right, rects->bottom);
+ DEBUG_WARN( "(%d,%d-%d,%d)", rects->left, rects->top, rects->right, rects->bottom);
}
- fprintf(stderr, "\n");
+ DEBUG_WARN( "\n");
}
void region16_copy_band_with_union(RECTANGLE_16 *dst,
context->quantization_encode = rfx_quantization_encode;
context->dwt_2d_decode = rfx_dwt_2d_decode;
context->dwt_2d_encode = rfx_dwt_2d_encode;
- context->rlgr_decode = rfx_rlgr_decode;
- context->rlgr_encode = rfx_rlgr_encode;
RFX_INIT_SIMD(context);
free(priv->tileWorkParams);
#ifdef WITH_PROFILER
- fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n");
+ DEBUG_WARN( "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n");
#endif
}
free(message->tiles);
region16_uninit(&tilesRegion);
out_free_message:
- fprintf(stderr, "remoteFx error\n");
+ DEBUG_WARN( "remoteFx error\n");
region16_uninit(&rectsRegion);
free(message);
return 0;
#include "rfx_decode.h"
/* stride is bytes between rows in the output buffer. */
-static void rfx_decode_format_rgb(INT16* r_buf, INT16* g_buf, INT16* b_buf,
+void rfx_decode_format_rgb(INT16* r_buf, INT16* g_buf, INT16* b_buf,
RDP_PIXEL_FORMAT pixel_format, BYTE* dst_buf, int stride)
{
primitives_t *prims = primitives_get();
PROFILER_ENTER(context->priv->prof_rfx_decode_component);
PROFILER_ENTER(context->priv->prof_rfx_rlgr_decode);
- context->rlgr_decode(context->mode, data, size, buffer, 4096);
+ rfx_rlgr_decode(data, size, buffer, 4096, (context->mode == RLGR1) ? 1 : 3);
PROFILER_EXIT(context->priv->prof_rfx_rlgr_decode);
PROFILER_ENTER(context->priv->prof_rfx_differential_decode);
pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* cr_b_buffer */
rfx_decode_component(context, y_quants, tile->YData, tile->YLen, pSrcDst[0]); /* YData */
-
rfx_decode_component(context, cb_quants, tile->CbData, tile->CbLen, pSrcDst[1]); /* CbData */
-
rfx_decode_component(context, cr_quants, tile->CrData, tile->CrLen, pSrcDst[2]); /* CrData */
PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb);
#include "rfx_differential.h"
-void rfx_differential_decode(INT16* buffer, int buffer_size)
+void rfx_differential_decode(INT16* buffer, int size)
{
- INT16* src;
- INT16* dst;
+ INT16* ptr = buffer;
+ INT16* end = &buffer[size - 1];
- for (src = buffer, dst = buffer + 1; buffer_size > 1; src++, dst++, buffer_size--)
+ while (ptr != end)
{
- *dst += *src;
+ ptr[1] += ptr[0];
+ ptr++;
}
}
-void rfx_differential_encode(INT16* buffer, int buffer_size)
+void rfx_differential_encode(INT16* buffer, int size)
{
INT16 n1, n2;
INT16* dst;
- for (n1 = *buffer, dst = buffer + 1; buffer_size > 1; dst++, buffer_size--)
+ for (n1 = *buffer, dst = buffer + 1; size > 1; dst++, size--)
{
n2 = *dst;
*dst -= n1;
#include <freerdp/codec/rfx.h>
-void rfx_differential_decode(INT16* buffer, int buffer_size);
-void rfx_differential_encode(INT16* buffer, int buffer_size);
+void rfx_differential_decode(INT16* buffer, int size);
+void rfx_differential_encode(INT16* buffer, int size);
#endif /* __RFX_DIFFERENTIAL_H */
void rfx_dwt_2d_decode(INT16* buffer, INT16* dwt_buffer)
{
- rfx_dwt_2d_decode_block(buffer + 3840, dwt_buffer, 8);
- rfx_dwt_2d_decode_block(buffer + 3072, dwt_buffer, 16);
- rfx_dwt_2d_decode_block(buffer, dwt_buffer, 32);
+ rfx_dwt_2d_decode_block(&buffer[3840], dwt_buffer, 8);
+ rfx_dwt_2d_decode_block(&buffer[3072], dwt_buffer, 16);
+ rfx_dwt_2d_decode_block(&buffer[0], dwt_buffer, 32);
}
static void rfx_dwt_2d_encode_block(INT16* buffer, INT16* dwt, int subband_width)
void rfx_dwt_2d_encode(INT16* buffer, INT16* dwt_buffer)
{
- rfx_dwt_2d_encode_block(buffer, dwt_buffer, 32);
- rfx_dwt_2d_encode_block(buffer + 3072, dwt_buffer, 16);
- rfx_dwt_2d_encode_block(buffer + 3840, dwt_buffer, 8);
+ rfx_dwt_2d_encode_block(&buffer[0], dwt_buffer, 32);
+ rfx_dwt_2d_encode_block(&buffer[3072], dwt_buffer, 16);
+ rfx_dwt_2d_encode_block(&buffer[3840], dwt_buffer, 8);
}
PROFILER_EXIT(context->priv->prof_rfx_differential_encode);
PROFILER_ENTER(context->priv->prof_rfx_rlgr_encode);
- *size = context->rlgr_encode(context->mode, data, 4096, buffer, buffer_size);
+ *size = rfx_rlgr_encode(context->mode, data, 4096, buffer, buffer_size);
PROFILER_EXIT(context->priv->prof_rfx_rlgr_encode);
PROFILER_EXIT(context->priv->prof_rfx_encode_component);
while(buf < buf_end);
}
-void
-rfx_quantization_decode_NEON(INT16 * buffer, const UINT32 * quantization_values)
+void rfx_quantization_decode_NEON(INT16 * buffer, const UINT32 * quantVals)
{
- rfx_quantization_decode_block_NEON(buffer, 4096, 5);
-
- rfx_quantization_decode_block_NEON(buffer, 1024, quantization_values[8] - 6); /* HL1 */
- rfx_quantization_decode_block_NEON(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
- rfx_quantization_decode_block_NEON(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
- rfx_quantization_decode_block_NEON(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
- rfx_quantization_decode_block_NEON(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
- rfx_quantization_decode_block_NEON(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
- rfx_quantization_decode_block_NEON(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
- rfx_quantization_decode_block_NEON(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
- rfx_quantization_decode_block_NEON(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */
- rfx_quantization_decode_block_NEON(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
+ rfx_quantization_decode_block_NEON(&buffer[0], 1024, quantVals[8] - 1); /* HL1 */
+ rfx_quantization_decode_block_NEON(&buffer[1024], 1024, quantVals[7] - 1); /* LH1 */
+ rfx_quantization_decode_block_NEON(&buffer[2048], 1024, quantVals[9] - 1); /* HH1 */
+ rfx_quantization_decode_block_NEON(&buffer[3072], 256, quantVals[5] - 1); /* HL2 */
+ rfx_quantization_decode_block_NEON(&buffer[3328], 256, quantVals[4] - 1); /* LH2 */
+ rfx_quantization_decode_block_NEON(&buffer[3584], 256, quantVals[6] - 1); /* HH2 */
+ rfx_quantization_decode_block_NEON(&buffer[3840], 64, quantVals[2] - 1); /* HL3 */
+ rfx_quantization_decode_block_NEON(&buffer[3904], 64, quantVals[1] - 1); /* LH3 */
+ rfx_quantization_decode_block_NEON(&buffer[3968], 64, quantVals[3] - 1); /* HH3 */
+ rfx_quantization_decode_block_NEON(&buffer[4032], 64, quantVals[0] - 1); /* LL3 */
}
#endif
#include <freerdp/primitives.h>
+
#include "rfx_quantization.h"
-static void rfx_quantization_decode_block(const primitives_t *prims, INT16* buffer, int buffer_size, UINT32 factor)
+/*
+ * Band Offset Dimensions Size
+ *
+ * HL1 0 32x32 1024
+ * LH1 1024 32x32 1024
+ * HH1 2048 32x32 1024
+ *
+ * HL2 3072 16x16 256
+ * LH2 3328 16x16 256
+ * HH2 3584 16x16 256
+ *
+ * HL3 3840 8x8 64
+ * LH3 3904 8x8 64
+ * HH3 3968 8x8 64
+ *
+ * LL3 4032 8x8 64
+ */
+
+void rfx_quantization_decode_block(const primitives_t *prims, INT16* buffer, int buffer_size, UINT32 factor)
{
if (factor == 0)
return;
prims->lShiftC_16s(buffer, factor, buffer, buffer_size);
}
-void rfx_quantization_decode(INT16* buffer, const UINT32* quantization_values)
+void rfx_quantization_decode(INT16* buffer, const UINT32* quantVals)
{
- const primitives_t *prims = primitives_get();
-
- /* Scale the values so that they are represented as 11.5 fixed-point number */
- rfx_quantization_decode_block(prims, buffer, 4096, 5);
+ const primitives_t* prims = primitives_get();
- rfx_quantization_decode_block(prims, buffer, 1024, quantization_values[8] - 6); /* HL1 */
- rfx_quantization_decode_block(prims, buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
- rfx_quantization_decode_block(prims, buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
- rfx_quantization_decode_block(prims, buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
- rfx_quantization_decode_block(prims, buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
- rfx_quantization_decode_block(prims, buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
- rfx_quantization_decode_block(prims, buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
- rfx_quantization_decode_block(prims, buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
- rfx_quantization_decode_block(prims, buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */
- rfx_quantization_decode_block(prims, buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
+ rfx_quantization_decode_block(prims, &buffer[0], 1024, quantVals[8] - 1); /* HL1 */
+ rfx_quantization_decode_block(prims, &buffer[1024], 1024, quantVals[7] - 1); /* LH1 */
+ rfx_quantization_decode_block(prims, &buffer[2048], 1024, quantVals[9] - 1); /* HH1 */
+ rfx_quantization_decode_block(prims, &buffer[3072], 256, quantVals[5] - 1); /* HL2 */
+ rfx_quantization_decode_block(prims, &buffer[3328], 256, quantVals[4] - 1); /* LH2 */
+ rfx_quantization_decode_block(prims, &buffer[3584], 256, quantVals[6] - 1); /* HH2 */
+ rfx_quantization_decode_block(prims, &buffer[3840], 64, quantVals[2] - 1); /* HL3 */
+ rfx_quantization_decode_block(prims, &buffer[3904], 64, quantVals[1] - 1); /* LH3 */
+ rfx_quantization_decode_block(prims, &buffer[3968], 64, quantVals[3] - 1); /* HH3 */
+ rfx_quantization_decode_block(prims, &buffer[4032], 64, quantVals[0] - 1); /* LL3 */
}
static void rfx_quantization_encode_block(INT16* buffer, int buffer_size, UINT32 factor)
void rfx_quantization_decode(INT16* buffer, const UINT32* quantization_values);
void rfx_quantization_encode(INT16* buffer, const UINT32* quantization_values);
+void rfx_quantization_decode_block(const primitives_t *prims, INT16* buffer, int buffer_size, UINT32 factor);
+
#endif /* __RFX_QUANTIZATION_H */
#include <string.h>
#include <winpr/crt.h>
+#include <winpr/print.h>
+#include <winpr/sysinfo.h>
+#include <winpr/bitstream.h>
#include "rfx_bitstream.h"
#include "rfx_rlgr.h"
-/* Constants used within the RLGR1/RLGR3 algorithm */
-#define KPMAX (80) /* max value for kp or krp */
-#define LSGR (3) /* shift count to convert kp to k */
-#define UP_GR (4) /* increase in kp after a zero run in RL mode */
-#define DN_GR (6) /* decrease in kp after a nonzero symbol in RL mode */
-#define UQ_GR (3) /* increase in kp after nonzero symbol in GR mode */
-#define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */
-
-/* Gets (returns) the next nBits from the bitstream */
-#define GetBits(nBits, r) rfx_bitstream_get_bits(bs, nBits, r)
-
-/* From current output pointer, write "value", check and update buffer_size */
-#define WriteValue(value) \
-{ \
- if (buffer_size > 0) \
- *dst++ = (value); \
- buffer_size--; \
-}
-
-/* From current output pointer, write next nZeroes terms with value 0, check and update buffer_size */
-#define WriteZeroes(nZeroes) \
-{ \
- int nZeroesWritten = (nZeroes); \
- if (nZeroesWritten > buffer_size) \
- nZeroesWritten = buffer_size; \
- if (nZeroesWritten > 0) \
- { \
- memset(dst, 0, nZeroesWritten * sizeof(INT16)); \
- dst += nZeroesWritten; \
- } \
- buffer_size -= (nZeroes); \
-}
+/* Constants used in RLGR1/RLGR3 algorithm */
+#define KPMAX (80) /* max value for kp or krp */
+#define LSGR (3) /* shift count to convert kp to k */
+#define UP_GR (4) /* increase in kp after a zero run in RL mode */
+#define DN_GR (6) /* decrease in kp after a nonzero symbol in RL mode */
+#define UQ_GR (3) /* increase in kp after nonzero symbol in GR mode */
+#define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */
/* Returns the least number of bits required to represent a given value */
#define GetMinBits(_val, _nbits) \
} \
}
-/* Converts from (2 * magnitude - sign) to integer */
-#define GetIntFrom2MagSign(twoMs) (((twoMs) & 1) ? -1 * (INT16)(((twoMs) + 1) >> 1) : (INT16)((twoMs) >> 1))
-
/*
* Update the passed parameter and clamp it to the range [0, KPMAX]
* Return the value of parameter right-shifted by LSGR
_k = (_param >> LSGR); \
}
-/* Outputs the Golomb/Rice encoding of a non-negative integer */
-#define GetGRCode(krp, kr, vk, _mag) \
- vk = 0; \
- _mag = 0; \
- /* chew up/count leading 1s and escape 0 */ \
- do { \
- GetBits(1, r); \
- if (r == 1) \
- vk++; \
- else \
- break; \
- } while (1); \
- /* get next *kr bits, and combine with leading 1s */ \
- GetBits(*kr, _mag); \
- _mag |= (vk << *kr); \
- /* adjust krp and kr based on vk */ \
- if (!vk) { \
- UpdateParam(*krp, -2, *kr); \
- } \
- else if (vk != 1) { \
- UpdateParam(*krp, vk, *kr); /* at 1, no change! */ \
- }
+static BOOL g_LZCNT = FALSE;
-int rfx_rlgr_decode(RLGR_MODE mode, const BYTE* data, int data_size, INT16* buffer, int buffer_size)
+static INLINE UINT32 lzcnt_s(UINT32 x)
{
- int k;
- int kp;
- int kr;
- int krp;
- UINT16 r;
- INT16* dst;
- RFX_BITSTREAM* bs;
-
- int vk;
- UINT16 mag16;
+ if (!x)
+ return 32;
+
+ if (!g_LZCNT)
+ {
+ UINT32 y;
+ int n = 32;
+ y = x >> 16; if (y != 0) { n = n - 16; x = y; }
+ y = x >> 8; if (y != 0) { n = n - 8; x = y; }
+ y = x >> 4; if (y != 0) { n = n - 4; x = y; }
+ y = x >> 2; if (y != 0) { n = n - 2; x = y; }
+ y = x >> 1; if (y != 0) return n - 2;
+ return n - x;
+ }
- bs = (RFX_BITSTREAM*) malloc(sizeof(RFX_BITSTREAM));
- ZeroMemory(bs, sizeof(RFX_BITSTREAM));
+ return __lzcnt(x);
+}
- rfx_bitstream_attach(bs, data, data_size);
- dst = buffer;
+int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT32 DstSize, int mode)
+{
+ int vk;
+ int run;
+ int cnt;
+ int size;
+ int nbits;
+ int offset;
+ INT16 mag;
+ int k, kp;
+ int kr, krp;
+ UINT16 code;
+ UINT32 sign;
+ UINT32 nIdx;
+ UINT32 val1;
+ UINT32 val2;
+ INT16* pOutput;
+ wBitStream* bs;
+ wBitStream s_bs;
+
+ g_LZCNT = IsProcessorFeaturePresentEx(PF_EX_LZCNT);
- /* initialize the parameters */
k = 1;
kp = k << LSGR;
+
kr = 1;
krp = kr << LSGR;
- while (!rfx_bitstream_eos(bs) && buffer_size > 0)
+ if ((mode != 1) && (mode != 3))
+ mode = 1;
+
+ if (!pSrcData || !SrcSize)
+ return -1;
+
+ if (!pDstData || !DstSize)
+ return -1;
+
+ pOutput = pDstData;
+
+ bs = &s_bs;
+
+ BitStream_Attach(bs, pSrcData, SrcSize);
+ BitStream_Fetch(bs);
+
+ while ((BitStream_GetRemainingLength(bs) > 0) && ((pOutput - pDstData) < DstSize))
{
- int run;
if (k)
{
- int mag;
- UINT32 sign;
+ /* Run-Length (RL) Mode */
+
+ run = 0;
+
+ /* count number of leading 0s */
+
+ cnt = lzcnt_s(bs->accumulator);
+
+ nbits = BitStream_GetRemainingLength(bs);
- /* RL MODE */
- while (!rfx_bitstream_eos(bs))
+ if (cnt > nbits)
+ cnt = nbits;
+
+ vk = cnt;
+
+ while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
{
- GetBits(1, r);
- if (r)
- break;
- /* we have an RL escape "0", which translates to a run (1<<k) of zeros */
- WriteZeroes(1 << k);
- UpdateParam(kp, UP_GR, k); /* raise k and kp up because of zero run */
+ BitStream_Shift32(bs);
+
+ cnt = lzcnt_s(bs->accumulator);
+
+ nbits = BitStream_GetRemainingLength(bs);
+
+ if (cnt > nbits)
+ cnt = nbits;
+
+ vk += cnt;
+ }
+
+ BitStream_Shift(bs, (vk % 32));
+
+ if (BitStream_GetRemainingLength(bs) < 1)
+ break;
+
+ BitStream_Shift(bs, 1);
+
+ while (vk--)
+ {
+ run += (1 << k); /* add (1 << k) to run length */
+
+ /* update k, kp params */
+
+ kp += UP_GR;
+
+ if (kp > KPMAX)
+ kp = KPMAX;
+
+ k = kp >> LSGR;
+ }
+
+ /* next k bits contain run length remainder */
+
+ if (BitStream_GetRemainingLength(bs) < k)
+ break;
+
+ bs->mask = ((1 << k) - 1);
+ run += ((bs->accumulator >> (32 - k)) & bs->mask);
+ BitStream_Shift(bs, k);
+
+ /* read sign bit */
+
+ if (BitStream_GetRemainingLength(bs) < 1)
+ break;
+
+ sign = (bs->accumulator & 0x80000000) ? 1 : 0;
+ BitStream_Shift(bs, 1);
+
+ /* count number of leading 1s */
+
+ cnt = lzcnt_s(~(bs->accumulator));
+
+ nbits = BitStream_GetRemainingLength(bs);
+
+ if (cnt > nbits)
+ cnt = nbits;
+
+ vk = cnt;
+
+ while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
+ {
+ BitStream_Shift32(bs);
+
+ cnt = lzcnt_s(~(bs->accumulator));
+
+ nbits = BitStream_GetRemainingLength(bs);
+
+ if (cnt > nbits)
+ cnt = nbits;
+
+ vk += cnt;
}
- /* next k bits will contain remaining run or zeros */
- GetBits(k, run);
- WriteZeroes(run);
+ BitStream_Shift(bs, (vk % 32));
+
+ if (BitStream_GetRemainingLength(bs) < 1)
+ break;
+
+ BitStream_Shift(bs, 1);
+
+ /* next kr bits contain code remainder */
+
+ if (BitStream_GetRemainingLength(bs) < kr)
+ break;
+
+ bs->mask = ((1 << kr) - 1);
+ code = (UINT16) ((bs->accumulator >> (32 - kr)) & bs->mask);
+ BitStream_Shift(bs, kr);
+
+ /* add (vk << kr) to code */
+
+ code |= (vk << kr);
+
+ if (!vk)
+ {
+ /* update kr, krp params */
+
+ krp -= 2;
+
+ if (krp < 0)
+ krp = 0;
+
+ kr = krp >> LSGR;
+ }
+ else if (vk != 1)
+ {
+ /* update kr, krp params */
- /* get nonzero value, starting with sign bit and then GRCode for magnitude -1 */
- GetBits(1, sign);
+ krp += vk;
- /* magnitude - 1 was coded (because it was nonzero) */
- GetGRCode(&krp, &kr, vk, mag16)
- mag = (int) (mag16 + 1);
+ if (krp > KPMAX)
+ krp = KPMAX;
- WriteValue(sign ? -mag : mag);
- UpdateParam(kp, -DN_GR, k); /* lower k and kp because of nonzero term */
+ kr = krp >> LSGR;
+ }
+
+ /* update k, kp params */
+
+ kp -= DN_GR;
+
+ if (kp < 0)
+ kp = 0;
+
+ k = kp >> LSGR;
+
+ /* compute magnitude from code */
+
+ if (sign)
+ mag = ((INT16) (code + 1)) * -1;
+ else
+ mag = (INT16) (code + 1);
+
+ /* write to output stream */
+
+ offset = (int) (pOutput - pDstData);
+ size = run;
+
+ if ((offset + size) > DstSize)
+ size = DstSize - offset;
+
+ if (size)
+ {
+ ZeroMemory(pOutput, size * sizeof(INT16));
+ pOutput += size;
+ }
+
+ if ((pOutput - pDstData) < DstSize)
+ {
+ *pOutput = mag;
+ pOutput++;
+ }
}
else
{
- UINT32 mag;
- UINT32 nIdx;
- UINT32 val1;
- UINT32 val2;
+ /* Golomb-Rice (GR) Mode */
- /* GR (GOLOMB-RICE) MODE */
- GetGRCode(&krp, &kr, vk, mag16) /* values coded are 2 * magnitude - sign */
- mag = (UINT32) mag16;
+ /* count number of leading 1s */
- if (mode == RLGR1)
+ cnt = lzcnt_s(~(bs->accumulator));
+
+ nbits = BitStream_GetRemainingLength(bs);
+
+ if (cnt > nbits)
+ cnt = nbits;
+
+ vk = cnt;
+
+ while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
+ {
+ BitStream_Shift32(bs);
+
+ cnt = lzcnt_s(~(bs->accumulator));
+
+ nbits = BitStream_GetRemainingLength(bs);
+
+ if (cnt > nbits)
+ cnt = nbits;
+
+ vk += cnt;
+ }
+
+ BitStream_Shift(bs, (vk % 32));
+
+ if (BitStream_GetRemainingLength(bs) < 1)
+ break;
+
+ BitStream_Shift(bs, 1);
+
+ /* next kr bits contain code remainder */
+
+ if (BitStream_GetRemainingLength(bs) < kr)
+ break;
+
+ bs->mask = ((1 << kr) - 1);
+ code = (UINT16) ((bs->accumulator >> (32 - kr)) & bs->mask);
+ BitStream_Shift(bs, kr);
+
+ /* add (vk << kr) to code */
+
+ code |= (vk << kr);
+
+ if (!vk)
{
- if (!mag)
+ /* update kr, krp params */
+
+ krp -= 2;
+
+ if (krp < 0)
+ krp = 0;
+
+ kr = krp >> LSGR;
+ }
+ else if (vk != 1)
+ {
+ /* update kr, krp params */
+
+ krp += vk;
+
+ if (krp > KPMAX)
+ krp = KPMAX;
+
+ kr = krp >> LSGR;
+ }
+
+ if (mode == 1) /* RLGR1 */
+ {
+ if (!code)
{
- WriteValue(0);
- UpdateParam(kp, UQ_GR, k); /* raise k and kp due to zero */
+ /* update k, kp params */
+
+ kp += UQ_GR;
+
+ if (kp > KPMAX)
+ kp = KPMAX;
+
+ k = kp >> LSGR;
+
+ mag = 0;
}
else
{
- WriteValue(GetIntFrom2MagSign(mag));
- UpdateParam(kp, -DQ_GR, k); /* lower k and kp due to nonzero */
+ /* update k, kp params */
+
+ kp -= DQ_GR;
+
+ if (kp < 0)
+ kp = 0;
+
+ k = kp >> LSGR;
+
+ /*
+ * code = 2 * mag - sign
+ * sign + code = 2 * mag
+ */
+
+ if (code & 1)
+ mag = ((INT16) ((code + 1) >> 1)) * -1;
+ else
+ mag = (INT16) (code >> 1);
+ }
+
+ if ((pOutput - pDstData) < DstSize)
+ {
+ *pOutput = mag;
+ pOutput++;
}
}
- else /* mode == RLGR3 */
+ else if (mode == 3) /* RLGR3 */
{
- /*
- * In GR mode FOR RLGR3, we have encoded the
- * sum of two (2 * mag - sign) values
- */
+ nIdx = 0;
- /* maximum possible bits for first term */
- GetMinBits(mag, nIdx);
+ if (code)
+ {
+ mag = (UINT32) code;
+ nIdx = 32 - lzcnt_s(mag);
+ }
+
+ if (BitStream_GetRemainingLength(bs) < nIdx)
+ break;
- /* decode val1 is first term's (2 * mag - sign) value */
- GetBits(nIdx, val1);
+ bs->mask = ((1 << nIdx) - 1);
+ val1 = ((bs->accumulator >> (32 - nIdx)) & bs->mask);
+ BitStream_Shift(bs, nIdx);
- /* val2 is second term's (2 * mag - sign) value */
- val2 = mag - val1;
+ val2 = code - val1;
if (val1 && val2)
{
- /* raise k and kp if both terms nonzero */
- UpdateParam(kp, -2 * DQ_GR, k);
+ /* update k, kp params */
+
+ kp -= (2 * DQ_GR);
+
+ if (kp < 0)
+ kp = 0;
+
+ k = kp >> LSGR;
}
else if (!val1 && !val2)
{
- /* lower k and kp if both terms zero */
- UpdateParam(kp, 2 * UQ_GR, k);
+ /* update k, kp params */
+
+ kp += (2 * UQ_GR);
+
+ if (kp > KPMAX)
+ kp = KPMAX;
+
+ k = kp >> LSGR;
+ }
+
+ if (val1 & 1)
+ mag = ((INT16) ((val1 + 1) >> 1)) * -1;
+ else
+ mag = (INT16) (val1 >> 1);
+
+ if ((pOutput - pDstData) < DstSize)
+ {
+ *pOutput = mag;
+ pOutput++;
}
- WriteValue(GetIntFrom2MagSign(val1));
- WriteValue(GetIntFrom2MagSign(val2));
+ if (val2 & 1)
+ mag = ((INT16) ((val2 + 1) >> 1)) * -1;
+ else
+ mag = (INT16) (val2 >> 1);
+
+ if ((pOutput - pDstData) < DstSize)
+ {
+ *pOutput = mag;
+ pOutput++;
+ }
}
}
}
- free(bs);
+ offset = (int) (pOutput - pDstData);
+
+ if (offset < DstSize)
+ {
+ size = DstSize - offset;
+ ZeroMemory(pOutput, size * 2);
+ pOutput += size;
+ }
+
+ offset = (int) (pOutput - pDstData);
+
+ if (offset != DstSize)
+ return -1;
- return (dst - buffer);
+ return 1;
}
/* Returns the next coefficient (a signed int) to encode, from the input stream */
#include <freerdp/codec/rfx.h>
-int rfx_rlgr_decode(RLGR_MODE mode, const BYTE* data, int data_size, INT16* buffer, int buffer_size);
int rfx_rlgr_encode(RLGR_MODE mode, const INT16* data, int data_size, BYTE* buffer, int buffer_size);
#endif /* __RFX_RLGR_H */
} while(ptr < buf_end);
}
-static void rfx_quantization_decode_sse2(INT16* buffer, const UINT32* quantization_values)
+static void rfx_quantization_decode_sse2(INT16* buffer, const UINT32* quantVals)
{
_mm_prefetch_buffer((char*) buffer, 4096 * sizeof(INT16));
- rfx_quantization_decode_block_sse2(buffer, 4096, 5);
-
- rfx_quantization_decode_block_sse2(buffer, 1024, quantization_values[8] - 6); /* HL1 */
- rfx_quantization_decode_block_sse2(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
- rfx_quantization_decode_block_sse2(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
- rfx_quantization_decode_block_sse2(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
- rfx_quantization_decode_block_sse2(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
- rfx_quantization_decode_block_sse2(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
- rfx_quantization_decode_block_sse2(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
- rfx_quantization_decode_block_sse2(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
- rfx_quantization_decode_block_sse2(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */
- rfx_quantization_decode_block_sse2(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
+ rfx_quantization_decode_block_sse2(&buffer[0], 1024, quantVals[8] - 1); /* HL1 */
+ rfx_quantization_decode_block_sse2(&buffer[1024], 1024, quantVals[7] - 1); /* LH1 */
+ rfx_quantization_decode_block_sse2(&buffer[2048], 1024, quantVals[9] - 1); /* HH1 */
+ rfx_quantization_decode_block_sse2(&buffer[3072], 256, quantVals[5] - 1); /* HL2 */
+ rfx_quantization_decode_block_sse2(&buffer[3328], 256, quantVals[4] - 1); /* LH2 */
+ rfx_quantization_decode_block_sse2(&buffer[3584], 256, quantVals[6] - 1); /* HH2 */
+ rfx_quantization_decode_block_sse2(&buffer[3840], 64, quantVals[2] - 1); /* HL3 */
+ rfx_quantization_decode_block_sse2(&buffer[3904], 64, quantVals[1] - 1); /* LH3 */
+ rfx_quantization_decode_block_sse2(&buffer[3968], 64, quantVals[3] - 1); /* HH3 */
+ rfx_quantization_decode_block_sse2(&buffer[4032], 64, quantVals[0] - 1); /* LL3 */
}
static __inline void __attribute__((ATTRIBUTES))
{
_mm_prefetch_buffer((char*) buffer, 4096 * sizeof(INT16));
- rfx_dwt_2d_decode_block_sse2(buffer + 3840, dwt_buffer, 8);
- rfx_dwt_2d_decode_block_sse2(buffer + 3072, dwt_buffer, 16);
- rfx_dwt_2d_decode_block_sse2(buffer, dwt_buffer, 32);
+ rfx_dwt_2d_decode_block_sse2(&buffer[3840], dwt_buffer, 8);
+ rfx_dwt_2d_decode_block_sse2(&buffer[3072], dwt_buffer, 16);
+ rfx_dwt_2d_decode_block_sse2(&buffer[0], dwt_buffer, 32);
}
static __inline void __attribute__((ATTRIBUTES))
TestFreeRDPCodecZGfx.c
TestFreeRDPCodecPlanar.c
TestFreeRDPCodecClear.c
+ TestFreeRDPCodecProgressive.c
TestFreeRDPCodecRemoteFX.c)
create_test_sourcelist(${MODULE_PREFIX}_SRCS
#include <freerdp/freerdp.h>
#include <freerdp/codec/mppc.h>
+#include <freerdp/log.h>
static BYTE TEST_RDP5_COMPRESSED_DATA[] =
{
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)
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;
}
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)
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;
}
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);
}
mppc_context_free(mppc);
-
return 0;
}
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);
}
mppc_context_free(mppc);
-
return 0;
}
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)
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;
}
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)
}
mppc_context_free(mppc);
-
return 0;
}
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);
}
mppc_context_free(mppc);
-
return 0;
}
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;
}
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);
}
ncrush_context_free(ncrush);
-
return 1;
}
#include <freerdp/freerdp.h>
#include <freerdp/codec/color.h>
#include <freerdp/codec/bitmap.h>
+#include <freerdp/codec/planar.h>
/**
* Experimental Case 01: 64x64 (32bpp)
{ 0x01, 0x67, 0x8B, 0xA3, 0x78, 0xAF }
};
-#include "../planar.h"
-
-static unsigned long next = 1;
-
-static int simple_rand(void)
-{
- next = next * 1103515245 + 12345;
- return ((unsigned int) (next / 65536) % 32768);
-}
-
static void fill_bitmap_alpha_channel(BYTE* data, int width, int height, BYTE value)
{
int i, j;
for (j = 0; j < width; j++)
{
printf("%02X%s", *data,
- ((j + 1) == width)? "\n" : " ");
+ ((j + 1) == width)? "\n" : " ");
data += 4;
}
}
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]))
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;
}
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]))
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;
}
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]))
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;
}
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;
}
int TestFreeRDPCodecPlanar(int argc, char* argv[])
{
- int i, j;
+ int i;
int dstSize;
UINT32 format;
+ BYTE* pDstData;
HCLRCONV clrconv;
DWORD planarFlags;
BYTE* srcBitmap32;
int width, height;
BYTE* blackBitmap;
BYTE* whiteBitmap;
- BYTE* randomBitmap;
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);
- if (!bitmap_decompress(compressedBitmap, decompressedBitmap, width, height, dstSize, 32, 32))
+ pDstData = decompressedBitmap;
+
+ if (planar_decompress(planar, compressedBitmap, dstSize, &pDstData,
+ PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height) < 0)
{
printf("failed to decompress white bitmap: width: %d height: %d\n", width, height);
return -1;
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;
}
{
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);
- if (!bitmap_decompress(compressedBitmap, decompressedBitmap, width, height, dstSize, 32, 32))
+ pDstData = decompressedBitmap;
+
+ if (planar_decompress(planar, compressedBitmap, dstSize, &pDstData,
+ PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height) < 0)
{
printf("failed to decompress black bitmap: width: %d height: %d\n", width, height);
return -1;
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;
}
free(decompressedBitmap);
}
- for (i = 4; i < 64; i += 4)
- {
- width = i;
- height = i;
-
- randomBitmap = (BYTE*) malloc(width * height * 4);
-
- for (j = 0; j < width * height * 4; j++)
- {
- randomBitmap[j] = (BYTE) (simple_rand() % 256);
- }
-
- fill_bitmap_alpha_channel(randomBitmap, width, height, 0x00);
-
- compressedBitmap = freerdp_bitmap_compress_planar(planar, randomBitmap, format, width, height, width * 4, NULL, &dstSize);
-
- decompressedBitmap = (BYTE*) malloc(width * height * 4);
- ZeroMemory(decompressedBitmap, width * height * 4);
-
- if (!bitmap_decompress(compressedBitmap, decompressedBitmap, width, height, dstSize, 32, 32))
- {
- printf("failed to decompress random bitmap: width: %d height: %d\n", width, height);
- return -1;
- }
- else
- {
- printf("success decompressing random bitmap: width: %d height: %d\n", width, height);
- }
-
- if (memcmp(decompressedBitmap, randomBitmap, width * height * 4) != 0)
- {
- printf("random bitmap\n");
- winpr_HexDump(randomBitmap, width * height * 4);
-
- printf("decompressed bitmap\n");
- winpr_HexDump(decompressedBitmap, width * height * 4);
-
- printf("error decompressed random bitmap corrupted: width: %d height: %d\n", width, height);
- return -1;
- }
-
- free(compressedBitmap);
- free(decompressedBitmap);
- }
+ 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);
- if (!bitmap_decompress(compressedBitmap, decompressedBitmap, width, height, dstSize, 32, 32))
+ pDstData = decompressedBitmap;
+
+ if (planar_decompress(planar, compressedBitmap, dstSize, &pDstData,
+ PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height) < 0)
{
printf("failed to decompress experimental bitmap 01: width: %d height: %d\n", width, height);
return -1;
{
#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);
- if (!bitmap_decompress(compressedBitmap, decompressedBitmap, width, height, dstSize, 32, 32))
+ pDstData = decompressedBitmap;
+
+ if (planar_decompress(planar, compressedBitmap, dstSize, &pDstData,
+ PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height) < 0)
{
printf("failed to decompress experimental bitmap 02: width: %d height: %d\n", width, height);
return -1;
{
#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;
}
}
/* 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);
- if (!bitmap_decompress(compressedBitmap, decompressedBitmap, width, height, dstSize, 32, 32))
+ pDstData = decompressedBitmap;
+
+ if (planar_decompress(planar, compressedBitmap, dstSize, &pDstData,
+ PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height) < 0)
{
printf("failed to decompress experimental bitmap 03: width: %d height: %d\n", width, height);
return -1;
{
#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;
}
--- /dev/null
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/image.h>
+#include <winpr/print.h>
+#include <winpr/wlog.h>
+
+#include <freerdp/codec/region.h>
+
+#include <freerdp/codec/progressive.h>
+
+/**
+ * Microsoft Progressive Codec Sample Data
+ * (available under NDA only)
+ *
+ * <enc/dec>_<image#>_<quarter#>_<prog%>_<bitmap>.<type>
+ *
+ * readme.pdf
+ *
+ * bitmaps/
+ * 1920by1080-SampleImage1.bmp
+ * 1920by1080-SampleImage2.bmp
+ * 1920by1080-SampleImage3.bmp
+ *
+ * compress/
+ * enc_0_0_025_sampleimage1.bin
+ * enc_0_0_050_sampleimage1.bin
+ * enc_0_0_075_sampleimage1.bin
+ * enc_0_0_100_sampleimage1.bin
+ * enc_0_1_025_sampleimage1.bin
+ * enc_0_1_050_sampleimage1.bin
+ * enc_0_1_075_sampleimage1.bin
+ * enc_0_1_100_sampleimage1.bin
+ * enc_0_2_025_sampleimage1.bin
+ * enc_0_2_050_sampleimage1.bin
+ * enc_0_2_075_sampleimage1.bin
+ * enc_0_2_100_sampleimage1.bin
+ * enc_0_3_025_sampleimage1.bin
+ * enc_0_3_050_sampleimage1.bin
+ * enc_0_3_075_sampleimage1.bin
+ * enc_0_3_100_sampleimage1.bin
+ * enc_1_0_025_sampleimage2.bin
+ * enc_1_0_050_sampleimage2.bin
+ * enc_1_0_075_sampleimage2.bin
+ * enc_1_0_100_sampleimage2.bin
+ * enc_1_1_025_sampleimage2.bin
+ * enc_1_1_050_sampleimage2.bin
+ * enc_1_1_075_sampleimage2.bin
+ * enc_1_1_100_sampleimage2.bin
+ * enc_1_2_025_sampleimage2.bin
+ * enc_1_2_050_sampleimage2.bin
+ * enc_1_2_075_sampleimage2.bin
+ * enc_1_2_100_sampleimage2.bin
+ * enc_1_3_025_sampleimage2.bin
+ * enc_1_3_050_sampleimage2.bin
+ * enc_1_3_075_sampleimage2.bin
+ * enc_1_3_100_sampleimage2.bin
+ * enc_2_0_025_sampleimage3.bin
+ * enc_2_0_050_sampleimage3.bin
+ * enc_2_0_075_sampleimage3.bin
+ * enc_2_0_100_sampleimage3.bin
+ * enc_2_1_025_sampleimage3.bin
+ * enc_2_1_050_sampleimage3.bin
+ * enc_2_1_075_sampleimage3.bin
+ * enc_2_1_100_sampleimage3.bin
+ * enc_2_2_025_sampleimage3.bin
+ * enc_2_2_050_sampleimage3.bin
+ * enc_2_2_075_sampleimage3.bin
+ * enc_2_2_100_sampleimage3.bin
+ * enc_2_3_025_sampleimage3.bin
+ * enc_2_3_050_sampleimage3.bin
+ * enc_2_3_075_sampleimage3.bin
+ * enc_2_3_100_sampleimage3.bin
+ *
+ * decompress/
+ * dec_0_0_025_sampleimage1.bmp
+ * dec_0_0_050_sampleimage1.bmp
+ * dec_0_0_075_sampleimage1.bmp
+ * dec_0_0_100_sampleimage1.bmp
+ * dec_0_1_025_sampleimage1.bmp
+ * dec_0_1_050_sampleimage1.bmp
+ * dec_0_1_075_sampleimage1.bmp
+ * dec_0_1_100_sampleimage1.bmp
+ * dec_0_2_025_sampleimage1.bmp
+ * dec_0_2_050_sampleimage1.bmp
+ * dec_0_2_075_sampleimage1.bmp
+ * dec_0_2_100_sampleimage1.bmp
+ * dec_0_3_025_sampleimage1.bmp
+ * dec_0_3_050_sampleimage1.bmp
+ * dec_0_3_075_sampleimage1.bmp
+ * dec_0_3_100_sampleimage1.bmp
+ * dec_1_0_025_sampleimage2.bmp
+ * dec_1_0_050_sampleimage2.bmp
+ * dec_1_0_075_sampleimage2.bmp
+ * dec_1_0_100_sampleimage2.bmp
+ * dec_1_1_025_sampleimage2.bmp
+ * dec_1_1_050_sampleimage2.bmp
+ * dec_1_1_075_sampleimage2.bmp
+ * dec_1_1_100_sampleimage2.bmp
+ * dec_1_2_025_sampleimage2.bmp
+ * dec_1_2_050_sampleimage2.bmp
+ * dec_1_2_075_sampleimage2.bmp
+ * dec_1_2_100_sampleimage2.bmp
+ * dec_1_3_025_sampleimage2.bmp
+ * dec_1_3_050_sampleimage2.bmp
+ * dec_1_3_075_sampleimage2.bmp
+ * dec_1_3_100_sampleimage2.bmp
+ * dec_2_0_025_sampleimage3.bmp
+ * dec_2_0_050_sampleimage3.bmp
+ * dec_2_0_075_sampleimage3.bmp
+ * dec_2_0_100_sampleimage3.bmp
+ * dec_2_1_025_sampleimage3.bmp
+ * dec_2_1_050_sampleimage3.bmp
+ * dec_2_1_075_sampleimage3.bmp
+ * dec_2_1_100_sampleimage3.bmp
+ * dec_2_2_025_sampleimage3.bmp
+ * dec_2_2_050_sampleimage3.bmp
+ * dec_2_2_075_sampleimage3.bmp
+ * dec_2_2_100_sampleimage3.bmp
+ * dec_2_3_025_sampleimage3.bmp
+ * dec_2_3_050_sampleimage3.bmp
+ * dec_2_3_075_sampleimage3.bmp
+ * dec_2_3_100_sampleimage3.bmp
+ */
+
+struct _EGFX_SAMPLE_FILE
+{
+ BYTE* buffer;
+ UINT32 size;
+};
+typedef struct _EGFX_SAMPLE_FILE EGFX_SAMPLE_FILE;
+
+static int g_Width = 0;
+static int g_Height = 0;
+static int g_DstStep = 0;
+static BYTE* g_DstData = NULL;
+
+static void test_fill_image_alpha_channel(BYTE* data, int width, int height, BYTE value)
+{
+ int i, j;
+ UINT32* pixel;
+
+ for (i = 0; i < height; i++)
+ {
+ for (j = 0; j < width; j++)
+ {
+ pixel = (UINT32*) &data[((i * width) + j) * 4];
+ *pixel = ((*pixel & 0x00FFFFFF) | (value << 24));
+ }
+ }
+}
+
+static void* test_image_memset32(UINT32* ptr, UINT32 fill, size_t length)
+{
+ while (length--)
+ {
+ *ptr++ = fill;
+ }
+
+ return (void*) ptr;
+}
+
+static int test_image_fill(BYTE* pDstData, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, UINT32 color)
+{
+ int y;
+ UINT32* pDstPixel;
+
+ if (nDstStep < 0)
+ nDstStep = 4 * nWidth;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ pDstPixel = (UINT32*) &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
+ test_image_memset32(pDstPixel, color, nWidth);
+ }
+
+ return 1;
+}
+
+static int test_image_fill_quarter(BYTE* pDstData, int nDstStep, int nWidth, int nHeight, UINT32 color, int quarter)
+{
+ int x = 0;
+ int y = 0;
+ int width = 0;
+ int height = 0;
+
+ switch (quarter)
+ {
+ case 0:
+ x = 0;
+ y = 0;
+ width = nWidth / 2;
+ height = nHeight /2;
+ break;
+
+ case 1:
+ x = nWidth / 2;
+ y = nHeight / 2;
+ width = nWidth / 2;
+ height = nHeight /2;
+ break;
+
+ case 2:
+ x = 0;
+ y = nHeight / 2;
+ width = nWidth / 2;
+ height = nHeight /2;
+ break;
+
+ case 3:
+ x = nWidth / 2;
+ y = 0;
+ width = nWidth / 2;
+ height = nHeight /2;
+ break;
+ }
+
+ test_image_fill(pDstData, nDstStep, x, y, width, height, 0xFF000000);
+
+ return 1;
+}
+
+static int test_image_fill_unused_quarters(BYTE* pDstData, int nDstStep, int nWidth, int nHeight, UINT32 color, int quarter)
+{
+ return 1;
+
+ if (quarter == 0)
+ {
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 1);
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 2);
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 3);
+ }
+ else if (quarter == 1)
+ {
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 0);
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 2);
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 3);
+ }
+ else if (quarter == 2)
+ {
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 0);
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 1);
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 3);
+ }
+ else if (quarter == 3)
+ {
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 0);
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 1);
+ test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 2);
+ }
+
+ return 1;
+}
+
+BYTE* test_progressive_load_file(char* path, char* file, UINT32* size)
+{
+ FILE* fp;
+ BYTE* buffer;
+ char* filename;
+
+ filename = GetCombinedPath(path, file);
+
+ fp = fopen(filename, "r");
+
+ if (!fp)
+ return NULL;
+
+ fseek(fp, 0, SEEK_END);
+ *size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ buffer = (BYTE*) malloc(*size);
+
+ if (!buffer)
+ return NULL;
+
+ if (fread(buffer, *size, 1, fp) != 1)
+ return NULL;
+
+ free(filename);
+ fclose(fp);
+
+ return buffer;
+}
+
+int test_progressive_load_files(char* ms_sample_path, EGFX_SAMPLE_FILE files[3][4][4])
+{
+ int imageNo = 0;
+ int quarterNo = 0;
+ int passNo = 0;
+
+ /* image 1 */
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_0_025_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_0_050_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_0_075_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_0_100_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_1_025_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_1_050_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_1_075_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_1_100_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_2_025_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_2_050_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_2_075_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_2_100_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_3_025_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_3_050_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_3_075_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_0_3_100_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ imageNo++;
+
+ /* image 2 */
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_0_025_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_0_050_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_0_075_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_0_100_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_1_025_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_1_050_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_1_075_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_1_100_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_2_025_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_2_050_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_2_075_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_2_100_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_3_025_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_3_050_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_3_075_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_1_3_100_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ imageNo++;
+
+ /* image 3 */
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_0_025_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_0_050_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_0_075_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_0_100_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_1_025_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_1_050_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_1_075_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_1_100_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_2_025_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_2_050_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_2_075_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_2_100_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_3_025_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_3_050_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_3_075_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path,
+ "compress/enc_2_3_100_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size));
+ passNo = (passNo + 1) % 4;
+
+ /* check if all test data has been loaded */
+
+ for (imageNo = 0; imageNo < 3; imageNo++)
+ {
+ for (quarterNo = 0; quarterNo < 4; quarterNo++)
+ {
+ for (passNo = 0; passNo < 4; passNo++)
+ {
+ if (!files[imageNo][quarterNo][passNo].buffer)
+ return -1;
+ }
+ }
+ }
+
+ return 1;
+}
+
+BYTE* test_progressive_load_bitmap(char* path, char* file, UINT32* size, int quarter)
+{
+ int status;
+ BYTE* buffer;
+ wImage* image;
+ char* filename;
+
+ filename = GetCombinedPath(path, file);
+
+ if (!filename)
+ return NULL;
+
+ image = winpr_image_new();
+
+ if (!image)
+ return NULL;
+
+ status = winpr_image_read(image, filename);
+
+ if (status < 0)
+ return NULL;
+
+ buffer = image->data;
+ *size = image->height * image->scanline;
+
+ test_fill_image_alpha_channel(image->data, image->width, image->height, 0xFF);
+ test_image_fill_unused_quarters(image->data, image->scanline, image->width, image->height, quarter, 0xFF000000);
+
+ winpr_image_free(image, FALSE);
+ free(filename);
+
+ return buffer;
+}
+
+int test_progressive_load_bitmaps(char* ms_sample_path, EGFX_SAMPLE_FILE bitmaps[3][4][4])
+{
+ int imageNo = 0;
+ int quarterNo = 0;
+ int passNo = 0;
+
+ /* image 1 */
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_0_025_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_0_050_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_0_075_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_0_100_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_1_025_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_1_050_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_1_075_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_1_100_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_2_025_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_2_050_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_2_075_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_2_100_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_3_025_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_3_050_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_3_075_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_0_3_100_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ imageNo++;
+
+ /* image 2 */
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_0_025_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_0_050_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_0_075_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_0_100_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_1_025_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_1_050_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_1_075_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_1_100_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_2_025_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_2_050_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_2_075_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_2_100_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_3_025_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_3_050_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_3_075_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_1_3_100_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ imageNo++;
+
+ /* image 3 */
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_0_025_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_0_050_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_0_075_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_0_100_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_1_025_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_1_050_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_1_075_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_1_100_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_2_025_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_2_050_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_2_075_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_2_100_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ quarterNo = (quarterNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_3_025_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_3_050_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_3_075_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path,
+ "decompress/dec_2_3_100_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo);
+ passNo = (passNo + 1) % 4;
+
+ /* check if all test data has been loaded */
+
+ for (imageNo = 0; imageNo < 3; imageNo++)
+ {
+ for (quarterNo = 0; quarterNo < 4; quarterNo++)
+ {
+ for (passNo = 0; passNo < 4; passNo++)
+ {
+ if (!bitmaps[imageNo][quarterNo][passNo].buffer)
+ return -1;
+ }
+ }
+ }
+
+ return 1;
+}
+
+static int test_memcmp_count(const BYTE* mem1, const BYTE* mem2, int size, int margin)
+{
+ int error;
+ int count = 0;
+ int index = 0;
+
+ for (index = 0; index < size; index++)
+ {
+ if (*mem1 != *mem2)
+ {
+ error = (*mem1 > *mem2) ? *mem1 - *mem2 : *mem2 - *mem1;
+
+ if (error > margin)
+ count++;
+ }
+
+ mem1++;
+ mem2++;
+ }
+
+ return count;
+}
+
+int test_progressive_decode(PROGRESSIVE_CONTEXT* progressive, EGFX_SAMPLE_FILE files[4], EGFX_SAMPLE_FILE bitmaps[4], int quarter, int count)
+{
+ int cnt;
+ int pass;
+ int size;
+ int index;
+ int status;
+ int nXSrc, nYSrc;
+ int nXDst, nYDst;
+ int nWidth, nHeight;
+ RECTANGLE_16 tileRect;
+ RECTANGLE_16 updateRect;
+ RECTANGLE_16 clippingRect;
+ RFX_PROGRESSIVE_TILE* tile;
+ PROGRESSIVE_BLOCK_REGION* region;
+
+ clippingRect.left = 0;
+ clippingRect.top = 0;
+ clippingRect.right = g_Width;
+ clippingRect.bottom = g_Height;
+
+ for (pass = 0; pass < count; pass++)
+ {
+ status = progressive_decompress(progressive, files[pass].buffer, files[pass].size,
+ &g_DstData, PIXEL_FORMAT_XRGB32, g_DstStep, 0, 0, g_Width, g_Height, 0);
+
+ printf("ProgressiveDecompress: status: %d pass: %d\n", status, pass + 1);
+
+ region = &(progressive->region);
+
+ switch (quarter)
+ {
+ case 0:
+ clippingRect.left = 0;
+ clippingRect.top = 0;
+ clippingRect.right = g_Width / 2;
+ clippingRect.bottom = g_Height /2;
+ break;
+
+ case 1:
+ clippingRect.left = g_Width / 2;
+ clippingRect.top = g_Height / 2;
+ clippingRect.right = g_Width;
+ clippingRect.bottom = g_Height;
+ break;
+
+ case 2:
+ clippingRect.left = 0;
+ clippingRect.top = g_Height / 2;
+ clippingRect.right = g_Width / 2;
+ clippingRect.bottom = g_Height;
+ break;
+
+ case 3:
+ clippingRect.left = g_Width / 2;
+ clippingRect.top = 0;
+ clippingRect.right = g_Width;
+ clippingRect.bottom = g_Height / 2;
+ break;
+ }
+
+ for (index = 0; index < region->numTiles; index++)
+ {
+ tile = region->tiles[index];
+
+ tileRect.left = tile->x;
+ tileRect.top = tile->y;
+ tileRect.right = tile->x + tile->width;
+ tileRect.bottom = tile->y + tile->height;
+
+ rectangles_intersection(&tileRect, &clippingRect, &updateRect);
+
+ nXDst = updateRect.left;
+ nYDst = updateRect.top;
+ nWidth = updateRect.right - updateRect.left;
+ nHeight = updateRect.bottom - updateRect.top;
+
+ if ((nWidth <= 0) || (nHeight <= 0))
+ continue;
+
+ nXSrc = nXDst - tile->x;
+ nYSrc = nYDst - tile->y;
+
+ freerdp_image_copy(g_DstData, PIXEL_FORMAT_XRGB32, g_DstStep,
+ nXDst, nYDst, nWidth, nHeight, tile->data,
+ PIXEL_FORMAT_XRGB32, 64 * 4, nXSrc, nYSrc);
+ }
+
+ size = bitmaps[pass].size;
+ cnt = test_memcmp_count(g_DstData, bitmaps[pass].buffer, size, 1);
+
+ if (cnt)
+ {
+ float rate = ((float) cnt) / ((float) size) * 100.0f;
+ printf("Progressive RemoteFX decompression failure\n");
+ printf("Actual, Expected (%d/%d = %.3f%%):\n", cnt, size, rate);
+ }
+
+ //WLog_Image(progressive->log, WLOG_TRACE, g_DstData, g_Width, g_Height, 32);
+ }
+
+ return 1;
+}
+
+int test_progressive_ms_sample(char* ms_sample_path)
+{
+ int count;
+ int status;
+ EGFX_SAMPLE_FILE files[3][4][4];
+ EGFX_SAMPLE_FILE bitmaps[3][4][4];
+ PROGRESSIVE_CONTEXT* progressive;
+
+ g_Width = 1920;
+ g_Height = 1080;
+ g_DstStep = g_Width * 4;
+
+ ZeroMemory(files, sizeof(files));
+ ZeroMemory(bitmaps, sizeof(bitmaps));
+
+ status = test_progressive_load_files(ms_sample_path, files);
+
+ if (status < 0)
+ return -1;
+
+ status = test_progressive_load_bitmaps(ms_sample_path, bitmaps);
+
+ if (status < 0)
+ return -1;
+
+ count = 4;
+
+ progressive = progressive_context_new(FALSE);
+
+ g_DstData = _aligned_malloc(g_DstStep * g_Height, 16);
+
+ progressive_create_surface_context(progressive, 0, g_Width, g_Height);
+
+ /* image 1 */
+
+ if (1)
+ {
+ printf("\nSample Image 1\n");
+ test_image_fill(g_DstData, g_DstStep, 0, 0, g_Width, g_Height, 0xFF000000);
+ test_progressive_decode(progressive, files[0][0], bitmaps[0][0], 0, count);
+ test_progressive_decode(progressive, files[0][1], bitmaps[0][1], 1, count);
+ test_progressive_decode(progressive, files[0][2], bitmaps[0][2], 2, count);
+ test_progressive_decode(progressive, files[0][3], bitmaps[0][3], 3, count);
+ }
+
+ /* image 2 */
+
+ if (0)
+ {
+ printf("\nSample Image 2\n"); /* sample data is in incorrect order */
+ test_image_fill(g_DstData, g_DstStep, 0, 0, g_Width, g_Height, 0xFF000000);
+ test_progressive_decode(progressive, files[1][0], bitmaps[1][0], 0, count);
+ test_progressive_decode(progressive, files[1][1], bitmaps[1][1], 1, count);
+ test_progressive_decode(progressive, files[1][2], bitmaps[1][2], 2, count);
+ test_progressive_decode(progressive, files[1][3], bitmaps[1][3], 3, count);
+ }
+
+ /* image 3 */
+
+ if (0)
+ {
+ printf("\nSample Image 3\n"); /* sample data is in incorrect order */
+ test_image_fill(g_DstData, g_DstStep, 0, 0, g_Width, g_Height, 0xFF000000);
+ test_progressive_decode(progressive, files[2][0], bitmaps[2][0], 0, count);
+ test_progressive_decode(progressive, files[2][1], bitmaps[2][1], 1, count);
+ test_progressive_decode(progressive, files[2][2], bitmaps[2][2], 2, count);
+ test_progressive_decode(progressive, files[2][3], bitmaps[2][3], 3, count);
+ }
+
+ progressive_context_free(progressive);
+
+ _aligned_free(g_DstData);
+
+ return 0;
+}
+
+int TestFreeRDPCodecProgressive(int argc, char* argv[])
+{
+ char* ms_sample_path;
+
+ ms_sample_path = _strdup("/tmp/EGFX_PROGRESSIVE_MS_SAMPLE");
+
+ if (PathFileExistsA(ms_sample_path))
+ return test_progressive_ms_sample(ms_sample_path);
+
+ free(ms_sample_path);
+
+ return 0;
+}
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;
}
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;
}
{
//if (test_XCrushCompressBells() < 0)
// return -1;
-
if (test_XCrushCompressIsland() < 0)
return -1;
OriginalData[1] = (BYTE) Level2ComprFlags;
#if 0
- printf("XCrushCompress: Level1ComprFlags: %s Level2ComprFlags: %s\n",
+ DEBUG_MSG("XCrushCompress: Level1ComprFlags: %s Level2ComprFlags: %s\n",
xcrush_get_level_1_compression_flags_string(Level1ComprFlags),
xcrush_get_level_2_compression_flags_string(Level2ComprFlags));
#endif
#include <openssl/rand.h>
#include <openssl/engine.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/client/file.h>
#include <freerdp/client/cmdline.h>
{
char* p;
char* q;
+ int port;
char* str;
size_t length;
p += length;
}
+ p = strstr(p, "<L P=\"");
+
+ while (p)
+ {
+ p += sizeof("<L P=\"") - 1;
+
+ q = strchr(p, '"');
+
+ if (!q)
+ return -1;
+
+ q[0] = '\0';
+ q++;
+
+ port = atoi(p);
+
+ p = strstr(q, " N=\"");
+
+ if (!p)
+ return -1;
+
+ p += sizeof(" N=\"") - 1;
+
+ q = strchr(p, '"');
+
+ if (!q)
+ return -1;
+
+ q[0] = '\0';
+ q++;
+
+ length = strlen(p);
+
+ if (length > 8)
+ {
+ if (strncmp(p, "169.254.", 8) != 0)
+ {
+ file->MachineAddress = _strdup(p);
+ file->MachinePort = (UINT32) port;
+ break;
+ }
+ }
+
+ p = strstr(q, "<L P=\"");
+ }
+
free(str);
return 1;
return ExpertBlob;
}
+char* freerdp_assistance_generate_pass_stub(DWORD flags)
+{
+ UINT32 nums[14];
+ char* passStub = NULL;
+ char set1[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*_";
+ char set2[12] = "!@#$&^*()-+=";
+ char set3[10] = "0123456789";
+ char set4[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ char set5[26] = "abcdefghijklmnopqrstuvwxyz";
+
+ passStub = (char*) malloc(15);
+
+ if (!passStub)
+ return NULL;
+
+ /**
+ * PassStub generation:
+ *
+ * Characters 0 and 5-13 are from the set A-Z a-z 0-9 * _
+ * Character 1 is from the set !@#$&^*()-+=
+ * Character 2 is from the set 0-9
+ * Character 3 is from the set A-Z
+ * Character 4 is from the set a-z
+ *
+ * Example: WB^6HsrIaFmEpi
+ */
+
+ RAND_bytes((BYTE*) nums, sizeof(nums));
+
+ passStub[0] = set1[nums[0] % sizeof(set1)]; /* character 0 */
+ passStub[1] = set2[nums[1] % sizeof(set2)]; /* character 1 */
+ passStub[2] = set3[nums[2] % sizeof(set3)]; /* character 2 */
+ passStub[3] = set4[nums[3] % sizeof(set4)]; /* character 3 */
+ passStub[4] = set5[nums[4] % sizeof(set5)]; /* character 4 */
+ passStub[5] = set1[nums[5] % sizeof(set1)]; /* character 5 */
+ passStub[6] = set1[nums[6] % sizeof(set1)]; /* character 6 */
+ passStub[7] = set1[nums[7] % sizeof(set1)]; /* character 7 */
+ passStub[8] = set1[nums[8] % sizeof(set1)]; /* character 8 */
+ passStub[9] = set1[nums[9] % sizeof(set1)]; /* character 9 */
+ passStub[10] = set1[nums[10] % sizeof(set1)]; /* character 10 */
+ passStub[11] = set1[nums[11] % sizeof(set1)]; /* character 11 */
+ passStub[12] = set1[nums[12] % sizeof(set1)]; /* character 12 */
+ passStub[13] = set1[nums[13] % sizeof(set1)]; /* character 13 */
+ passStub[14] = '\0';
+
+ return passStub;
+}
+
BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub, int* pEncryptedSize)
{
int status;
if (!status)
{
- fprintf(stderr, "EVP_CipherInit_ex failure\n");
+ DEBUG_WARN( "EVP_CipherInit_ex failure\n");
return NULL;
}
if (!status)
{
- fprintf(stderr, "EVP_CipherInit_ex failure\n");
+ DEBUG_WARN( "EVP_CipherInit_ex failure\n");
return NULL;
}
if (!status)
{
- fprintf(stderr, "EVP_CipherUpdate failure\n");
+ DEBUG_WARN( "EVP_CipherUpdate failure\n");
return NULL;
}
if (!status)
{
- fprintf(stderr, "EVP_CipherFinal_ex failure\n");
+ DEBUG_WARN( "EVP_CipherFinal_ex failure\n");
return NULL;
}
if (status != 1)
{
- fprintf(stderr, "EVP_DecryptFinal_ex failure\n");
+ DEBUG_WARN( "EVP_DecryptFinal_ex failure\n");
return -1;
}
status = freerdp_assistance_parse_connection_string2(file);
- printf("freerdp_assistance_parse_connection_string2: %d\n", status);
+ DEBUG_MSG("freerdp_assistance_parse_connection_string2: %d\n", status);
return 1;
}
if (status < 0)
{
- fprintf(stderr, "freerdp_assistance_parse_connection_string1 failure: %d\n", status);
+ DEBUG_WARN( "freerdp_assistance_parse_connection_string1 failure: %d\n", status);
return -1;
}
#include <freerdp/settings.h>
#include <freerdp/freerdp.h>
+#include <freerdp/utils/debug.h>
int freerdp_addin_set_argument(ADDIN_ARGV* args, char* argument)
{
}
- fprintf(stderr, "%s: unknown device type %d\n", __FUNCTION__, device->Type);
+ DEBUG_WARN( "%s: unknown device type %d\n", __FUNCTION__, device->Type);
return NULL;
}
{
case FreeRDP_ServerMode:
return settings->ServerMode;
- break;
case FreeRDP_NetworkAutoDetect:
return settings->NetworkAutoDetect;
- break;
case FreeRDP_SupportAsymetricKeys:
return settings->SupportAsymetricKeys;
- break;
case FreeRDP_SupportErrorInfoPdu:
return settings->SupportErrorInfoPdu;
- break;
case FreeRDP_SupportStatusInfoPdu:
return settings->SupportStatusInfoPdu;
- break;
case FreeRDP_SupportMonitorLayoutPdu:
return settings->SupportMonitorLayoutPdu;
- break;
case FreeRDP_SupportGraphicsPipeline:
return settings->SupportGraphicsPipeline;
- break;
case FreeRDP_SupportDynamicTimeZone:
return settings->SupportDynamicTimeZone;
- break;
case FreeRDP_DisableEncryption:
return settings->DisableEncryption;
- break;
case FreeRDP_ConsoleSession:
return settings->ConsoleSession;
- break;
case FreeRDP_SpanMonitors:
return settings->SpanMonitors;
- break;
case FreeRDP_UseMultimon:
return settings->UseMultimon;
- break;
case FreeRDP_ForceMultimon:
return settings->ForceMultimon;
- break;
case FreeRDP_AutoLogonEnabled:
return settings->AutoLogonEnabled;
- break;
case FreeRDP_CompressionEnabled:
return settings->CompressionEnabled;
- break;
case FreeRDP_DisableCtrlAltDel:
return settings->DisableCtrlAltDel;
- break;
case FreeRDP_EnableWindowsKey:
return settings->EnableWindowsKey;
- break;
case FreeRDP_MaximizeShell:
return settings->MaximizeShell;
- break;
case FreeRDP_LogonNotify:
return settings->LogonNotify;
- break;
case FreeRDP_LogonErrors:
return settings->LogonErrors;
- break;
case FreeRDP_MouseAttached:
return settings->MouseAttached;
- break;
case FreeRDP_MouseHasWheel:
return settings->MouseHasWheel;
- break;
case FreeRDP_RemoteConsoleAudio:
return settings->RemoteConsoleAudio;
- break;
case FreeRDP_AudioPlayback:
return settings->AudioPlayback;
- break;
case FreeRDP_AudioCapture:
return settings->AudioCapture;
- break;
case FreeRDP_VideoDisable:
return settings->VideoDisable;
- break;
case FreeRDP_PasswordIsSmartcardPin:
return settings->PasswordIsSmartcardPin;
- break;
case FreeRDP_UsingSavedCredentials:
return settings->UsingSavedCredentials;
- break;
case FreeRDP_ForceEncryptedCsPdu:
return settings->ForceEncryptedCsPdu;
- break;
case FreeRDP_HiDefRemoteApp:
return settings->HiDefRemoteApp;
- break;
case FreeRDP_IPv6Enabled:
return settings->IPv6Enabled;
- break;
case FreeRDP_AutoReconnectionEnabled:
return settings->AutoReconnectionEnabled;
- break;
case FreeRDP_DynamicDaylightTimeDisabled:
return settings->DynamicDaylightTimeDisabled;
- break;
case FreeRDP_AllowFontSmoothing:
return settings->AllowFontSmoothing;
- break;
case FreeRDP_DisableWallpaper:
return settings->DisableWallpaper;
- break;
case FreeRDP_DisableFullWindowDrag:
return settings->DisableFullWindowDrag;
- break;
case FreeRDP_DisableMenuAnims:
return settings->DisableMenuAnims;
- break;
case FreeRDP_DisableThemes:
return settings->DisableThemes;
- break;
case FreeRDP_DisableCursorShadow:
return settings->DisableCursorShadow;
- break;
case FreeRDP_DisableCursorBlinking:
return settings->DisableCursorBlinking;
- break;
case FreeRDP_AllowDesktopComposition:
return settings->AllowDesktopComposition;
- break;
case FreeRDP_RemoteAssistanceMode:
return settings->RemoteAssistanceMode;
- break;
case FreeRDP_TlsSecurity:
return settings->TlsSecurity;
- break;
case FreeRDP_NlaSecurity:
return settings->NlaSecurity;
- break;
case FreeRDP_RdpSecurity:
return settings->RdpSecurity;
- break;
case FreeRDP_ExtSecurity:
return settings->ExtSecurity;
- break;
case FreeRDP_Authentication:
return settings->Authentication;
- break;
case FreeRDP_NegotiateSecurityLayer:
return settings->NegotiateSecurityLayer;
- break;
case FreeRDP_RestrictedAdminModeRequired:
return settings->RestrictedAdminModeRequired;
- break;
case FreeRDP_DisableCredentialsDelegation:
return settings->DisableCredentialsDelegation;
- break;
case FreeRDP_AuthenticationLevel:
return settings->AuthenticationLevel;
- break;
case FreeRDP_MstscCookieMode:
return settings->MstscCookieMode;
- break;
case FreeRDP_SendPreconnectionPdu:
return settings->SendPreconnectionPdu;
- break;
case FreeRDP_IgnoreCertificate:
return settings->IgnoreCertificate;
- break;
case FreeRDP_ExternalCertificateManagement:
return settings->ExternalCertificateManagement;
- break;
case FreeRDP_Workarea:
return settings->Workarea;
- break;
case FreeRDP_Fullscreen:
return settings->Fullscreen;
- break;
case FreeRDP_GrabKeyboard:
return settings->GrabKeyboard;
- break;
case FreeRDP_Decorations:
return settings->Decorations;
- break;
case FreeRDP_SmartSizing:
return settings->SmartSizing;
- break;
case FreeRDP_MouseMotion:
return settings->MouseMotion;
- break;
case FreeRDP_AsyncInput:
return settings->AsyncInput;
- break;
case FreeRDP_AsyncUpdate:
return settings->AsyncUpdate;
- break;
case FreeRDP_AsyncChannels:
return settings->AsyncChannels;
- break;
case FreeRDP_AsyncTransport:
return settings->AsyncTransport;
- break;
case FreeRDP_ToggleFullscreen:
return settings->ToggleFullscreen;
- break;
case FreeRDP_SoftwareGdi:
return settings->SoftwareGdi;
- break;
case FreeRDP_LocalConnection:
return settings->LocalConnection;
- break;
case FreeRDP_AuthenticationOnly:
return settings->AuthenticationOnly;
- break;
case FreeRDP_CredentialsFromStdin:
return settings->CredentialsFromStdin;
- break;
case FreeRDP_DumpRemoteFx:
return settings->DumpRemoteFx;
- break;
case FreeRDP_PlayRemoteFx:
return settings->PlayRemoteFx;
- break;
case FreeRDP_GatewayUseSameCredentials:
return settings->GatewayUseSameCredentials;
- break;
case FreeRDP_GatewayEnabled:
return settings->GatewayEnabled;
- break;
case FreeRDP_GatewayBypassLocal:
return settings->GatewayBypassLocal;
- break;
case FreeRDP_RemoteApplicationMode:
return settings->RemoteApplicationMode;
- break;
case FreeRDP_DisableRemoteAppCapsCheck:
return settings->DisableRemoteAppCapsCheck;
- break;
case FreeRDP_RemoteAppLanguageBarSupported:
return settings->RemoteAppLanguageBarSupported;
- break;
case FreeRDP_RefreshRect:
return settings->RefreshRect;
- break;
case FreeRDP_SuppressOutput:
return settings->SuppressOutput;
- break;
case FreeRDP_FastPathOutput:
return settings->FastPathOutput;
- break;
case FreeRDP_SaltedChecksum:
return settings->SaltedChecksum;
- break;
case FreeRDP_LongCredentialsSupported:
return settings->LongCredentialsSupported;
- break;
case FreeRDP_NoBitmapCompressionHeader:
return settings->NoBitmapCompressionHeader;
- break;
case FreeRDP_BitmapCompressionDisabled:
return settings->BitmapCompressionDisabled;
- break;
case FreeRDP_DesktopResize:
return settings->DesktopResize;
- break;
case FreeRDP_DrawAllowDynamicColorFidelity:
return settings->DrawAllowDynamicColorFidelity;
- break;
case FreeRDP_DrawAllowColorSubsampling:
return settings->DrawAllowColorSubsampling;
- break;
case FreeRDP_DrawAllowSkipAlpha:
return settings->DrawAllowSkipAlpha;
- break;
case FreeRDP_BitmapCacheV3Enabled:
return settings->BitmapCacheV3Enabled;
- break;
case FreeRDP_AltSecFrameMarkerSupport:
return settings->AltSecFrameMarkerSupport;
- break;
case FreeRDP_BitmapCacheEnabled:
return settings->BitmapCacheEnabled;
- break;
case FreeRDP_AllowCacheWaitingList:
return settings->AllowCacheWaitingList;
- break;
case FreeRDP_BitmapCachePersistEnabled:
return settings->BitmapCachePersistEnabled;
- break;
case FreeRDP_ColorPointerFlag:
return settings->ColorPointerFlag;
- break;
case FreeRDP_UnicodeInput:
return settings->UnicodeInput;
- break;
case FreeRDP_FastPathInput:
return settings->FastPathInput;
- break;
case FreeRDP_MultiTouchInput:
return settings->MultiTouchInput;
- break;
case FreeRDP_MultiTouchGestures:
return settings->MultiTouchGestures;
- break;
case FreeRDP_SoundBeepsEnabled:
return settings->SoundBeepsEnabled;
- break;
case FreeRDP_SurfaceCommandsEnabled:
return settings->SurfaceCommandsEnabled;
- break;
case FreeRDP_FrameMarkerCommandEnabled:
return settings->FrameMarkerCommandEnabled;
- break;
case FreeRDP_RemoteFxOnly:
return settings->RemoteFxOnly;
- break;
case FreeRDP_RemoteFxCodec:
return settings->RemoteFxCodec;
- break;
case FreeRDP_RemoteFxImageCodec:
return settings->RemoteFxImageCodec;
- break;
case FreeRDP_NSCodec:
return settings->NSCodec;
- break;
case FreeRDP_FrameAcknowledge:
return settings->FrameAcknowledge;
- break;
case FreeRDP_JpegCodec:
return settings->JpegCodec;
- break;
case FreeRDP_GfxThinClient:
return settings->GfxThinClient;
- break;
case FreeRDP_GfxSmallCache:
return settings->GfxSmallCache;
- break;
case FreeRDP_GfxProgressive:
return settings->GfxProgressive;
- break;
case FreeRDP_GfxProgressiveV2:
return settings->GfxProgressiveV2;
- break;
case FreeRDP_GfxH264:
return settings->GfxH264;
- break;
case FreeRDP_DrawNineGridEnabled:
return settings->DrawNineGridEnabled;
- break;
case FreeRDP_DrawGdiPlusEnabled:
return settings->DrawGdiPlusEnabled;
- break;
case FreeRDP_DrawGdiPlusCacheEnabled:
return settings->DrawGdiPlusCacheEnabled;
- break;
case FreeRDP_DeviceRedirection:
return settings->DeviceRedirection;
- break;
case FreeRDP_RedirectDrives:
return settings->RedirectDrives;
- break;
case FreeRDP_RedirectHomeDrive:
return settings->RedirectHomeDrive;
- break;
case FreeRDP_RedirectSmartCards:
return settings->RedirectSmartCards;
- break;
case FreeRDP_RedirectPrinters:
return settings->RedirectPrinters;
- break;
case FreeRDP_RedirectSerialPorts:
return settings->RedirectSerialPorts;
- break;
case FreeRDP_RedirectParallelPorts:
return settings->RedirectParallelPorts;
- break;
case FreeRDP_RedirectClipboard:
return settings->RedirectClipboard;
- break;
default:
- fprintf(stderr, "freerdp_get_param_bool: unknown id: %d\n", id);
+ DEBUG_WARN( "freerdp_get_param_bool: unknown id: %d\n", id);
return -1;
- break;
}
-
- return -1;
}
int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
break;
default:
- fprintf(stderr, "freerdp_set_param_bool: unknown id %d (param = %d)\n", id, param);
+ DEBUG_WARN( "freerdp_set_param_bool: unknown id %d (param = %d)\n", id, param);
return -1;
- break;
}
/* Mark field as modified */
{
case FreeRDP_XPan:
return settings->XPan;
- break;
case FreeRDP_YPan:
return settings->YPan;
- break;
default:
- fprintf(stderr, "freerdp_get_param_int: unknown id: %d\n", id);
+ DEBUG_WARN( "freerdp_get_param_int: unknown id: %d\n", id);
return 0;
- break;
}
-
- return 0;
}
int freerdp_set_param_int(rdpSettings* settings, int id, int param)
break;
default:
- fprintf(stderr, "freerdp_set_param_int: unknown id %d (param = %d)\n", id, param);
+ DEBUG_WARN( "freerdp_set_param_int: unknown id %d (param = %d)\n", id, param);
return -1;
- break;
}
settings->SettingsModified[id] = 1;
{
case FreeRDP_ShareId:
return settings->ShareId;
- break;
case FreeRDP_PduSource:
return settings->PduSource;
- break;
case FreeRDP_ServerPort:
return settings->ServerPort;
- break;
case FreeRDP_RdpVersion:
return settings->RdpVersion;
- break;
case FreeRDP_DesktopWidth:
return settings->DesktopWidth;
- break;
case FreeRDP_DesktopHeight:
return settings->DesktopHeight;
- break;
case FreeRDP_ColorDepth:
return settings->ColorDepth;
- break;
case FreeRDP_ConnectionType:
return settings->ConnectionType;
- break;
case FreeRDP_ClientBuild:
return settings->ClientBuild;
- break;
case FreeRDP_EarlyCapabilityFlags:
return settings->EarlyCapabilityFlags;
- break;
case FreeRDP_EncryptionMethods:
return settings->EncryptionMethods;
- break;
case FreeRDP_ExtEncryptionMethods:
return settings->ExtEncryptionMethods;
- break;
case FreeRDP_EncryptionLevel:
return settings->EncryptionLevel;
- break;
+
+ case FreeRDP_ServerRandomLength:
+ return settings->ServerRandomLength;
+
+ case FreeRDP_ClientRandomLength:
+ return settings->ClientRandomLength;
case FreeRDP_ChannelCount:
return settings->ChannelCount;
- break;
case FreeRDP_ChannelDefArraySize:
return settings->ChannelDefArraySize;
- break;
case FreeRDP_ClusterInfoFlags:
return settings->ClusterInfoFlags;
- break;
case FreeRDP_RedirectedSessionId:
return settings->RedirectedSessionId;
- break;
case FreeRDP_MonitorDefArraySize:
return settings->MonitorDefArraySize;
- break;
case FreeRDP_DesktopPosX:
return settings->DesktopPosX;
- break;
case FreeRDP_DesktopPosY:
return settings->DesktopPosY;
- break;
case FreeRDP_MultitransportFlags:
return settings->MultitransportFlags;
- break;
case FreeRDP_CompressionLevel:
return settings->CompressionLevel;
- break;
case FreeRDP_AutoReconnectMaxRetries:
return settings->AutoReconnectMaxRetries;
- break;
case FreeRDP_PerformanceFlags:
return settings->PerformanceFlags;
- break;
case FreeRDP_RequestedProtocols:
return settings->RequestedProtocols;
- break;
case FreeRDP_SelectedProtocol:
return settings->SelectedProtocol;
- break;
case FreeRDP_NegotiationFlags:
return settings->NegotiationFlags;
- break;
case FreeRDP_CookieMaxLength:
return settings->CookieMaxLength;
- break;
case FreeRDP_PreconnectionId:
return settings->PreconnectionId;
- break;
case FreeRDP_RedirectionFlags:
return settings->RedirectionFlags;
- break;
case FreeRDP_LoadBalanceInfoLength:
return settings->LoadBalanceInfoLength;
- break;
case FreeRDP_RedirectionPasswordLength:
return settings->RedirectionPasswordLength;
- break;
case FreeRDP_RedirectionTsvUrlLength:
return settings->RedirectionTsvUrlLength;
- break;
case FreeRDP_TargetNetAddressCount:
return settings->TargetNetAddressCount;
- break;
case FreeRDP_PercentScreen:
return settings->PercentScreen;
- break;
case FreeRDP_GatewayUsageMethod:
return settings->GatewayUsageMethod;
- break;
case FreeRDP_GatewayPort:
return settings->GatewayPort;
- break;
case FreeRDP_GatewayCredentialsSource:
return settings->GatewayCredentialsSource;
- break;
case FreeRDP_RemoteAppNumIconCaches:
return settings->RemoteAppNumIconCaches;
- break;
case FreeRDP_RemoteAppNumIconCacheEntries:
return settings->RemoteAppNumIconCacheEntries;
- break;
case FreeRDP_ReceivedCapabilitiesSize:
return settings->ReceivedCapabilitiesSize;
- break;
case FreeRDP_OsMajorType:
return settings->OsMajorType;
- break;
case FreeRDP_OsMinorType:
return settings->OsMinorType;
- break;
case FreeRDP_BitmapCacheVersion:
return settings->BitmapCacheVersion;
- break;
case FreeRDP_BitmapCacheV2NumCells:
return settings->BitmapCacheV2NumCells;
- break;
case FreeRDP_PointerCacheSize:
return settings->PointerCacheSize;
- break;
case FreeRDP_KeyboardLayout:
return settings->KeyboardLayout;
- break;
case FreeRDP_KeyboardType:
return settings->KeyboardType;
- break;
case FreeRDP_KeyboardSubType:
return settings->KeyboardSubType;
- break;
case FreeRDP_KeyboardFunctionKey:
return settings->KeyboardFunctionKey;
+
+ case FreeRDP_KeyboardHook:
+ return settings->KeyboardHook;
break;
case FreeRDP_BrushSupportLevel:
return settings->BrushSupportLevel;
- break;
case FreeRDP_GlyphSupportLevel:
return settings->GlyphSupportLevel;
- break;
case FreeRDP_OffscreenSupportLevel:
return settings->OffscreenSupportLevel;
- break;
case FreeRDP_OffscreenCacheSize:
return settings->OffscreenCacheSize;
- break;
case FreeRDP_OffscreenCacheEntries:
return settings->OffscreenCacheEntries;
- break;
case FreeRDP_VirtualChannelCompressionFlags:
return settings->VirtualChannelCompressionFlags;
- break;
case FreeRDP_VirtualChannelChunkSize:
return settings->VirtualChannelChunkSize;
- break;
case FreeRDP_MultifragMaxRequestSize:
return settings->MultifragMaxRequestSize;
- break;
case FreeRDP_LargePointerFlag:
return settings->LargePointerFlag;
- break;
case FreeRDP_CompDeskSupportLevel:
return settings->CompDeskSupportLevel;
- break;
case FreeRDP_RemoteFxCodecId:
return settings->RemoteFxCodecId;
- break;
case FreeRDP_RemoteFxCodecMode:
return settings->RemoteFxCodecMode;
- break;
case FreeRDP_NSCodecId:
return settings->NSCodecId;
- break;
case FreeRDP_JpegCodecId:
return settings->JpegCodecId;
- break;
case FreeRDP_JpegQuality:
return settings->JpegQuality;
- break;
case FreeRDP_BitmapCacheV3CodecId:
return settings->BitmapCacheV3CodecId;
- break;
case FreeRDP_DrawNineGridCacheSize:
return settings->DrawNineGridCacheSize;
- break;
case FreeRDP_DrawNineGridCacheEntries:
return settings->DrawNineGridCacheEntries;
- break;
case FreeRDP_DeviceCount:
return settings->DeviceCount;
- break;
case FreeRDP_DeviceArraySize:
return settings->DeviceArraySize;
- break;
case FreeRDP_StaticChannelCount:
return settings->StaticChannelCount;
- break;
case FreeRDP_StaticChannelArraySize:
return settings->StaticChannelArraySize;
- break;
case FreeRDP_DynamicChannelCount:
return settings->DynamicChannelCount;
- break;
case FreeRDP_DynamicChannelArraySize:
return settings->DynamicChannelArraySize;
- break;
default:
- fprintf(stderr, "freerdp_get_param_uint32: unknown id: %d\n", id);
+ DEBUG_WARN( "freerdp_get_param_uint32: unknown id: %d\n", id);
return 0;
- break;
}
-
- return 0;
}
int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
settings->EncryptionLevel = param;
break;
+ case FreeRDP_ServerRandomLength:
+ settings->ServerRandomLength = param;
+ break;
+
+ case FreeRDP_ClientRandomLength:
+ settings->ClientRandomLength = param;
+ break;
+
case FreeRDP_ChannelCount:
settings->ChannelCount = param;
break;
settings->KeyboardFunctionKey = param;
break;
+ case FreeRDP_KeyboardHook:
+ settings->KeyboardHook = param;
+ break;
+
case FreeRDP_BrushSupportLevel:
settings->BrushSupportLevel = param;
break;
break;
default:
- fprintf(stderr, "freerdp_set_param_uint32: unknown id %d (param = %u)\n", id, param);
+ DEBUG_WARN( "freerdp_set_param_uint32: unknown id %d (param = %u)\n", id, param);
return -1;
- break;
}
/* Mark field as modified */
{
case FreeRDP_ParentWindowId:
return settings->ParentWindowId;
- break;
default:
- fprintf(stderr, "freerdp_get_param_uint64: unknown id: %d\n", id);
+ DEBUG_WARN( "freerdp_get_param_uint64: unknown id: %d\n", id);
return -1;
- break;
}
-
- return 0;
}
int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
break;
default:
- fprintf(stderr, "freerdp_set_param_uint64: unknown id %d (param = %u)\n", id, (UINT32) param);
+ DEBUG_WARN( "freerdp_set_param_uint64: unknown id %d (param = %u)\n", id, (UINT32) param);
return -1;
- break;
}
/* Mark field as modified */
{
case FreeRDP_ServerHostname:
return settings->ServerHostname;
- break;
case FreeRDP_Username:
return settings->Username;
- break;
case FreeRDP_Password:
return settings->Password;
- break;
case FreeRDP_Domain:
return settings->Domain;
- break;
case FreeRDP_PasswordHash:
return settings->PasswordHash;
- break;
case FreeRDP_ClientHostname:
return settings->ClientHostname;
- break;
case FreeRDP_ClientProductId:
return settings->ClientProductId;
- break;
case FreeRDP_AlternateShell:
return settings->AlternateShell;
- break;
case FreeRDP_ShellWorkingDirectory:
return settings->ShellWorkingDirectory;
- break;
case FreeRDP_ClientAddress:
return settings->ClientAddress;
- break;
case FreeRDP_ClientDir:
return settings->ClientDir;
- break;
case FreeRDP_DynamicDSTTimeZoneKeyName:
return settings->DynamicDSTTimeZoneKeyName;
- break;
case FreeRDP_RemoteAssistanceSessionId:
return settings->RemoteAssistanceSessionId;
- break;
case FreeRDP_RemoteAssistancePassStub:
return settings->RemoteAssistancePassStub;
- break;
case FreeRDP_RemoteAssistancePassword:
return settings->RemoteAssistancePassword;
- break;
case FreeRDP_RemoteAssistanceRCTicket:
return settings->RemoteAssistanceRCTicket;
- break;
case FreeRDP_AuthenticationServiceClass:
return settings->AuthenticationServiceClass;
- break;
case FreeRDP_PreconnectionBlob:
return settings->PreconnectionBlob;
- break;
case FreeRDP_KerberosKdc:
return settings->KerberosKdc;
- break;
case FreeRDP_KerberosRealm:
return settings->KerberosRealm;
- break;
case FreeRDP_CertificateName:
return settings->CertificateName;
- break;
case FreeRDP_CertificateFile:
return settings->CertificateFile;
- break;
case FreeRDP_PrivateKeyFile:
return settings->PrivateKeyFile;
- break;
case FreeRDP_RdpKeyFile:
return settings->RdpKeyFile;
- break;
case FreeRDP_WindowTitle:
return settings->WindowTitle;
- break;
case FreeRDP_ComputerName:
return settings->ComputerName;
- break;
case FreeRDP_ConnectionFile:
return settings->ConnectionFile;
- break;
case FreeRDP_AssistanceFile:
return settings->AssistanceFile;
- break;
case FreeRDP_HomePath:
return settings->HomePath;
- break;
case FreeRDP_ConfigPath:
return settings->ConfigPath;
- break;
case FreeRDP_CurrentPath:
return settings->CurrentPath;
- break;
case FreeRDP_DumpRemoteFxFile:
return settings->DumpRemoteFxFile;
- break;
case FreeRDP_PlayRemoteFxFile:
return settings->PlayRemoteFxFile;
- break;
case FreeRDP_GatewayHostname:
return settings->GatewayHostname;
- break;
case FreeRDP_GatewayUsername:
return settings->GatewayUsername;
- break;
case FreeRDP_GatewayPassword:
return settings->GatewayPassword;
- break;
case FreeRDP_GatewayDomain:
return settings->GatewayDomain;
- break;
case FreeRDP_RemoteApplicationName:
return settings->RemoteApplicationName;
- break;
case FreeRDP_RemoteApplicationIcon:
return settings->RemoteApplicationIcon;
- break;
case FreeRDP_RemoteApplicationProgram:
return settings->RemoteApplicationProgram;
- break;
case FreeRDP_RemoteApplicationFile:
return settings->RemoteApplicationFile;
- break;
case FreeRDP_RemoteApplicationGuid:
return settings->RemoteApplicationGuid;
- break;
case FreeRDP_RemoteApplicationCmdLine:
return settings->RemoteApplicationCmdLine;
- break;
case FreeRDP_ImeFileName:
return settings->ImeFileName;
- break;
case FreeRDP_DrivesToRedirect:
return settings->DrivesToRedirect;
- break;
default:
- fprintf(stderr, "freerdp_get_param_string: unknown id: %d\n", id);
+ DEBUG_WARN( "freerdp_get_param_string: unknown id: %d\n", id);
return NULL;
- break;
}
-
- return NULL;
}
int freerdp_set_param_string(rdpSettings* settings, int id, const char* param)
break;
default:
- fprintf(stderr, "freerdp_set_param_string: unknown id %d (param = %s)\n", id, param);
+ DEBUG_WARN( "freerdp_set_param_string: unknown id %d (param = %s)\n", id, param);
return -1;
- break;
}
/* Mark field as modified */
{
case FreeRDP_ScalingFactor:
return settings->ScalingFactor;
- break;
default:
- fprintf(stderr, "freerdp_get_param_double: unknown id: %d\n", id);
+ DEBUG_WARN( "freerdp_get_param_double: unknown id: %d\n", id);
return 0;
- break;
}
-
- return 0;
}
int freerdp_set_param_double(rdpSettings* settings, int id, double param)
default:
return -1;
- break;
}
/* Mark field as modified */
client.h
server.c
server.h
+ codecs.c
metrics.c
capabilities.c
capabilities.h
#include "bulk.h"
+#define TAG "com.freerdp.core"
+
//#define WITH_BULK_DEBUG 1
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;
}
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)
{
- printf("compression/decompression failure\n");
+ DEBUG_MSG("compression/decompression failure\n");
return status;
}
if (_DstSize != SrcSize)
{
- printf("compression/decompression size mismatch: Actual: %d, Expected: %d\n", _DstSize, SrcSize);
+ DEBUG_MSG("compression/decompression size mismatch: Actual: %d, Expected: %d\n", _DstSize, SrcSize);
return -1;
}
if (memcmp(_pDstData, pSrcData, SrcSize) != 0)
{
- printf("compression/decompression input/output mismatch! flags: 0x%04X\n", _Flags);
-
+ DEBUG_MSG("compression/decompression input/output mismatch! flags: 0x%04X\n", _Flags);
#if 1
- printf("Actual:\n");
- winpr_HexDump(_pDstData, SrcSize);
-
- printf("Expected:\n");
- winpr_HexDump(pSrcData, SrcSize);
+ DEBUG_MSG("Actual:\n");
+ winpr_HexDump(TAG, WLOG_DEBUG, _pDstData, SrcSize);
+ DEBUG_MSG("Expected:\n");
+ winpr_HexDump(TAG, WLOG_DEBUG, pSrcData, SrcSize);
#endif
-
return -1;
}
UINT32 CompressedBytes;
UINT32 UncompressedBytes;
double CompressionRatio;
-
metrics = bulk->context->metrics;
-
bulk_compression_max_size(bulk);
type = flags & BULK_COMPRESSION_TYPE_MASK;
{
CompressedBytes = SrcSize;
UncompressedBytes = *pDstSize;
-
CompressionRatio = metrics_write_bytes(metrics, UncompressedBytes, CompressedBytes);
-
#ifdef WITH_BULK_DEBUG
{
- printf("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);
+ 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);
}
#endif
}
else
{
- fprintf(stderr, "Decompression failure!\n");
+ DEBUG_WARN("Decompression failure!\n");
}
return status;
UINT32 CompressedBytes;
UINT32 UncompressedBytes;
double CompressionRatio;
-
metrics = bulk->context->metrics;
if ((SrcSize <= 50) || (SrcSize >= 16384))
*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))
{
{
CompressedBytes = *pDstSize;
UncompressedBytes = SrcSize;
-
CompressionRatio = metrics_write_bytes(metrics, UncompressedBytes, CompressedBytes);
-
#ifdef WITH_BULK_DEBUG
{
- printf("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);
+ 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);
}
#endif
}
#if 0
+
if (bulk_compress_validate(bulk, pSrcData, SrcSize, ppDstData, pDstSize, pFlags) < 0)
status = -1;
-#endif
+#endif
return status;
}
{
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);
}
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;
}
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);
}
if (length < 24)
return FALSE;
- fprintf(stderr, "GeneralCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "GeneralCapabilitySet (length %d):\n", length);
Stream_Read_UINT16(s, osMajorType); /* osMajorType (2 bytes) */
Stream_Read_UINT16(s, osMinorType); /* osMinorType (2 bytes) */
Stream_Read_UINT8(s, refreshRectSupport); /* refreshRectSupport (1 byte) */
Stream_Read_UINT8(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */
- fprintf(stderr, "\tosMajorType: 0x%04X\n", osMajorType);
- fprintf(stderr, "\tosMinorType: 0x%04X\n", osMinorType);
- fprintf(stderr, "\tprotocolVersion: 0x%04X\n", protocolVersion);
- fprintf(stderr, "\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
- fprintf(stderr, "\tgeneralCompressionTypes: 0x%04X\n", generalCompressionTypes);
- fprintf(stderr, "\textraFlags: 0x%04X\n", extraFlags);
- fprintf(stderr, "\tupdateCapabilityFlag: 0x%04X\n", updateCapabilityFlag);
- fprintf(stderr, "\tremoteUnshareFlag: 0x%04X\n", remoteUnshareFlag);
- fprintf(stderr, "\tgeneralCompressionLevel: 0x%04X\n", generalCompressionLevel);
- fprintf(stderr, "\trefreshRectSupport: 0x%02X\n", refreshRectSupport);
- fprintf(stderr, "\tsuppressOutputSupport: 0x%02X\n", suppressOutputSupport);
+ DEBUG_WARN( "\tosMajorType: 0x%04X\n", osMajorType);
+ DEBUG_WARN( "\tosMinorType: 0x%04X\n", osMinorType);
+ DEBUG_WARN( "\tprotocolVersion: 0x%04X\n", protocolVersion);
+ DEBUG_WARN( "\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
+ DEBUG_WARN( "\tgeneralCompressionTypes: 0x%04X\n", generalCompressionTypes);
+ DEBUG_WARN( "\textraFlags: 0x%04X\n", extraFlags);
+ DEBUG_WARN( "\tupdateCapabilityFlag: 0x%04X\n", updateCapabilityFlag);
+ DEBUG_WARN( "\tremoteUnshareFlag: 0x%04X\n", remoteUnshareFlag);
+ DEBUG_WARN( "\tgeneralCompressionLevel: 0x%04X\n", generalCompressionLevel);
+ DEBUG_WARN( "\trefreshRectSupport: 0x%02X\n", refreshRectSupport);
+ DEBUG_WARN( "\tsuppressOutputSupport: 0x%02X\n", suppressOutputSupport);
return TRUE;
}
header = rdp_capability_set_start(s);
- drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
+ if (settings->DrawAllowSkipAlpha)
+ drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
+
+ if (settings->DrawAllowColorSubsampling)
+ drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY;
+
+ if (settings->DrawAllowDynamicColorFidelity)
+ drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING; /* currently unimplemented */
+
/* While bitmap_decode.c now implements YCoCg, in turning it
* on we have found Microsoft is inconsistent on whether to invert R & B.
* And it's not only from one server to another; on Win7/2008R2, it appears
* will not send it. YCoCg is still needed for EGFX, but it at least
* appears consistent in its use.
*/
- /* drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY; */
- /* YCoCg with chroma subsampling is not implemented in bitmap_decode.c. */
- /* drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING; */
if (settings->RdpVersion > 5)
preferredBitsPerPixel = settings->ColorDepth;
UINT16 multipleRectangleSupport;
UINT16 pad2OctetsB;
- fprintf(stderr, "BitmapCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "BitmapCapabilitySet (length %d):\n", length);
if (length < 28)
return FALSE;
Stream_Read_UINT16(s, multipleRectangleSupport); /* multipleRectangleSupport (2 bytes) */
Stream_Read_UINT16(s, pad2OctetsB); /* pad2OctetsB (2 bytes) */
- fprintf(stderr, "\tpreferredBitsPerPixel: 0x%04X\n", preferredBitsPerPixel);
- fprintf(stderr, "\treceive1BitPerPixel: 0x%04X\n", receive1BitPerPixel);
- fprintf(stderr, "\treceive4BitsPerPixel: 0x%04X\n", receive4BitsPerPixel);
- fprintf(stderr, "\treceive8BitsPerPixel: 0x%04X\n", receive8BitsPerPixel);
- fprintf(stderr, "\tdesktopWidth: 0x%04X\n", desktopWidth);
- fprintf(stderr, "\tdesktopHeight: 0x%04X\n", desktopHeight);
- fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets);
- fprintf(stderr, "\tdesktopResizeFlag: 0x%04X\n", desktopResizeFlag);
- fprintf(stderr, "\tbitmapCompressionFlag: 0x%04X\n", bitmapCompressionFlag);
- fprintf(stderr, "\thighColorFlags: 0x%02X\n", highColorFlags);
- fprintf(stderr, "\tdrawingFlags: 0x%02X\n", drawingFlags);
- fprintf(stderr, "\tmultipleRectangleSupport: 0x%04X\n", multipleRectangleSupport);
- fprintf(stderr, "\tpad2OctetsB: 0x%04X\n", pad2OctetsB);
+ DEBUG_WARN( "\tpreferredBitsPerPixel: 0x%04X\n", preferredBitsPerPixel);
+ DEBUG_WARN( "\treceive1BitPerPixel: 0x%04X\n", receive1BitPerPixel);
+ DEBUG_WARN( "\treceive4BitsPerPixel: 0x%04X\n", receive4BitsPerPixel);
+ DEBUG_WARN( "\treceive8BitsPerPixel: 0x%04X\n", receive8BitsPerPixel);
+ DEBUG_WARN( "\tdesktopWidth: 0x%04X\n", desktopWidth);
+ DEBUG_WARN( "\tdesktopHeight: 0x%04X\n", desktopHeight);
+ DEBUG_WARN( "\tpad2Octets: 0x%04X\n", pad2Octets);
+ DEBUG_WARN( "\tdesktopResizeFlag: 0x%04X\n", desktopResizeFlag);
+ DEBUG_WARN( "\tbitmapCompressionFlag: 0x%04X\n", bitmapCompressionFlag);
+ DEBUG_WARN( "\thighColorFlags: 0x%02X\n", highColorFlags);
+ DEBUG_WARN( "\tdrawingFlags: 0x%02X\n", drawingFlags);
+ DEBUG_WARN( "\tmultipleRectangleSupport: 0x%04X\n", multipleRectangleSupport);
+ DEBUG_WARN( "\tpad2OctetsB: 0x%04X\n", pad2OctetsB);
return TRUE;
}
UINT16 textANSICodePage;
UINT16 pad2OctetsE;
- fprintf(stderr, "OrderCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "OrderCapabilitySet (length %d):\n", length);
if (length < 88)
return FALSE;
Stream_Read_UINT16(s, textANSICodePage); /* textANSICodePage (2 bytes) */
Stream_Read_UINT16(s, pad2OctetsE); /* pad2OctetsE (2 bytes) */
- fprintf(stderr, "\tpad4OctetsA: 0x%08X\n", pad4OctetsA);
- fprintf(stderr, "\tdesktopSaveXGranularity: 0x%04X\n", desktopSaveXGranularity);
- fprintf(stderr, "\tdesktopSaveYGranularity: 0x%04X\n", desktopSaveYGranularity);
- fprintf(stderr, "\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
- fprintf(stderr, "\tmaximumOrderLevel: 0x%04X\n", maximumOrderLevel);
- fprintf(stderr, "\tnumberFonts: 0x%04X\n", numberFonts);
- fprintf(stderr, "\torderFlags: 0x%04X\n", orderFlags);
-
- fprintf(stderr, "\torderSupport:\n");
- fprintf(stderr, "\t\tDSTBLT: %d\n", orderSupport[NEG_DSTBLT_INDEX]);
- fprintf(stderr, "\t\tPATBLT: %d\n", orderSupport[NEG_PATBLT_INDEX]);
- fprintf(stderr, "\t\tSCRBLT: %d\n", orderSupport[NEG_SCRBLT_INDEX]);
- fprintf(stderr, "\t\tMEMBLT: %d\n", orderSupport[NEG_MEMBLT_INDEX]);
- fprintf(stderr, "\t\tMEM3BLT: %d\n", orderSupport[NEG_MEM3BLT_INDEX]);
- fprintf(stderr, "\t\tATEXTOUT: %d\n", orderSupport[NEG_ATEXTOUT_INDEX]);
- fprintf(stderr, "\t\tAEXTTEXTOUT: %d\n", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
- fprintf(stderr, "\t\tDRAWNINEGRID: %d\n", orderSupport[NEG_DRAWNINEGRID_INDEX]);
- fprintf(stderr, "\t\tLINETO: %d\n", orderSupport[NEG_LINETO_INDEX]);
- fprintf(stderr, "\t\tMULTI_DRAWNINEGRID: %d\n", orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
- fprintf(stderr, "\t\tOPAQUE_RECT: %d\n", orderSupport[NEG_OPAQUE_RECT_INDEX]);
- fprintf(stderr, "\t\tSAVEBITMAP: %d\n", orderSupport[NEG_SAVEBITMAP_INDEX]);
- fprintf(stderr, "\t\tWTEXTOUT: %d\n", orderSupport[NEG_WTEXTOUT_INDEX]);
- fprintf(stderr, "\t\tMEMBLT_V2: %d\n", orderSupport[NEG_MEMBLT_V2_INDEX]);
- fprintf(stderr, "\t\tMEM3BLT_V2: %d\n", orderSupport[NEG_MEM3BLT_V2_INDEX]);
- fprintf(stderr, "\t\tMULTIDSTBLT: %d\n", orderSupport[NEG_MULTIDSTBLT_INDEX]);
- fprintf(stderr, "\t\tMULTIPATBLT: %d\n", orderSupport[NEG_MULTIPATBLT_INDEX]);
- fprintf(stderr, "\t\tMULTISCRBLT: %d\n", orderSupport[NEG_MULTISCRBLT_INDEX]);
- fprintf(stderr, "\t\tMULTIOPAQUERECT: %d\n", orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
- fprintf(stderr, "\t\tFAST_INDEX: %d\n", orderSupport[NEG_FAST_INDEX_INDEX]);
- fprintf(stderr, "\t\tPOLYGON_SC: %d\n", orderSupport[NEG_POLYGON_SC_INDEX]);
- fprintf(stderr, "\t\tPOLYGON_CB: %d\n", orderSupport[NEG_POLYGON_CB_INDEX]);
- fprintf(stderr, "\t\tPOLYLINE: %d\n", orderSupport[NEG_POLYLINE_INDEX]);
- fprintf(stderr, "\t\tUNUSED23: %d\n", orderSupport[NEG_UNUSED23_INDEX]);
- fprintf(stderr, "\t\tFAST_GLYPH: %d\n", orderSupport[NEG_FAST_GLYPH_INDEX]);
- fprintf(stderr, "\t\tELLIPSE_SC: %d\n", orderSupport[NEG_ELLIPSE_SC_INDEX]);
- fprintf(stderr, "\t\tELLIPSE_CB: %d\n", orderSupport[NEG_ELLIPSE_CB_INDEX]);
- fprintf(stderr, "\t\tGLYPH_INDEX: %d\n", orderSupport[NEG_GLYPH_INDEX_INDEX]);
- fprintf(stderr, "\t\tGLYPH_WEXTTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
- fprintf(stderr, "\t\tGLYPH_WLONGTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
- fprintf(stderr, "\t\tGLYPH_WLONGEXTTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
- fprintf(stderr, "\t\tUNUSED31: %d\n", orderSupport[NEG_UNUSED31_INDEX]);
-
- fprintf(stderr, "\ttextFlags: 0x%04X\n", textFlags);
- fprintf(stderr, "\torderSupportExFlags: 0x%04X\n", orderSupportExFlags);
- fprintf(stderr, "\tpad4OctetsB: 0x%08X\n", pad4OctetsB);
- fprintf(stderr, "\tdesktopSaveSize: 0x%08X\n", desktopSaveSize);
- fprintf(stderr, "\tpad2OctetsC: 0x%04X\n", pad2OctetsC);
- fprintf(stderr, "\tpad2OctetsD: 0x%04X\n", pad2OctetsD);
- fprintf(stderr, "\ttextANSICodePage: 0x%04X\n", textANSICodePage);
- fprintf(stderr, "\tpad2OctetsE: 0x%04X\n", pad2OctetsE);
+ DEBUG_WARN( "\tpad4OctetsA: 0x%08X\n", pad4OctetsA);
+ DEBUG_WARN( "\tdesktopSaveXGranularity: 0x%04X\n", desktopSaveXGranularity);
+ DEBUG_WARN( "\tdesktopSaveYGranularity: 0x%04X\n", desktopSaveYGranularity);
+ DEBUG_WARN( "\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
+ DEBUG_WARN( "\tmaximumOrderLevel: 0x%04X\n", maximumOrderLevel);
+ DEBUG_WARN( "\tnumberFonts: 0x%04X\n", numberFonts);
+ DEBUG_WARN( "\torderFlags: 0x%04X\n", orderFlags);
+
+ DEBUG_WARN( "\torderSupport:\n");
+ DEBUG_WARN( "\t\tDSTBLT: %d\n", orderSupport[NEG_DSTBLT_INDEX]);
+ DEBUG_WARN( "\t\tPATBLT: %d\n", orderSupport[NEG_PATBLT_INDEX]);
+ DEBUG_WARN( "\t\tSCRBLT: %d\n", orderSupport[NEG_SCRBLT_INDEX]);
+ DEBUG_WARN( "\t\tMEMBLT: %d\n", orderSupport[NEG_MEMBLT_INDEX]);
+ DEBUG_WARN( "\t\tMEM3BLT: %d\n", orderSupport[NEG_MEM3BLT_INDEX]);
+ DEBUG_WARN( "\t\tATEXTOUT: %d\n", orderSupport[NEG_ATEXTOUT_INDEX]);
+ DEBUG_WARN( "\t\tAEXTTEXTOUT: %d\n", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
+ DEBUG_WARN( "\t\tDRAWNINEGRID: %d\n", orderSupport[NEG_DRAWNINEGRID_INDEX]);
+ DEBUG_WARN( "\t\tLINETO: %d\n", orderSupport[NEG_LINETO_INDEX]);
+ DEBUG_WARN( "\t\tMULTI_DRAWNINEGRID: %d\n", orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
+ DEBUG_WARN( "\t\tOPAQUE_RECT: %d\n", orderSupport[NEG_OPAQUE_RECT_INDEX]);
+ DEBUG_WARN( "\t\tSAVEBITMAP: %d\n", orderSupport[NEG_SAVEBITMAP_INDEX]);
+ DEBUG_WARN( "\t\tWTEXTOUT: %d\n", orderSupport[NEG_WTEXTOUT_INDEX]);
+ DEBUG_WARN( "\t\tMEMBLT_V2: %d\n", orderSupport[NEG_MEMBLT_V2_INDEX]);
+ DEBUG_WARN( "\t\tMEM3BLT_V2: %d\n", orderSupport[NEG_MEM3BLT_V2_INDEX]);
+ DEBUG_WARN( "\t\tMULTIDSTBLT: %d\n", orderSupport[NEG_MULTIDSTBLT_INDEX]);
+ DEBUG_WARN( "\t\tMULTIPATBLT: %d\n", orderSupport[NEG_MULTIPATBLT_INDEX]);
+ DEBUG_WARN( "\t\tMULTISCRBLT: %d\n", orderSupport[NEG_MULTISCRBLT_INDEX]);
+ DEBUG_WARN( "\t\tMULTIOPAQUERECT: %d\n", orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
+ DEBUG_WARN( "\t\tFAST_INDEX: %d\n", orderSupport[NEG_FAST_INDEX_INDEX]);
+ DEBUG_WARN( "\t\tPOLYGON_SC: %d\n", orderSupport[NEG_POLYGON_SC_INDEX]);
+ DEBUG_WARN( "\t\tPOLYGON_CB: %d\n", orderSupport[NEG_POLYGON_CB_INDEX]);
+ DEBUG_WARN( "\t\tPOLYLINE: %d\n", orderSupport[NEG_POLYLINE_INDEX]);
+ DEBUG_WARN( "\t\tUNUSED23: %d\n", orderSupport[NEG_UNUSED23_INDEX]);
+ DEBUG_WARN( "\t\tFAST_GLYPH: %d\n", orderSupport[NEG_FAST_GLYPH_INDEX]);
+ DEBUG_WARN( "\t\tELLIPSE_SC: %d\n", orderSupport[NEG_ELLIPSE_SC_INDEX]);
+ DEBUG_WARN( "\t\tELLIPSE_CB: %d\n", orderSupport[NEG_ELLIPSE_CB_INDEX]);
+ DEBUG_WARN( "\t\tGLYPH_INDEX: %d\n", orderSupport[NEG_GLYPH_INDEX_INDEX]);
+ DEBUG_WARN( "\t\tGLYPH_WEXTTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
+ DEBUG_WARN( "\t\tGLYPH_WLONGTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
+ DEBUG_WARN( "\t\tGLYPH_WLONGEXTTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
+ DEBUG_WARN( "\t\tUNUSED31: %d\n", orderSupport[NEG_UNUSED31_INDEX]);
+
+ DEBUG_WARN( "\ttextFlags: 0x%04X\n", textFlags);
+ DEBUG_WARN( "\torderSupportExFlags: 0x%04X\n", orderSupportExFlags);
+ DEBUG_WARN( "\tpad4OctetsB: 0x%08X\n", pad4OctetsB);
+ DEBUG_WARN( "\tdesktopSaveSize: 0x%08X\n", desktopSaveSize);
+ DEBUG_WARN( "\tpad2OctetsC: 0x%04X\n", pad2OctetsC);
+ DEBUG_WARN( "\tpad2OctetsD: 0x%04X\n", pad2OctetsD);
+ DEBUG_WARN( "\ttextANSICodePage: 0x%04X\n", textANSICodePage);
+ DEBUG_WARN( "\tpad2OctetsE: 0x%04X\n", pad2OctetsE);
return TRUE;
}
UINT16 Cache2Entries;
UINT16 Cache2MaximumCellSize;
- fprintf(stderr, "BitmapCacheCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "BitmapCacheCapabilitySet (length %d):\n", length);
if (length < 40)
return FALSE;
Stream_Read_UINT16(s, Cache2Entries); /* Cache2Entries (2 bytes) */
Stream_Read_UINT16(s, Cache2MaximumCellSize); /* Cache2MaximumCellSize (2 bytes) */
- fprintf(stderr, "\tpad1: 0x%08X\n", pad1);
- fprintf(stderr, "\tpad2: 0x%08X\n", pad2);
- fprintf(stderr, "\tpad3: 0x%08X\n", pad3);
- fprintf(stderr, "\tpad4: 0x%08X\n", pad4);
- fprintf(stderr, "\tpad5: 0x%08X\n", pad5);
- fprintf(stderr, "\tpad6: 0x%08X\n", pad6);
- fprintf(stderr, "\tCache0Entries: 0x%04X\n", Cache0Entries);
- fprintf(stderr, "\tCache0MaximumCellSize: 0x%04X\n", Cache0MaximumCellSize);
- fprintf(stderr, "\tCache1Entries: 0x%04X\n", Cache1Entries);
- fprintf(stderr, "\tCache1MaximumCellSize: 0x%04X\n", Cache1MaximumCellSize);
- fprintf(stderr, "\tCache2Entries: 0x%04X\n", Cache2Entries);
- fprintf(stderr, "\tCache2MaximumCellSize: 0x%04X\n", Cache2MaximumCellSize);
+ DEBUG_WARN( "\tpad1: 0x%08X\n", pad1);
+ DEBUG_WARN( "\tpad2: 0x%08X\n", pad2);
+ DEBUG_WARN( "\tpad3: 0x%08X\n", pad3);
+ DEBUG_WARN( "\tpad4: 0x%08X\n", pad4);
+ DEBUG_WARN( "\tpad5: 0x%08X\n", pad5);
+ DEBUG_WARN( "\tpad6: 0x%08X\n", pad6);
+ DEBUG_WARN( "\tCache0Entries: 0x%04X\n", Cache0Entries);
+ DEBUG_WARN( "\tCache0MaximumCellSize: 0x%04X\n", Cache0MaximumCellSize);
+ DEBUG_WARN( "\tCache1Entries: 0x%04X\n", Cache1Entries);
+ DEBUG_WARN( "\tCache1MaximumCellSize: 0x%04X\n", Cache1MaximumCellSize);
+ DEBUG_WARN( "\tCache2Entries: 0x%04X\n", Cache2Entries);
+ DEBUG_WARN( "\tCache2MaximumCellSize: 0x%04X\n", Cache2MaximumCellSize);
return TRUE;
}
UINT16 controlInterest;
UINT16 detachInterest;
- fprintf(stderr, "ControlCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "ControlCapabilitySet (length %d):\n", length);
if (length < 12)
return FALSE;
Stream_Read_UINT16(s, controlInterest); /* controlInterest (2 bytes) */
Stream_Read_UINT16(s, detachInterest); /* detachInterest (2 bytes) */
- fprintf(stderr, "\tcontrolFlags: 0x%04X\n", controlFlags);
- fprintf(stderr, "\tremoteDetachFlag: 0x%04X\n", remoteDetachFlag);
- fprintf(stderr, "\tcontrolInterest: 0x%04X\n", controlInterest);
- fprintf(stderr, "\tdetachInterest: 0x%04X\n", detachInterest);
+ DEBUG_WARN( "\tcontrolFlags: 0x%04X\n", controlFlags);
+ DEBUG_WARN( "\tremoteDetachFlag: 0x%04X\n", remoteDetachFlag);
+ DEBUG_WARN( "\tcontrolInterest: 0x%04X\n", controlInterest);
+ DEBUG_WARN( "\tdetachInterest: 0x%04X\n", detachInterest);
return TRUE;
}
UINT16 helpExtendedKeyFlag;
UINT16 windowManagerKeyFlag;
- fprintf(stderr, "WindowActivationCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "WindowActivationCapabilitySet (length %d):\n", length);
if (length < 12)
return FALSE;
Stream_Read_UINT16(s, helpExtendedKeyFlag); /* helpExtendedKeyFlag (2 bytes) */
Stream_Read_UINT16(s, windowManagerKeyFlag); /* windowManagerKeyFlag (2 bytes) */
- fprintf(stderr, "\thelpKeyFlag: 0x%04X\n", helpKeyFlag);
- fprintf(stderr, "\thelpKeyIndexFlag: 0x%04X\n", helpKeyIndexFlag);
- fprintf(stderr, "\thelpExtendedKeyFlag: 0x%04X\n", helpExtendedKeyFlag);
- fprintf(stderr, "\twindowManagerKeyFlag: 0x%04X\n", windowManagerKeyFlag);
+ DEBUG_WARN( "\thelpKeyFlag: 0x%04X\n", helpKeyFlag);
+ DEBUG_WARN( "\thelpKeyIndexFlag: 0x%04X\n", helpKeyIndexFlag);
+ DEBUG_WARN( "\thelpExtendedKeyFlag: 0x%04X\n", helpExtendedKeyFlag);
+ DEBUG_WARN( "\twindowManagerKeyFlag: 0x%04X\n", windowManagerKeyFlag);
return TRUE;
}
if (length < 10)
return FALSE;
- fprintf(stderr, "PointerCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "PointerCapabilitySet (length %d):\n", length);
Stream_Read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */
Stream_Read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */
Stream_Read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */
- fprintf(stderr, "\tcolorPointerFlag: 0x%04X\n", colorPointerFlag);
- fprintf(stderr, "\tcolorPointerCacheSize: 0x%04X\n", colorPointerCacheSize);
- fprintf(stderr, "\tpointerCacheSize: 0x%04X\n", pointerCacheSize);
+ DEBUG_WARN( "\tcolorPointerFlag: 0x%04X\n", colorPointerFlag);
+ DEBUG_WARN( "\tcolorPointerCacheSize: 0x%04X\n", colorPointerCacheSize);
+ DEBUG_WARN( "\tpointerCacheSize: 0x%04X\n", pointerCacheSize);
return TRUE;
}
UINT16 nodeId;
UINT16 pad2Octets;
- fprintf(stderr, "ShareCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "ShareCapabilitySet (length %d):\n", length);
if (length < 8)
return FALSE;
Stream_Read_UINT16(s, nodeId); /* nodeId (2 bytes) */
Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */
- fprintf(stderr, "\tnodeId: 0x%04X\n", nodeId);
- fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets);
+ DEBUG_WARN( "\tnodeId: 0x%04X\n", nodeId);
+ DEBUG_WARN( "\tpad2Octets: 0x%04X\n", pad2Octets);
return TRUE;
}
UINT16 colorTableCacheSize;
UINT16 pad2Octets;
- fprintf(stderr, "ColorCacheCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "ColorCacheCapabilitySet (length %d):\n", length);
if (length < 8)
return FALSE;
Stream_Read_UINT16(s, colorTableCacheSize); /* colorTableCacheSize (2 bytes) */
Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */
- fprintf(stderr, "\tcolorTableCacheSize: 0x%04X\n", colorTableCacheSize);
- fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets);
+ DEBUG_WARN( "\tcolorTableCacheSize: 0x%04X\n", colorTableCacheSize);
+ DEBUG_WARN( "\tpad2Octets: 0x%04X\n", pad2Octets);
return TRUE;
}
UINT16 soundFlags;
UINT16 pad2OctetsA;
- fprintf(stderr, "SoundCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "SoundCapabilitySet (length %d):\n", length);
if (length < 8)
return FALSE;
Stream_Read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */
Stream_Read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */
- fprintf(stderr, "\tsoundFlags: 0x%04X\n", soundFlags);
- fprintf(stderr, "\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
+ DEBUG_WARN( "\tsoundFlags: 0x%04X\n", soundFlags);
+ DEBUG_WARN( "\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
return TRUE;
}
UINT32 keyboardSubType;
UINT32 keyboardFunctionKey;
- fprintf(stderr, "InputCapabilitySet (length %d)\n", length);
+ DEBUG_WARN( "InputCapabilitySet (length %d)\n", length);
if (length < 88)
return FALSE;
Stream_Read_UINT32(s, keyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */
Stream_Seek(s, 64); /* imeFileName (64 bytes) */
- fprintf(stderr, "\tinputFlags: 0x%04X\n", inputFlags);
- fprintf(stderr, "\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
- fprintf(stderr, "\tkeyboardLayout: 0x%08X\n", keyboardLayout);
- fprintf(stderr, "\tkeyboardType: 0x%08X\n", keyboardType);
- fprintf(stderr, "\tkeyboardSubType: 0x%08X\n", keyboardSubType);
- fprintf(stderr, "\tkeyboardFunctionKey: 0x%08X\n", keyboardFunctionKey);
+ DEBUG_WARN( "\tinputFlags: 0x%04X\n", inputFlags);
+ DEBUG_WARN( "\tpad2OctetsA: 0x%04X\n", pad2OctetsA);
+ DEBUG_WARN( "\tkeyboardLayout: 0x%08X\n", keyboardLayout);
+ DEBUG_WARN( "\tkeyboardType: 0x%08X\n", keyboardType);
+ DEBUG_WARN( "\tkeyboardSubType: 0x%08X\n", keyboardSubType);
+ DEBUG_WARN( "\tkeyboardFunctionKey: 0x%08X\n", keyboardFunctionKey);
return TRUE;
}
UINT16 fontSupportFlags = 0;
UINT16 pad2Octets = 0;
- fprintf(stderr, "FontCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "FontCapabilitySet (length %d):\n", length);
if (length > 4)
Stream_Read_UINT16(s, fontSupportFlags); /* fontSupportFlags (2 bytes) */
if (length > 6)
Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */
- fprintf(stderr, "\tfontSupportFlags: 0x%04X\n", fontSupportFlags);
- fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets);
+ DEBUG_WARN( "\tfontSupportFlags: 0x%04X\n", fontSupportFlags);
+ DEBUG_WARN( "\tpad2Octets: 0x%04X\n", pad2Octets);
return TRUE;
}
{
UINT32 brushSupportLevel;
- fprintf(stderr, "BrushCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "BrushCapabilitySet (length %d):\n", length);
if (length < 8)
return FALSE;
Stream_Read_UINT32(s, brushSupportLevel); /* brushSupportLevel (4 bytes) */
- fprintf(stderr, "\tbrushSupportLevel: 0x%08X\n", brushSupportLevel);
+ DEBUG_WARN( "\tbrushSupportLevel: 0x%08X\n", brushSupportLevel);
return TRUE;
}
UINT16 glyphSupportLevel;
UINT16 pad2Octets;
- fprintf(stderr, "GlyphCacheCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "GlyphCacheCapabilitySet (length %d):\n", length);
if (length < 52)
return FALSE;
Stream_Read_UINT16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */
Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */
- fprintf(stderr, "\tglyphCache0: Entries: %d MaximumCellSize: %d\n", glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
- fprintf(stderr, "\tglyphCache1: Entries: %d MaximumCellSize: %d\n", glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
- fprintf(stderr, "\tglyphCache2: Entries: %d MaximumCellSize: %d\n", glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
- fprintf(stderr, "\tglyphCache3: Entries: %d MaximumCellSize: %d\n", glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
- fprintf(stderr, "\tglyphCache4: Entries: %d MaximumCellSize: %d\n", glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
- fprintf(stderr, "\tglyphCache5: Entries: %d MaximumCellSize: %d\n", glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
- fprintf(stderr, "\tglyphCache6: Entries: %d MaximumCellSize: %d\n", glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
- fprintf(stderr, "\tglyphCache7: Entries: %d MaximumCellSize: %d\n", glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
- fprintf(stderr, "\tglyphCache8: Entries: %d MaximumCellSize: %d\n", glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
- fprintf(stderr, "\tglyphCache9: Entries: %d MaximumCellSize: %d\n", glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
- fprintf(stderr, "\tfragCache: Entries: %d MaximumCellSize: %d\n", fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
- fprintf(stderr, "\tglyphSupportLevel: 0x%04X\n", glyphSupportLevel);
- fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets);
+ DEBUG_WARN( "\tglyphCache0: Entries: %d MaximumCellSize: %d\n", glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
+ DEBUG_WARN( "\tglyphCache1: Entries: %d MaximumCellSize: %d\n", glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
+ DEBUG_WARN( "\tglyphCache2: Entries: %d MaximumCellSize: %d\n", glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
+ DEBUG_WARN( "\tglyphCache3: Entries: %d MaximumCellSize: %d\n", glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
+ DEBUG_WARN( "\tglyphCache4: Entries: %d MaximumCellSize: %d\n", glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
+ DEBUG_WARN( "\tglyphCache5: Entries: %d MaximumCellSize: %d\n", glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
+ DEBUG_WARN( "\tglyphCache6: Entries: %d MaximumCellSize: %d\n", glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
+ DEBUG_WARN( "\tglyphCache7: Entries: %d MaximumCellSize: %d\n", glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
+ DEBUG_WARN( "\tglyphCache8: Entries: %d MaximumCellSize: %d\n", glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
+ DEBUG_WARN( "\tglyphCache9: Entries: %d MaximumCellSize: %d\n", glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
+ DEBUG_WARN( "\tfragCache: Entries: %d MaximumCellSize: %d\n", fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
+ DEBUG_WARN( "\tglyphSupportLevel: 0x%04X\n", glyphSupportLevel);
+ DEBUG_WARN( "\tpad2Octets: 0x%04X\n", pad2Octets);
return TRUE;
}
UINT16 offscreenCacheSize;
UINT16 offscreenCacheEntries;
- fprintf(stderr, "OffscreenBitmapCacheCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "OffscreenBitmapCacheCapabilitySet (length %d):\n", length);
if (length < 12)
return FALSE;
Stream_Read_UINT16(s, offscreenCacheSize); /* offscreenCacheSize (2 bytes) */
Stream_Read_UINT16(s, offscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */
- fprintf(stderr, "\toffscreenSupportLevel: 0x%08X\n", offscreenSupportLevel);
- fprintf(stderr, "\toffscreenCacheSize: 0x%04X\n", offscreenCacheSize);
- fprintf(stderr, "\toffscreenCacheEntries: 0x%04X\n", offscreenCacheEntries);
+ DEBUG_WARN( "\toffscreenSupportLevel: 0x%08X\n", offscreenSupportLevel);
+ DEBUG_WARN( "\toffscreenCacheSize: 0x%04X\n", offscreenCacheSize);
+ DEBUG_WARN( "\toffscreenCacheEntries: 0x%04X\n", offscreenCacheEntries);
return TRUE;
}
BYTE pad1;
UINT16 pad2;
- fprintf(stderr, "BitmapCacheHostSupportCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "BitmapCacheHostSupportCapabilitySet (length %d):\n", length);
if (length < 8)
return FALSE;
Stream_Read_UINT8(s, pad1); /* pad1 (1 byte) */
Stream_Read_UINT16(s, pad2); /* pad2 (2 bytes) */
- fprintf(stderr, "\tcacheVersion: 0x%02X\n", cacheVersion);
- fprintf(stderr, "\tpad1: 0x%02X\n", pad1);
- fprintf(stderr, "\tpad2: 0x%04X\n", pad2);
+ DEBUG_WARN( "\tcacheVersion: 0x%02X\n", cacheVersion);
+ DEBUG_WARN( "\tpad1: 0x%02X\n", pad1);
+ DEBUG_WARN( "\tpad2: 0x%04X\n", pad2);
return TRUE;
}
BYTE numCellCaches;
BITMAP_CACHE_V2_CELL_INFO bitmapCacheV2CellInfo[5];
- fprintf(stderr, "BitmapCacheV2CapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "BitmapCacheV2CapabilitySet (length %d):\n", length);
if (length < 40)
return FALSE;
rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */
Stream_Seek(s, 12); /* pad3 (12 bytes) */
- fprintf(stderr, "\tcacheFlags: 0x%04X\n", cacheFlags);
- fprintf(stderr, "\tpad2: 0x%02X\n", pad2);
- fprintf(stderr, "\tnumCellCaches: 0x%02X\n", numCellCaches);
- fprintf(stderr, "\tbitmapCache0CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[0].numEntries, bitmapCacheV2CellInfo[0].persistent);
- fprintf(stderr, "\tbitmapCache1CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[1].numEntries, bitmapCacheV2CellInfo[1].persistent);
- fprintf(stderr, "\tbitmapCache2CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[2].numEntries, bitmapCacheV2CellInfo[2].persistent);
- fprintf(stderr, "\tbitmapCache3CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[3].numEntries, bitmapCacheV2CellInfo[3].persistent);
- fprintf(stderr, "\tbitmapCache4CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[4].numEntries, bitmapCacheV2CellInfo[4].persistent);
+ DEBUG_WARN( "\tcacheFlags: 0x%04X\n", cacheFlags);
+ DEBUG_WARN( "\tpad2: 0x%02X\n", pad2);
+ DEBUG_WARN( "\tnumCellCaches: 0x%02X\n", numCellCaches);
+ DEBUG_WARN( "\tbitmapCache0CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[0].numEntries, bitmapCacheV2CellInfo[0].persistent);
+ DEBUG_WARN( "\tbitmapCache1CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[1].numEntries, bitmapCacheV2CellInfo[1].persistent);
+ DEBUG_WARN( "\tbitmapCache2CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[2].numEntries, bitmapCacheV2CellInfo[2].persistent);
+ DEBUG_WARN( "\tbitmapCache3CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[3].numEntries, bitmapCacheV2CellInfo[3].persistent);
+ DEBUG_WARN( "\tbitmapCache4CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[4].numEntries, bitmapCacheV2CellInfo[4].persistent);
return TRUE;
}
UINT32 flags;
UINT32 VCChunkSize;
- fprintf(stderr, "VirtualChannelCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "VirtualChannelCapabilitySet (length %d):\n", length);
if (length < 8)
return FALSE;
else
VCChunkSize = 1600;
- fprintf(stderr, "\tflags: 0x%08X\n", flags);
- fprintf(stderr, "\tVCChunkSize: 0x%08X\n", VCChunkSize);
+ DEBUG_WARN( "\tflags: 0x%08X\n", flags);
+ DEBUG_WARN( "\tVCChunkSize: 0x%08X\n", VCChunkSize);
return TRUE;
}
UINT16 DrawNineGridCacheSize;
UINT16 DrawNineGridCacheEntries;
- fprintf(stderr, "DrawNineGridCacheCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "DrawNineGridCacheCapabilitySet (length %d):\n", length);
if (length < 12)
return FALSE;
UINT32 GdipVersion;
UINT32 drawGdiplusCacheLevel;
- fprintf(stderr, "DrawGdiPlusCacheCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "DrawGdiPlusCacheCapabilitySet (length %d):\n", length);
if (length < 40)
return FALSE;
{
UINT32 railSupportLevel;
- fprintf(stderr, "RemoteProgramsCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "RemoteProgramsCapabilitySet (length %d):\n", length);
if (length < 8)
return FALSE;
Stream_Read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */
- fprintf(stderr, "\trailSupportLevel: 0x%08X\n", railSupportLevel);
+ DEBUG_WARN( "\trailSupportLevel: 0x%08X\n", railSupportLevel);
return TRUE;
}
BYTE numIconCaches;
UINT16 numIconCacheEntries;
- fprintf(stderr, "WindowListCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "WindowListCapabilitySet (length %d):\n", length);
if (length < 11)
return FALSE;
Stream_Read_UINT8(s, numIconCaches); /* numIconCaches (1 byte) */
Stream_Read_UINT16(s, numIconCacheEntries); /* numIconCacheEntries (2 bytes) */
- fprintf(stderr, "\twndSupportLevel: 0x%08X\n", wndSupportLevel);
- fprintf(stderr, "\tnumIconCaches: 0x%02X\n", numIconCaches);
- fprintf(stderr, "\tnumIconCacheEntries: 0x%04X\n", numIconCacheEntries);
+ DEBUG_WARN( "\twndSupportLevel: 0x%08X\n", wndSupportLevel);
+ DEBUG_WARN( "\tnumIconCaches: 0x%02X\n", numIconCaches);
+ DEBUG_WARN( "\tnumIconCacheEntries: 0x%04X\n", numIconCacheEntries);
return TRUE;
}
{
UINT16 compDeskSupportLevel;
- fprintf(stderr, "DesktopCompositionCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "DesktopCompositionCapabilitySet (length %d):\n", length);
if (length < 6)
return FALSE;
Stream_Read_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */
- fprintf(stderr, "\tcompDeskSupportLevel: 0x%04X\n", compDeskSupportLevel);
+ DEBUG_WARN( "\tcompDeskSupportLevel: 0x%04X\n", compDeskSupportLevel);
return TRUE;
}
{
UINT32 maxRequestSize;
- fprintf(stderr, "MultifragmentUpdateCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "MultifragmentUpdateCapabilitySet (length %d):\n", length);
if (length < 8)
return FALSE;
Stream_Read_UINT32(s, maxRequestSize); /* maxRequestSize (4 bytes) */
- fprintf(stderr, "\tmaxRequestSize: 0x%04X\n", maxRequestSize);
+ DEBUG_WARN( "\tmaxRequestSize: 0x%04X\n", maxRequestSize);
return TRUE;
}
{
UINT16 largePointerSupportFlags;
- fprintf(stderr, "LargePointerCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "LargePointerCapabilitySet (length %d):\n", length);
if (length < 6)
return FALSE;
Stream_Read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */
- fprintf(stderr, "\tlargePointerSupportFlags: 0x%04X\n", largePointerSupportFlags);
+ DEBUG_WARN( "\tlargePointerSupportFlags: 0x%04X\n", largePointerSupportFlags);
return TRUE;
}
UINT32 cmdFlags;
UINT32 reserved;
- fprintf(stderr, "SurfaceCommandsCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "SurfaceCommandsCapabilitySet (length %d):\n", length);
if (length < 12)
return FALSE;
Stream_Read_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */
Stream_Read_UINT32(s, reserved); /* reserved (4 bytes) */
- fprintf(stderr, "\tcmdFlags: 0x%08X\n", cmdFlags);
- fprintf(stderr, "\treserved: 0x%08X\n", reserved);
+ DEBUG_WARN( "\tcmdFlags: 0x%08X\n", cmdFlags);
+ DEBUG_WARN( "\treserved: 0x%08X\n", reserved);
return TRUE;
}
void rdp_print_bitmap_codec_guid(GUID* guid)
{
- fprintf(stderr, "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
+ DEBUG_WARN( "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
guid->Data1, guid->Data2, guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
UINT16 codecPropertiesLength;
UINT16 remainingLength;
- fprintf(stderr, "BitmapCodecsCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "BitmapCodecsCapabilitySet (length %d):\n", length);
if (length < 5)
return FALSE;
Stream_Read_UINT8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */
remainingLength = length - 5;
- fprintf(stderr, "\tbitmapCodecCount: %d\n", bitmapCodecCount);
+ DEBUG_WARN( "\tbitmapCodecCount: %d\n", bitmapCodecCount);
while (bitmapCodecCount > 0)
{
rdp_read_bitmap_codec_guid(s, &codecGuid); /* codecGuid (16 bytes) */
Stream_Read_UINT8(s, codecId); /* codecId (1 byte) */
- fprintf(stderr, "\tcodecGuid: 0x");
+ DEBUG_WARN( "\tcodecGuid: 0x");
rdp_print_bitmap_codec_guid(&codecGuid);
- fprintf(stderr, " (%s)\n", rdp_get_bitmap_codec_guid_name(&codecGuid));
+ DEBUG_WARN( " (%s)\n", rdp_get_bitmap_codec_guid_name(&codecGuid));
- fprintf(stderr, "\tcodecId: %d\n", codecId);
+ DEBUG_WARN( "\tcodecId: %d\n", codecId);
Stream_Read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */
- fprintf(stderr, "\tcodecPropertiesLength: %d\n", codecPropertiesLength);
+ DEBUG_WARN( "\tcodecPropertiesLength: %d\n", codecPropertiesLength);
remainingLength -= 19;
{
UINT32 frameAcknowledge;
- fprintf(stderr, "FrameAcknowledgeCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "FrameAcknowledgeCapabilitySet (length %d):\n", length);
if (length < 8)
return FALSE;
Stream_Read_UINT32(s, frameAcknowledge); /* frameAcknowledge (4 bytes) */
- fprintf(stderr, "\tframeAcknowledge: 0x%08X\n", frameAcknowledge);
+ DEBUG_WARN( "\tframeAcknowledge: 0x%08X\n", frameAcknowledge);
return TRUE;
}
{
BYTE bitmapCacheV3CodecId;
- fprintf(stderr, "BitmapCacheV3CodecIdCapabilitySet (length %d):\n", length);
+ DEBUG_WARN( "BitmapCacheV3CodecIdCapabilitySet (length %d):\n", length);
if (length < 5)
return FALSE;
Stream_Read_UINT8(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */
- fprintf(stderr, "\tbitmapCacheV3CodecId: 0x%02X\n", bitmapCacheV3CodecId);
+ DEBUG_WARN( "\tbitmapCacheV3CodecId: 0x%02X\n", bitmapCacheV3CodecId);
return TRUE;
}
rdp_read_capability_set_header(s, &length, &type);
- fprintf(stderr, "%s ", receiving ? "Receiving" : "Sending");
+ DEBUG_WARN( "%s ", receiving ? "Receiving" : "Sending");
em = bm + length;
if (Stream_GetRemainingLength(s) < (size_t) (length - 4))
{
- fprintf(stderr, "error processing stream\n");
+ DEBUG_WARN( "error processing stream\n");
return FALSE;
}
break;
default:
- fprintf(stderr, "unknown capability type %d\n", type);
+ DEBUG_WARN( "unknown capability type %d\n", type);
break;
}
if (s->pointer != em)
{
- fprintf(stderr, "incorrect offset, type:0x%02X actual:%d expected:%d\n",
+ DEBUG_WARN( "incorrect offset, type:0x%02X actual:%d expected:%d\n",
type, (int) (s->pointer - bm), (int) (em - bm));
}
}
else
{
- fprintf(stderr, "%s: not handling capability type %d yet\n", __FUNCTION__, type);
+ DEBUG_WARN( "%s: not handling capability type %d yet\n", __FUNCTION__, type);
}
em = bm + length;
if (Stream_GetRemainingLength(s) < ((size_t) length - 4))
{
- fprintf(stderr, "error processing stream\n");
+ DEBUG_WARN( "error processing stream\n");
return FALSE;
}
break;
default:
- fprintf(stderr, "unknown capability type %d\n", type);
+ DEBUG_WARN( "unknown capability type %d\n", type);
break;
}
if (s->pointer != em)
{
- fprintf(stderr, "incorrect offset, type:0x%02X actual:%d expected:%d\n",
+ DEBUG_WARN( "incorrect offset, type:0x%02X actual:%d expected:%d\n",
type, (int) (s->pointer - bm), (int) (em - bm));
}
if (numberCapabilities)
{
- fprintf(stderr, "%s: strange we haven't read the number of announced capacity sets, read=%d expected=%d\n",
+ DEBUG_WARN( "%s: strange we haven't read the number of announced capacity sets, read=%d expected=%d\n",
__FUNCTION__, count-numberCapabilities, count);
}
{
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
{
- fprintf(stderr, "rdp_decrypt failed\n");
+ DEBUG_WARN( "rdp_decrypt failed\n");
return FALSE;
}
}
if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId))
{
- fprintf(stderr, "unexpected MCS channel id %04x received\n", *pChannelId);
+ DEBUG_WARN( "unexpected MCS channel id %04x received\n", *pChannelId);
return FALSE;
}
}
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
{
- fprintf(stderr, "rdp_read_share_control_header failed\n");
+ DEBUG_WARN( "rdp_read_share_control_header failed\n");
return FALSE;
}
if (pduType != PDU_TYPE_DEMAND_ACTIVE)
{
if (pduType != PDU_TYPE_SERVER_REDIRECTION)
- fprintf(stderr, "expected PDU_TYPE_DEMAND_ACTIVE %04x, got %04x\n", PDU_TYPE_DEMAND_ACTIVE, pduType);
+ DEBUG_WARN( "expected PDU_TYPE_DEMAND_ACTIVE %04x, got %04x\n", PDU_TYPE_DEMAND_ACTIVE, pduType);
return FALSE;
}
/* capabilitySets */
if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities))
{
- fprintf(stderr, "rdp_read_capability_sets failed\n");
+ DEBUG_WARN( "rdp_read_capability_sets failed\n");
return FALSE;
}
#include "certificate.h"
+#define TAG "com.freerdp.core"
+
/**
*
* X.509 Certificate Structure
*
*/
-static const char *certificate_read_errors[] = {
+static const char* certificate_read_errors[] =
+{
"Certificate tag",
"TBSCertificate",
"Explicit Contextual Tag [0]",
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 */
info->ModulusLength = modulus_length;
info->Modulus = (BYTE*) malloc(info->ModulusLength);
+
if (!info->Modulus)
goto error1;
+
Stream_Read(s, info->Modulus, info->ModulusLength);
error++;
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:
- fprintf(stderr, "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;
}
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;
}
if (Stream_GetRemainingLength(s) < 20)
return FALSE;
+
Stream_Read(s, magic, 4);
if (memcmp(magic, "RSA1", 4) != 0)
{
- fprintf(stderr, "%s: magic error\n", __FUNCTION__);
+ DEBUG_WARN("%s: magic error\n", __FUNCTION__);
return FALSE;
}
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;
}
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. */
if (sum != 0)
{
- fprintf(stderr, "%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)
{
- fprintf(stderr, "%s: invalid signature\n", __FUNCTION__);
+ DEBUG_WARN("%s: invalid signature\n", __FUNCTION__);
//return FALSE;
}
if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01)
{
- fprintf(stderr, "%s: invalid signature\n", __FUNCTION__);
+ DEBUG_WARN("%s: invalid signature\n", __FUNCTION__);
//return FALSE;
}
if (!(dwSigAlgId == SIGNATURE_ALG_RSA && dwKeyAlgId == KEY_EXCHANGE_ALG_RSA))
{
- fprintf(stderr, "%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;
}
if (wPublicKeyBlobType != BB_RSA_KEY_BLOB)
{
- fprintf(stderr, "%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))
{
- fprintf(stderr, "%s: error in server public key\n", __FUNCTION__);
+ DEBUG_WARN("%s: error in server public key\n", __FUNCTION__);
return FALSE;
}
if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB)
{
- fprintf(stderr, "%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)
{
- fprintf(stderr, "%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)
{
- fprintf(stderr, "%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))
{
- fprintf(stderr, "%s: unable to parse server public signature\n", __FUNCTION__);
+ DEBUG_WARN("%s: unable to parse server public signature\n", __FUNCTION__);
return FALSE;
}
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;
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;
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) {
- fprintf(stderr, "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);
}
}
return TRUE;
s = Stream_New(server_cert, length);
-
Stream_Read_UINT32(s, dwVersion); /* dwVersion (4 bytes) */
switch (dwVersion & CERT_CHAIN_VERSION_MASK)
break;
default:
- fprintf(stderr, "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;
}
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)
{
- fprintf(stderr, "%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)
{
- fprintf(stderr, "%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;
switch (RSA_check_key(rsa))
{
case 0:
- fprintf(stderr, "%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:
break;
default:
- fprintf(stderr, "%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)
{
- fprintf(stderr, "%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:
if (key->Modulus)
free(key->Modulus);
+
free(key->PrivateExponent);
free(key);
}
if (!channel)
{
- fprintf(stderr, "freerdp_channel_send: unknown channelId %d\n", channelId);
+ DEBUG_WARN( "freerdp_channel_send: unknown channelId %d\n", channelId);
return FALSE;
}
if (channels->clientDataCount + 1 >= CHANNEL_MAX_COUNT)
{
- fprintf(stderr, "error: too many channels\n");
+ DEBUG_WARN( "error: too many channels\n");
return 1;
}
if (!status)
{
- fprintf(stderr, "error: channel export function call failed\n");
+ DEBUG_WARN( "error: channel export function call failed\n");
return 1;
}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * RDP Codecs
+ *
+ * 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 "rdp.h"
+
+#include <freerdp/codecs.h>
+
+int freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags)
+{
+ if (flags & FREERDP_CODEC_INTERLEAVED)
+ {
+ if (!codecs->interleaved)
+ {
+ codecs->interleaved = bitmap_interleaved_context_new(FALSE);
+ }
+ }
+
+ if (flags & FREERDP_CODEC_PLANAR)
+ {
+ if (!codecs->planar)
+ {
+ codecs->planar = freerdp_bitmap_planar_context_new(FALSE, 64, 64);
+ }
+ }
+
+ if (flags & FREERDP_CODEC_NSCODEC)
+ {
+ if (!codecs->nsc)
+ {
+ codecs->nsc = nsc_context_new();
+ }
+ }
+
+ if (flags & FREERDP_CODEC_REMOTEFX)
+ {
+ if (!codecs->rfx)
+ {
+ codecs->rfx = rfx_context_new(FALSE);
+ }
+ }
+
+ if (flags & FREERDP_CODEC_CLEARCODEC)
+ {
+ if (!codecs->clear)
+ {
+ codecs->clear = clear_context_new(FALSE);
+ }
+ }
+
+ if (flags & FREERDP_CODEC_ALPHACODEC)
+ {
+
+ }
+
+ if (flags & FREERDP_CODEC_PROGRESSIVE)
+ {
+ if (!codecs->progressive)
+ {
+ codecs->progressive = progressive_context_new(FALSE);
+ }
+ }
+
+ if (flags & FREERDP_CODEC_H264)
+ {
+ if (!codecs->h264)
+ {
+ codecs->h264 = h264_context_new(FALSE);
+ }
+ }
+
+ return 1;
+}
+
+rdpCodecs* codecs_new(rdpContext* context)
+{
+ rdpCodecs* codecs;
+
+ codecs = (rdpCodecs*) calloc(1, sizeof(rdpCodecs));
+
+ if (codecs)
+ {
+ codecs->context = context;
+ }
+
+ return codecs;
+}
+
+void codecs_free(rdpCodecs* codecs)
+{
+ if (!codecs)
+ return;
+
+ if (codecs->rfx)
+ {
+ rfx_context_free(codecs->rfx);
+ codecs->rfx = NULL;
+ }
+
+ if (codecs->nsc)
+ {
+ nsc_context_free(codecs->nsc);
+ codecs->nsc = NULL;
+ }
+
+ if (codecs->h264)
+ {
+ h264_context_free(codecs->h264);
+ codecs->h264 = NULL;
+ }
+
+ if (codecs->clear)
+ {
+ clear_context_free(codecs->clear);
+ codecs->clear = NULL;
+ }
+
+ if (codecs->progressive)
+ {
+ progressive_context_free(codecs->progressive);
+ codecs->progressive = NULL;
+ }
+
+ if (codecs->planar)
+ {
+ freerdp_bitmap_planar_context_free(codecs->planar);
+ codecs->planar = NULL;
+ }
+
+ if (codecs->interleaved)
+ {
+ bitmap_interleaved_context_free(codecs->interleaved);
+ codecs->interleaved = NULL;
+ }
+
+ free(codecs);
+}
+
freerdp_set_last_error(rdp->context, FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED);
}
- fprintf(stderr, "Error: protocol security negotiation or connection failure\n");
+ DEBUG_WARN( "Error: protocol security negotiation or connection failure\n");
return FALSE;
}
freerdp_set_last_error(rdp->context, FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR);
}
- fprintf(stderr, "Error: unable to send MCS Connect Initial\n");
+ DEBUG_WARN( "Error: unable to send MCS Connect Initial\n");
return FALSE;
}
wStream* s;
UINT32 length;
UINT32 key_len;
- BYTE *crypt_client_random = NULL;
- BOOL ret = FALSE;
int status = 0;
+ BOOL ret = FALSE;
+ rdpSettings* settings;
+ BYTE* crypt_client_random = NULL;
- if (!rdp->settings->DisableEncryption)
+ settings = rdp->settings;
+
+ if (!settings->DisableEncryption)
{
/* no RDP encryption */
return TRUE;
/* encrypt client random */
- if (rdp->settings->ClientRandom)
- free(rdp->settings->ClientRandom);
+ if (settings->ClientRandom)
+ free(settings->ClientRandom);
- rdp->settings->ClientRandom = malloc(CLIENT_RANDOM_LENGTH);
+ settings->ClientRandomLength = CLIENT_RANDOM_LENGTH;
+ settings->ClientRandom = malloc(settings->ClientRandomLength);
- if (!rdp->settings->ClientRandom)
+ if (!settings->ClientRandom)
return FALSE;
+ crypto_nonce(settings->ClientRandom, settings->ClientRandomLength);
+ key_len = settings->RdpServerCertificate->cert_info.ModulusLength;
+ mod = settings->RdpServerCertificate->cert_info.Modulus;
+ exp = settings->RdpServerCertificate->cert_info.exponent;
- crypto_nonce(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH);
- key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength;
- mod = rdp->settings->RdpServerCertificate->cert_info.Modulus;
- exp = rdp->settings->RdpServerCertificate->cert_info.exponent;
/*
* client random must be (bitlen / 8) + 8 - see [MS-RDPBCGR] 5.3.4.1
* for details
*/
- crypt_client_random = calloc(1,key_len+8);
+ crypt_client_random = calloc(1, key_len + 8);
+
if (!crypt_client_random)
return FALSE;
- crypto_rsa_public_encrypt(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH, key_len, mod, exp, crypt_client_random);
+
+ crypto_rsa_public_encrypt(settings->ClientRandom, settings->ClientRandomLength, key_len, mod, exp, crypt_client_random);
/* send crypt client random to server */
length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8;
goto end;
/* now calculate encrypt / decrypt and update keys */
- if (!security_establish_keys(rdp->settings->ClientRandom, rdp))
+ if (!security_establish_keys(settings->ClientRandom, rdp))
goto end;
rdp->do_crypt = TRUE;
- if (rdp->settings->SaltedChecksum)
+ if (settings->SaltedChecksum)
rdp->do_secure_checksum = TRUE;
- if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
+ if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
{
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
if (!rdp->fips_encrypt)
{
- fprintf(stderr, "%s: unable to allocate des3 encrypt key\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate des3 encrypt key\n", __FUNCTION__);
goto end;
}
rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);
if (!rdp->fips_decrypt)
{
- fprintf(stderr, "%s: unable to allocate des3 decrypt key\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate des3 decrypt key\n", __FUNCTION__);
goto end;
}
rdp->fips_hmac = crypto_hmac_new();
if (!rdp->fips_hmac)
{
- fprintf(stderr, "%s: unable to allocate fips hmac\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate fips hmac\n", __FUNCTION__);
goto end;
}
ret = TRUE;
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_decrypt_key)
{
- fprintf(stderr, "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__);
goto end;
}
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_encrypt_key)
{
- fprintf(stderr, "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__);
goto end;
}
ret = TRUE;
if (!rdp_read_header(rdp, s, &length, &channel_id))
{
- fprintf(stderr, "%s: invalid RDP header\n", __FUNCTION__);
+ DEBUG_WARN( "%s: invalid RDP header\n", __FUNCTION__);
return FALSE;
}
if (!rdp_read_security_header(s, &sec_flags))
{
- fprintf(stderr, "%s: invalid security header\n", __FUNCTION__);
+ DEBUG_WARN( "%s: invalid security header\n", __FUNCTION__);
return FALSE;
}
if ((sec_flags & SEC_EXCHANGE_PKT) == 0)
{
- fprintf(stderr, "%s: missing SEC_EXCHANGE_PKT in security header\n", __FUNCTION__);
+ DEBUG_WARN( "%s: missing SEC_EXCHANGE_PKT in security header\n", __FUNCTION__);
return FALSE;
}
if (rand_len != key_len + 8)
{
- fprintf(stderr, "%s: invalid encrypted client random length\n", __FUNCTION__);
+ DEBUG_WARN( "%s: invalid encrypted client random length\n", __FUNCTION__);
goto end2;
}
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
if (!rdp->fips_encrypt)
{
- fprintf(stderr, "%s: unable to allocate des3 encrypt key\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate des3 encrypt key\n", __FUNCTION__);
goto end;
}
rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);
if (!rdp->fips_decrypt)
{
- fprintf(stderr, "%s: unable to allocate des3 decrypt key\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate des3 decrypt key\n", __FUNCTION__);
goto end;
}
rdp->fips_hmac = crypto_hmac_new();
if (!rdp->fips_hmac)
{
- fprintf(stderr, "%s: unable to allocate fips hmac\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate fips hmac\n", __FUNCTION__);
goto end;
}
ret = TRUE;
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_decrypt_key)
{
- fprintf(stderr, "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__);
goto end;
}
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_encrypt_key)
{
- fprintf(stderr, "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__);
goto end;
}
ret = TRUE;
{
if (!mcs_recv_connect_response(rdp->mcs, s))
{
- fprintf(stderr, "rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed\n");
+ DEBUG_WARN( "rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed\n");
return FALSE;
}
if (rdp->license->state == LICENSE_STATE_ABORTED)
{
- fprintf(stderr, "license connection sequence aborted.\n");
+ DEBUG_WARN( "license connection sequence aborted.\n");
return -1;
}
nego->selected_protocol = 0;
- fprintf(stderr, "Client Security: NLA:%d TLS:%d RDP:%d\n",
+ DEBUG_WARN( "Client Security: NLA:%d TLS:%d RDP:%d\n",
(nego->requested_protocols & PROTOCOL_NLA) ? 1 : 0,
(nego->requested_protocols & PROTOCOL_TLS) ? 1 : 0,
(nego->requested_protocols == PROTOCOL_RDP) ? 1 : 0
);
- fprintf(stderr, "Server Security: NLA:%d TLS:%d RDP:%d\n",
+ DEBUG_WARN( "Server Security: NLA:%d TLS:%d RDP:%d\n",
settings->NlaSecurity, settings->TlsSecurity, settings->RdpSecurity);
if ((settings->NlaSecurity) && (nego->requested_protocols & PROTOCOL_NLA))
}
else
{
- fprintf(stderr, "Protocol security negotiation failure\n");
+ DEBUG_WARN( "Protocol security negotiation failure\n");
}
- fprintf(stderr, "Negotiated Security: NLA:%d TLS:%d RDP:%d\n",
+ DEBUG_WARN( "Negotiated Security: NLA:%d TLS:%d RDP:%d\n",
(nego->selected_protocol & PROTOCOL_NLA) ? 1 : 0,
(nego->selected_protocol & PROTOCOL_TLS) ? 1 : 0,
(nego->selected_protocol == PROTOCOL_RDP) ? 1: 0
if (!mcs_recv_connect_initial(mcs, s))
return FALSE;
- fprintf(stderr, "Accepted client: %s\n", rdp->settings->ClientHostname);
- fprintf(stderr, "Accepted channels:");
+ DEBUG_WARN( "Accepted client: %s\n", rdp->settings->ClientHostname);
+ DEBUG_WARN( "Accepted channels:");
for (i = 0; i < mcs->channelCount; i++)
{
- fprintf(stderr, " %s", mcs->channels[i].Name);
+ DEBUG_WARN( " %s", mcs->channels[i].Name);
}
- fprintf(stderr, "\n");
+ DEBUG_WARN( "\n");
if (!mcs_send_connect_response(mcs))
return FALSE;
#include <stdio.h>
+#include <freerdp/utils/debug.h>
+
#include "errinfo.h"
int connectErrorCode;
{
if (code == errInfo->code)
{
- fprintf(stderr, "%s (0x%08X):\n%s\n", errInfo->name, code, errInfo->info);
+ DEBUG_WARN( "%s (0x%08X):\n%s\n", errInfo->name, code, errInfo->info);
return;
}
errInfo++;
}
- fprintf(stderr, "ERRINFO_UNKNOWN 0x%08X: Unknown error.\n", code);
+ DEBUG_WARN( "ERRINFO_UNKNOWN 0x%08X: Unknown error.\n", code);
}
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
if (!fastpath_recv_update_synchronize(fastpath, s))
- fprintf(stderr, "fastpath_recv_update_synchronize failure but we continue\n");
+ DEBUG_WARN( "fastpath_recv_update_synchronize failure but we continue\n");
else
IFCALL(update->Synchronize, context);
break;
if (bulkStatus < 0)
{
- fprintf(stderr, "bulk_decompress() failed\n");
+ DEBUG_WARN( "bulk_decompress() failed\n");
return -1;
}
{
if (fastpath->fragmentation != -1)
{
- fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_SINGLE\n");
+ DEBUG_WARN( "Unexpected FASTPATH_FRAGMENT_SINGLE\n");
return -1;
}
{
if (fastpath->fragmentation != -1)
{
- fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_FIRST\n");
+ DEBUG_WARN( "Unexpected FASTPATH_FRAGMENT_FIRST\n");
return -1;
}
if (totalSize > transport->settings->MultifragMaxRequestSize)
{
- fprintf(stderr, "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n",
+ DEBUG_WARN( "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n",
totalSize, transport->settings->MultifragMaxRequestSize);
return -1;
}
if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) &&
(fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT))
{
- fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_NEXT\n");
+ DEBUG_WARN( "Unexpected FASTPATH_FRAGMENT_NEXT\n");
return -1;
}
if (totalSize > transport->settings->MultifragMaxRequestSize)
{
- fprintf(stderr, "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n",
+ DEBUG_WARN( "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n",
totalSize, transport->settings->MultifragMaxRequestSize);
return -1;
}
if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) &&
(fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT))
{
- fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_LAST\n");
+ DEBUG_WARN( "Unexpected FASTPATH_FRAGMENT_LAST\n");
return -1;
}
if (totalSize > transport->settings->MultifragMaxRequestSize)
{
- fprintf(stderr, "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n",
+ DEBUG_WARN( "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n",
totalSize, transport->settings->MultifragMaxRequestSize);
return -1;
}
break;
default:
- fprintf(stderr, "Unknown eventCode %d\n", eventCode);
+ DEBUG_WARN( "Unknown eventCode %d\n", eventCode);
break;
}
if (length >= (2 << 14))
{
- fprintf(stderr, "Maximum FastPath PDU length is 32767\n");
+ DEBUG_WARN( "Maximum FastPath PDU length is 32767\n");
return FALSE;
}
enum FASTPATH_INPUT_KBDFLAGS
{
FASTPATH_INPUT_KBDFLAGS_RELEASE = 0x01,
- FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02
+ FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02,
+ FASTPATH_INPUT_KBDFLAGS_PREFIX_E1 = 0x04 /* for pause sequence */
};
struct _FASTPATH_UPDATE_PDU_HEADER
freerdp_set_last_error(instance->context, FREERDP_ERROR_PRE_CONNECT_FAILED);
}
- fprintf(stderr, "freerdp_pre_connect failed\n");
+ DEBUG_WARN( "freerdp_pre_connect failed\n");
goto freerdp_connect_finally;
}
/* --authonly tests the connection without a UI */
if (instance->settings->AuthenticationOnly)
{
- fprintf(stderr, "Authentication only, exit status %d\n", !status);
+ DEBUG_WARN( "Authentication only, exit status %d\n", !status);
goto freerdp_connect_finally;
}
if (!status)
{
- fprintf(stderr, "freerdp_post_connect failed\n");
+ DEBUG_WARN( "freerdp_post_connect failed\n");
if (!connectErrorCode)
{
rdp = instance->context->rdp;
transport_disconnect(rdp->transport);
+ update_post_disconnect(instance->update);
IFCALL(instance->PostDisconnect, instance);
if (instance->update->pcap_rfx)
PubSub_AddEventTypes(context->pubSub, FreeRDP_Events, sizeof(FreeRDP_Events) / sizeof(wEventType));
context->metrics = metrics_new(context);
+ context->codecs = codecs_new(context);
rdp = rdp_new(context);
instance->input = rdp->input;
PubSub_Free(instance->context->pubSub);
metrics_free(instance->context->metrics);
+ codecs_free(instance->context->codecs);
free(instance->context);
instance->context = NULL;
void freerdp_set_last_error(rdpContext* context, UINT32 lastError)
{
if (lastError)
- fprintf(stderr, "freerdp_set_last_error 0x%04X\n", lastError);
+ DEBUG_WARN( "freerdp_set_last_error 0x%04X\n", lastError);
context->LastError = lastError;
}
#include <winpr/stream.h>
#include <winpr/string.h>
+#include <freerdp/utils/debug.h>
+
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
#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)
{
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;
}
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;
}
{
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;
}
{
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;
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;
}
{
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;
Stream_Write(s, "\r\n", 2);
free(lines[i]);
}
- Stream_Write(s, "\r\n", 2);
+ 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;
}
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);
char* separator;
char* status_code;
char* reason_phrase;
-
separator = strchr(status_line, ' ');
+
if (!separator)
return FALSE;
- status_code = separator + 1;
+ 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;
}
else if (_stricmp(name, "WWW-Authenticate") == 0)
{
char* separator;
- char *authScheme, *authValue;
-
+ char* authScheme, *authValue;
separator = strchr(value, ' ');
if (separator != NULL)
* 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;
}
for (count = 1; count < http_response->count; count++)
{
line = http_response->lines[count];
-
/**
* name end_of_header
* | |
* 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 */
*end_of_header = end_of_header_char;
}
+
return TRUE;
}
for (i = 0; i < http_response->count; i++)
{
- fprintf(stderr, "%s\n", http_response->lines[i]);
+ DEBUG_WARN("%s\n", http_response->lines[i]);
}
- fprintf(stderr, "\n");
+
+ DEBUG_WARN("\n");
}
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;
while (nbytes < 5)
{
status = BIO_read(tls->bio, p, length - nbytes);
-
+
if (status <= 0)
{
if (!BIO_should_retry(tls->bio))
}
header_end = strstr((char*) buffer, "\r\n\r\n");
-
+
if (!header_end)
{
- fprintf(stderr, "%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;
}
{
int count;
char* line;
-
header_end[0] = '\0';
header_end[1] = '\0';
content = header_end + 2;
-
count = 0;
line = (char*) buffer;
}
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;
}
while (line != NULL)
{
http_response->lines[count] = _strdup(line);
+
if (!http_response->lines[count])
goto out_error;
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;
}
free(buffer);
-
return http_response;
-
out_error:
http_response_free(http_response);
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;
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;
free(http_response->lines[i]);
free(http_response->lines);
-
free(http_response->ReasonPhrase);
-
ListDictionary_Free(http_response->Authenticates);
if (http_response->ContentLength > 0)
if (status != SEC_E_OK)
{
- fprintf(stderr, "QuerySecurityPackageInfo status: 0x%08X\n", status);
+ DEBUG_WARN( "QuerySecurityPackageInfo status: 0x%08X\n", status);
return FALSE;
}
if (status != SEC_E_OK)
{
- fprintf(stderr, "AcquireCredentialsHandle status: 0x%08X\n", status);
+ DEBUG_WARN( "AcquireCredentialsHandle status: 0x%08X\n", status);
return FALSE;
}
if ((!ntlm) || (!ntlm->table))
{
- fprintf(stderr, "ntlm_authenticate: invalid ntlm context\n");
+ DEBUG_WARN( "ntlm_authenticate: invalid ntlm context\n");
return FALSE;
}
if (ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes) != SEC_E_OK)
{
- fprintf(stderr, "QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
+ DEBUG_WARN( "QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
return FALSE;
}
#include <winpr/tchar.h>
#include <winpr/synch.h>
#include <winpr/dsparse.h>
+#include <freerdp/log.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#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[] =
{
void rpc_pdu_header_print(rpcconn_hdr_t* header)
{
- fprintf(stderr, "rpc_vers: %d\n", header->common.rpc_vers);
- fprintf(stderr, "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)
- fprintf(stderr, "ptype: %s (%d)\n", "PTYPE_UNKNOWN", header->common.ptype);
+ DEBUG_WARN("ptype: %s (%d)\n", "PTYPE_UNKNOWN", header->common.ptype);
else
- fprintf(stderr, "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);
- fprintf(stderr, "pfc_flags (0x%02X) = {", header->common.pfc_flags);
if (header->common.pfc_flags & PFC_FIRST_FRAG)
- fprintf(stderr, " PFC_FIRST_FRAG");
+ DEBUG_WARN(" PFC_FIRST_FRAG");
+
if (header->common.pfc_flags & PFC_LAST_FRAG)
- fprintf(stderr, " PFC_LAST_FRAG");
+ DEBUG_WARN(" PFC_LAST_FRAG");
+
if (header->common.pfc_flags & PFC_PENDING_CANCEL)
- fprintf(stderr, " PFC_PENDING_CANCEL");
+ DEBUG_WARN(" PFC_PENDING_CANCEL");
+
if (header->common.pfc_flags & PFC_RESERVED_1)
- fprintf(stderr, " PFC_RESERVED_1");
+ DEBUG_WARN(" PFC_RESERVED_1");
+
if (header->common.pfc_flags & PFC_CONC_MPX)
- fprintf(stderr, " PFC_CONC_MPX");
+ DEBUG_WARN(" PFC_CONC_MPX");
+
if (header->common.pfc_flags & PFC_DID_NOT_EXECUTE)
- fprintf(stderr, " PFC_DID_NOT_EXECUTE");
- if (header->common.pfc_flags & PFC_OBJECT_UUID)
- fprintf(stderr, " PFC_OBJECT_UUID");
- fprintf(stderr, " }\n");
+ DEBUG_WARN(" PFC_DID_NOT_EXECUTE");
- fprintf(stderr, "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]);
+ if (header->common.pfc_flags & PFC_OBJECT_UUID)
+ DEBUG_WARN(" PFC_OBJECT_UUID");
- fprintf(stderr, "frag_length: %d\n", header->common.frag_length);
- fprintf(stderr, "auth_length: %d\n", header->common.auth_length);
- fprintf(stderr, "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)
{
- fprintf(stderr, "alloc_hint: %d\n", header->response.alloc_hint);
- fprintf(stderr, "p_cont_id: %d\n", header->response.p_cont_id);
- fprintf(stderr, "cancel_count: %d\n", header->response.cancel_count);
- fprintf(stderr, "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);
}
}
UINT32 rpc_offset_align(UINT32* offset, UINT32 alignment)
{
UINT32 pad;
-
pad = *offset;
*offset = (*offset + alignment - 1) & ~(alignment - 1);
pad = *offset - pad;
-
return pad;
}
UINT32 auth_pad_length;
UINT32 sec_trailer_offset;
rpc_sec_trailer* sec_trailer;
-
*offset = RPC_COMMON_FIELDS_LENGTH;
header = ((rpcconn_hdr_t*) buffer);
*offset += 4;
break;
default:
- fprintf(stderr, "%s: unknown ptype=0x%x\n", __FUNCTION__, header->common.ptype);
+ DEBUG_WARN("%s: unknown ptype=0x%x\n", __FUNCTION__, header->common.ptype);
return FALSE;
}
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
- fprintf(stderr, "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
/**
if ((frag_length - (sec_trailer_offset + 8)) != auth_length)
{
- fprintf(stderr, "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;
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
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
- fprintf(stderr, "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);
- fprintf(stderr, "\n");
+ winpr_HexDump(TAG, WLOG_DEBUG, data, length);
+ DEBUG_WARN("\n");
#endif
-
status = tls_write_all(rpc->TlsIn, data, length);
-
return status;
}
RpcClientCall* clientCall;
SECURITY_STATUS encrypt_status;
rpcconn_request_hdr_t* request_pdu;
-
ntlm = rpc->ntlm;
if (!ntlm || !ntlm->table)
{
- fprintf(stderr, "%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)
{
- fprintf(stderr, "%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;
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;
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;
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)
{
- fprintf(stderr, "EncryptMessage status: 0x%08X\n", encrypt_status);
+ DEBUG_WARN("EncryptMessage status: 0x%08X\n", encrypt_status);
free(request_pdu);
return -1;
}
length = -1;
free(request_pdu);
-
return length;
-
out_free_clientCall:
rpc_client_call_free(clientCall);
out_free_pdu:
if (!rts_connect(rpc))
{
- fprintf(stderr, "rts_connect error!\n");
+ DEBUG_WARN("rts_connect error!\n");
return FALSE;
}
if (rpc_secure_bind(rpc) != 0)
{
- fprintf(stderr, "rpc_secure_bind error!\n");
+ DEBUG_WARN("rpc_secure_bind error!\n");
return FALSE;
}
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;
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);
+ rpc_client_virtual_connection_init(rpc, connection);
return connection;
-
out_default_in:
free(connection->DefaultInChannel);
out_free:
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;
rpc->client->SynchronousSend = TRUE;
rpc->client->SynchronousReceive = TRUE;
-
return rpc;
-
out_free_virtualConnectionCookieTable:
rpc_client_free(rpc);
ArrayList_Free(rpc->VirtualConnectionCookieTable);
}
rpc_client_virtual_connection_free(rpc->VirtualConnection);
-
ArrayList_Clear(rpc->VirtualConnectionCookieTable);
ArrayList_Free(rpc->VirtualConnectionCookieTable);
-
free(rpc);
}
}
if (status <= 0)
{
- fprintf(stderr, "rpc_secure_bind: error sending bind pdu!\n");
+ DEBUG_WARN( "rpc_secure_bind: error sending bind pdu!\n");
return -1;
}
if (!pdu)
{
- fprintf(stderr, "rpc_secure_bind: error receiving bind ack pdu!\n");
+ DEBUG_WARN( "rpc_secure_bind: error receiving bind ack pdu!\n");
return -1;
}
if (rpc_recv_bind_ack_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s)) <= 0)
{
- fprintf(stderr, "rpc_secure_bind: error receiving bind ack pdu!\n");
+ DEBUG_WARN( "rpc_secure_bind: error receiving bind ack pdu!\n");
return -1;
}
if (rpc_send_rpc_auth_3_pdu(rpc) <= 0)
{
- fprintf(stderr, "rpc_secure_bind: error sending rpc_auth_3 pdu!\n");
+ DEBUG_WARN( "rpc_secure_bind: error sending rpc_auth_3 pdu!\n");
return -1;
}
}
else
{
- fprintf(stderr, "rpc_secure_bind: invalid state: %d\n", rpc->State);
+ DEBUG_WARN( "rpc_secure_bind: invalid state: %d\n", rpc->State);
return -1;
}
}
#include "rpc_client.h"
#include "../rdp.h"
+#define TAG "gateway"
#define SYNCHRONOUS_TIMEOUT 5000
wStream* rpc_client_fragment_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);
pdu->CallId = 0;
pdu->Flags = 0;
-
Stream_Length(pdu->s) = 0;
Stream_SetPosition(pdu->s, 0);
-
return pdu;
}
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);
{
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)
{
- fprintf(stderr, "%s: warning: unhandled RTS PDU\n", __FUNCTION__);
+ DEBUG_WARN("%s: warning: unhandled RTS PDU\n", __FUNCTION__);
return 0;
}
- fprintf(stderr, "%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);
case PTYPE_RESPONSE:
break;
default:
- fprintf(stderr, "%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;
}
if (!rpc_get_stub_data_info(rpc, buffer, &StubOffset, &StubLength))
{
- fprintf(stderr, "%s: expected stub\n", __FUNCTION__);
+ DEBUG_WARN("%s: expected stub\n", __FUNCTION__);
Queue_Enqueue(rpc->client->ReceiveQueue, NULL);
return -1;
}
if (StubLength == 4)
{
- //fprintf(stderr, "Ignoring TsProxySendToServer Response\n");
- //printf("Got stub length 4 with flags %d and callid %d\n", header->common.pfc_flags, header->common.call_id);
+ //DEBUG_WARN( "Ignoring TsProxySendToServer Response\n");
+ //DEBUG_MSG("Got stub length 4 with flags %d and callid %d\n", header->common.pfc_flags, header->common.call_id);
/* received a disconnect request from the server? */
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);
if (rpc->StubCallId != header->common.call_id)
{
- fprintf(stderr, "%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))
{
- //fprintf(stderr, "Sending Flow Control Ack PDU\n");
+ //DEBUG_WARN( "Sending Flow Control Ack PDU\n");
rts_send_flow_control_ack_pdu(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;
}
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)
{
- fprintf(stderr, "rpc_client_frag_read: error reading header\n");
+ DEBUG_WARN("rpc_client_frag_read: error reading header\n");
return -1;
}
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)
{
- fprintf(stderr, "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)
{
- fprintf(stderr, "%s: error reading fragment body\n", __FUNCTION__);
+ DEBUG_WARN("%s: error reading fragment body\n", __FUNCTION__);
return -1;
}
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;
int index;
int count;
RpcClientCall* clientCall;
-
ArrayList_Lock(rpc->client->ClientCallList);
-
clientCall = NULL;
count = ArrayList_Count(rpc->client->ClientCallList);
}
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;
}
{
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;
if (rpc->client->SynchronousSend)
{
status = WaitForSingleObject(rpc->client->PduSentEvent, SYNCHRONOUS_TIMEOUT);
+
if (status == WAIT_TIMEOUT)
{
- fprintf(stderr, "%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;
}
}
return 0;
-
out_free_stream:
Stream_Free(pdu->s, TRUE);
out_free:
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);
/*
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)
{
- fprintf(stderr, "%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)
{
- fprintf(stderr, "Receiving PDU (length: %d, CallId: %d)\n", pdu->s->length, pdu->CallId);
- winpr_HexDump(Stream_Buffer(pdu->s), Stream_Length(pdu->s));
- fprintf(stderr, "\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
{
- fprintf(stderr, "Receiving a NULL PDU\n");
+ DEBUG_WARN("Receiving a NULL PDU\n");
}
-#endif
+#endif
return pdu;
}
{
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)
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);
*/
if (rpc_client_on_read_event(rpc) < 0)
{
- fprintf(stderr, "%s: an error occured when treating first packet\n", __FUNCTION__);
+ DEBUG_WARN("%s: an error occured when treating first packet\n", __FUNCTION__);
goto out;
}
out:
CloseHandle(ReadEvent);
-
return NULL;
}
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;
}
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;
}
int rpc_client_free(rdpRpc* rpc)
{
RpcClient* client;
-
client = rpc->client;
if (!client)
if (client->FragmentPool)
Queue_Free(client->FragmentPool);
+
if (client->FragmentQueue)
Queue_Free(client->FragmentQueue);
if (client->ReceivePool)
Queue_Free(client->ReceivePool);
+
if (client->ReceiveQueue)
Queue_Free(client->ReceiveQueue);
if (client->StopEvent)
CloseHandle(client->StopEvent);
+
if (client->PduSentEvent)
CloseHandle(client->PduSentEvent);
int index;
UINT32 code;
- fprintf(stderr, "RPC Fault PDU:\n");
+ DEBUG_WARN( "RPC Fault PDU:\n");
code = rpc_map_status_code_to_win32_error_code(header->fault.status);
{
if (RPC_FAULT_CODES[index].code == code)
{
- fprintf(stderr, "status: %s (0x%08X)\n", RPC_FAULT_CODES[index].name, code);
+ DEBUG_WARN( "status: %s (0x%08X)\n", RPC_FAULT_CODES[index].name, code);
return 0;
}
}
{
if (RPC_TSG_FAULT_CODES[index].code == code)
{
- fprintf(stderr, "status: %s (0x%08X)\n", RPC_TSG_FAULT_CODES[index].name, code);
+ DEBUG_WARN( "status: %s (0x%08X)\n", RPC_TSG_FAULT_CODES[index].name, code);
return 0;
}
}
- fprintf(stderr, "status: %s (0x%08X)\n", "UNKNOWN", code);
+ DEBUG_WARN( "status: %s (0x%08X)\n", "UNKNOWN", code);
return 0;
}
if (!rpc_ntlm_http_out_connect(rpc))
{
- fprintf(stderr, "%s: rpc_out_connect_http error!\n", __FUNCTION__);
+ DEBUG_WARN( "%s: rpc_out_connect_http error!\n", __FUNCTION__);
return FALSE;
}
if (rts_send_CONN_A1_pdu(rpc) != 0)
{
- fprintf(stderr, "%s: rpc_send_CONN_A1_pdu error!\n", __FUNCTION__);
+ DEBUG_WARN( "%s: rpc_send_CONN_A1_pdu error!\n", __FUNCTION__);
return FALSE;
}
if (!rpc_ntlm_http_in_connect(rpc))
{
- fprintf(stderr, "%s: rpc_in_connect_http error!\n", __FUNCTION__);
+ DEBUG_WARN( "%s: rpc_in_connect_http error!\n", __FUNCTION__);
return FALSE;
}
if (rts_send_CONN_B1_pdu(rpc) < 0)
{
- fprintf(stderr, "%s: rpc_send_CONN_B1_pdu error!\n", __FUNCTION__);
+ DEBUG_WARN( "%s: rpc_send_CONN_B1_pdu error!\n", __FUNCTION__);
return FALSE;
}
http_response = http_response_recv(rpc->TlsOut);
if (!http_response)
{
- fprintf(stderr, "%s: unable to retrieve OUT Channel Response!\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to retrieve OUT Channel Response!\n", __FUNCTION__);
return FALSE;
}
if (http_response->StatusCode != HTTP_STATUS_OK)
{
- fprintf(stderr, "%s: error! Status Code: %d\n", __FUNCTION__, http_response->StatusCode);
+ DEBUG_WARN( "%s: error! Status Code: %d\n", __FUNCTION__, http_response->StatusCode);
http_response_print(http_response);
http_response_free(http_response);
if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_A3_SIGNATURE, rts))
{
- fprintf(stderr, "%s: unexpected RTS PDU: Expected CONN/A3\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unexpected RTS PDU: Expected CONN/A3\n", __FUNCTION__);
return FALSE;
}
if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts))
{
- fprintf(stderr, "%s: unexpected RTS PDU: Expected CONN/C2\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unexpected RTS PDU: Expected CONN/C2\n", __FUNCTION__);
return FALSE;
}
&BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4;
#if 0
- fprintf(stderr, "BytesReceived: %d AvailableWindow: %d\n",
+ DEBUG_WARN( "BytesReceived: %d AvailableWindow: %d\n",
BytesReceived, AvailableWindow);
- fprintf(stderr, "ChannelCookie: " RPC_UUID_FORMAT_STRING "\n", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie));
+ DEBUG_WARN( "ChannelCookie: " RPC_UUID_FORMAT_STRING "\n", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie));
#endif
rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow =
&BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4;
#if 0
- fprintf(stderr, "Destination: %d BytesReceived: %d AvailableWindow: %d\n",
+ DEBUG_WARN( "Destination: %d BytesReceived: %d AvailableWindow: %d\n",
Destination, BytesReceived, AvailableWindow);
- fprintf(stderr, "ChannelCookie: " RPC_UUID_FORMAT_STRING "\n", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie));
+ DEBUG_WARN( "ChannelCookie: " RPC_UUID_FORMAT_STRING "\n", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie));
#endif
rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow =
break;
default:
- fprintf(stderr, "Error: Unknown RTS Command Type: 0x%x\n", CommandType);
+ DEBUG_WARN( "Error: Unknown RTS Command Type: 0x%x\n", CommandType);
return -1;
break;
}
case RTS_PDU_PING:
return rts_send_ping_pdu(rpc);
default:
- fprintf(stderr, "%s: unimplemented signature id: 0x%08X\n", __FUNCTION__, SignatureId);
+ DEBUG_WARN( "%s: unimplemented signature id: 0x%08X\n", __FUNCTION__, SignatureId);
rts_print_pdu_signature(rpc, &signature);
break;
}
UINT32 SignatureId;
RTS_PDU_SIGNATURE_ENTRY* entry;
- fprintf(stderr, "RTS PDU Signature: Flags: 0x%04X NumberOfCommands: %d\n",
+ DEBUG_WARN( "RTS PDU Signature: Flags: 0x%04X NumberOfCommands: %d\n",
signature->Flags, signature->NumberOfCommands);
SignatureId = rts_identify_pdu_signature(rpc, signature, &entry);
if (SignatureId)
- fprintf(stderr, "Identified %s RTS PDU\n", entry->PduName);
+ DEBUG_WARN( "Identified %s RTS PDU\n", entry->PduName);
return 0;
}
#include <winpr/error.h>
#include <winpr/print.h>
#include <winpr/stream.h>
-
+#include <freerdp/log.h>
#include "rpc_client.h"
#include "tsg.h"
+#define TAG FREERDP_TAG("core")
/**
* RPC Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378623/
BYTE TsProxyCreateTunnelUnknownTrailerBytes[60] =
{
- 0x8A, 0xE3, 0x13, 0x71, 0x02, 0xF4, 0x36, 0x71, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x02, 0x40, 0x28, 0x00, 0xDD, 0x65, 0xE2, 0x44, 0xAF, 0x7D, 0xCD, 0x42, 0x85, 0x60, 0x3C, 0xDB,
- 0x6E, 0x7A, 0x27, 0x29, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11,
- 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00
+ 0x8A, 0xE3, 0x13, 0x71, 0x02, 0xF4, 0x36, 0x71, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x02, 0x40, 0x28, 0x00, 0xDD, 0x65, 0xE2, 0x44, 0xAF, 0x7D, 0xCD, 0x42, 0x85, 0x60, 0x3C, 0xDB,
+ 0x6E, 0x7A, 0x27, 0x29, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11,
+ 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00
};
DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], UINT32 count, UINT32* lengths)
UINT32 buffer3Length;
UINT32 numBuffers = 0;
UINT32 totalDataBytes = 0;
-
tsg = (rdpTsg*) IDL_handle;
buffer1Length = buffer2Length = buffer3Length = 0;
length = 28 + totalDataBytes;
buffer = (BYTE*) calloc(1, length);
+
if (!buffer)
return -1;
s = Stream_New(buffer, length);
-
/* PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE_NR (20 bytes) */
Stream_Write(s, &tsg->ChannelContext.ContextType, 4); /* ContextType (4 bytes) */
Stream_Write(s, tsg->ChannelContext.ContextUuid, 16); /* ContextUuid (16 bytes) */
-
Stream_Write_UINT32_BE(s, totalDataBytes); /* totalDataBytes (4 bytes) */
Stream_Write_UINT32_BE(s, numBuffers); /* numBuffers (4 bytes) */
if (buffer1Length > 0)
Stream_Write_UINT32_BE(s, buffer1Length); /* buffer1Length (4 bytes) */
+
if (buffer2Length > 0)
Stream_Write_UINT32_BE(s, buffer2Length); /* buffer2Length (4 bytes) */
+
if (buffer3Length > 0)
Stream_Write_UINT32_BE(s, buffer3Length); /* buffer3Length (4 bytes) */
if (buffer1Length > 0)
Stream_Write(s, buffer1, buffer1Length); /* buffer1 (variable) */
+
if (buffer2Length > 0)
Stream_Write(s, buffer2, buffer2Length); /* buffer2 (variable) */
+
if (buffer3Length > 0)
Stream_Write(s, buffer3, buffer3Length); /* buffer3 (variable) */
Stream_Length(s) = Stream_GetPosition(s);
-
status = rpc_write(tsg->rpc, Stream_Buffer(s), Stream_Length(s), TsProxySendToServerOpnum);
-
Stream_Free(s, TRUE);
if (status <= 0)
{
- fprintf(stderr, "rpc_write failed!\n");
+ DEBUG_WARN("rpc_write failed!\n");
return -1;
}
UINT32 length;
UINT32 NapCapabilities;
rdpRpc* rpc = tsg->rpc;
-
length = 108;
buffer = (BYTE*) malloc(length);
-
*((UINT32*) &buffer[0]) = TSG_PACKET_TYPE_VERSIONCAPS; /* PacketId */
*((UINT32*) &buffer[4]) = TSG_PACKET_TYPE_VERSIONCAPS; /* SwitchValue */
-
*((UINT32*) &buffer[8]) = 0x00020000; /* PacketVersionCapsPtr */
-
*((UINT16*) &buffer[12]) = TS_GATEWAY_TRANSPORT; /* ComponentId */
*((UINT16*) &buffer[14]) = TSG_PACKET_TYPE_VERSIONCAPS; /* PacketId */
-
*((UINT32*) &buffer[16]) = 0x00020004; /* TsgCapsPtr */
*((UINT32*) &buffer[20]) = 0x00000001; /* NumCapabilities */
-
*((UINT16*) &buffer[24]) = 0x0001; /* MajorVersion */
*((UINT16*) &buffer[26]) = 0x0001; /* MinorVersion */
*((UINT16*) &buffer[28]) = 0x0000; /* QuarantineCapabilities */
-
/* 4-byte alignment (30 + 2) */
*((UINT16*) &buffer[30]) = 0x0000; /* 2-byte pad */
-
*((UINT32*) &buffer[32]) = 0x00000001; /* MaxCount */
*((UINT32*) &buffer[36]) = TSG_CAPABILITY_TYPE_NAP; /* CapabilityType */
*((UINT32*) &buffer[40]) = TSG_CAPABILITY_TYPE_NAP; /* SwitchValue */
-
NapCapabilities =
- TSG_NAP_CAPABILITY_QUAR_SOH |
- TSG_NAP_CAPABILITY_IDLE_TIMEOUT |
- TSG_MESSAGING_CAP_CONSENT_SIGN |
- TSG_MESSAGING_CAP_SERVICE_MSG |
- TSG_MESSAGING_CAP_REAUTH;
-
+ TSG_NAP_CAPABILITY_QUAR_SOH |
+ TSG_NAP_CAPABILITY_IDLE_TIMEOUT |
+ TSG_MESSAGING_CAP_CONSENT_SIGN |
+ TSG_MESSAGING_CAP_SERVICE_MSG |
+ TSG_MESSAGING_CAP_REAUTH;
/*
* Alternate Code Path
*
* "Only allow connections from Remote Desktop Services clients that support RD Gateway messaging"
*/
//NapCapabilities = TSG_NAP_CAPABILITY_IDLE_TIMEOUT;
-
*((UINT32*) &buffer[44]) = NapCapabilities; /* capabilities */
-
CopyMemory(&buffer[48], TsProxyCreateTunnelUnknownTrailerBytes, 60);
-
status = rpc_write(rpc, buffer, length, TsProxyCreateTunnelOpnum);
if (status <= 0)
return FALSE;
free(buffer);
-
return TRUE;
}
buffer = &buffer[24];
packet = (PTSG_PACKET) calloc(1, sizeof(TSG_PACKET));
+
if (!packet)
return FALSE;
if ((packet->packetId == TSG_PACKET_TYPE_CAPS_RESPONSE) && (SwitchValue == TSG_PACKET_TYPE_CAPS_RESPONSE))
{
packetCapsResponse = (PTSG_PACKET_CAPS_RESPONSE) calloc(1, sizeof(TSG_PACKET_CAPS_RESPONSE));
+
if (!packetCapsResponse) // TODO: correct cleanup
return FALSE;
- packet->tsgPacket.packetCapsResponse = packetCapsResponse;
+ packet->tsgPacket.packetCapsResponse = packetCapsResponse;
/* PacketQuarResponsePtr (4 bytes) */
packetCapsResponse->pktQuarEncResponse.flags = *((UINT32*) &buffer[offset + 12]); /* Flags */
packetCapsResponse->pktQuarEncResponse.certChainLen = *((UINT32*) &buffer[offset + 16]); /* CertChainLength */
/* CertChainDataPtr (4 bytes) */
CopyMemory(&packetCapsResponse->pktQuarEncResponse.nonce, &buffer[offset + 24], 16); /* Nonce */
offset += 40;
-
Pointer = *((UINT32*) &buffer[offset]); /* VersionCapsPtr */
offset += 4;
{
Pointer = *((UINT32*) &buffer[offset]); /* MsgPtr (4 bytes): 0x00020014 */
offset += 4;
-
offset += 4; /* MaxCount (4 bytes) */
offset += 4; /* Offset (4 bytes) */
count = *((UINT32*) &buffer[offset]); /* ActualCount (4 bytes) */
offset += 4;
-
/*
* CertChainData is a wide character string, and the count is
* given in characters excluding the null terminator, therefore:
* size = (count * 2)
*/
offset += (count * 2); /* CertChainData */
-
/* 4-byte alignment */
rpc_offset_align(&offset, 4);
}
}
versionCaps = (PTSG_PACKET_VERSIONCAPS) calloc(1, sizeof(TSG_PACKET_VERSIONCAPS));
+
if (!versionCaps) // TODO: correct cleanup
return FALSE;
- packetCapsResponse->pktQuarEncResponse.versionCaps = versionCaps;
+ packetCapsResponse->pktQuarEncResponse.versionCaps = versionCaps;
versionCaps->tsgHeader.ComponentId = *((UINT16*) &buffer[offset]); /* ComponentId */
versionCaps->tsgHeader.PacketId = *((UINT16*) &buffer[offset + 2]); /* PacketId */
offset += 4;
if (versionCaps->tsgHeader.ComponentId != TS_GATEWAY_TRANSPORT)
{
- fprintf(stderr, "Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n",
- versionCaps->tsgHeader.ComponentId);
+ DEBUG_WARN("Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n",
+ versionCaps->tsgHeader.ComponentId);
free(packetCapsResponse);
free(versionCaps);
free(packet);
versionCaps->minorVersion = *((UINT16*) &buffer[offset + 10]); /* MinorVersion */
versionCaps->quarantineCapabilities = *((UINT16*) &buffer[offset + 12]); /* QuarantineCapabilities */
offset += 14;
-
/* 4-byte alignment */
rpc_offset_align(&offset, 4);
-
tsgCaps = (PTSG_PACKET_CAPABILITIES) calloc(1, sizeof(TSG_PACKET_CAPABILITIES));
+
if (!tsgCaps)
return FALSE;
versionCaps->tsgCaps = tsgCaps;
-
offset += 4; /* MaxCount (4 bytes) */
tsgCaps->capabilityType = *((UINT32*) &buffer[offset]); /* CapabilityType */
SwitchValue = *((UINT32*) &buffer[offset + 4]); /* SwitchValue */
if ((SwitchValue != TSG_CAPABILITY_TYPE_NAP) || (tsgCaps->capabilityType != TSG_CAPABILITY_TYPE_NAP))
{
- fprintf(stderr, "Unexpected CapabilityType: 0x%08X, Expected TSG_CAPABILITY_TYPE_NAP\n",
- tsgCaps->capabilityType);
+ DEBUG_WARN("Unexpected CapabilityType: 0x%08X, Expected TSG_CAPABILITY_TYPE_NAP\n",
+ tsgCaps->capabilityType);
free(tsgCaps);
free(versionCaps);
free(packetCapsResponse);
if (MsgBytes > TSG_MESSAGING_MAX_MESSAGE_LENGTH)
{
- fprintf(stderr, "Out of Spec Message Length %d", MsgBytes);
+ DEBUG_WARN("Out of Spec Message Length %d", MsgBytes);
free(tsgCaps);
free(versionCaps);
free(packetCapsResponse);
free(packet);
return FALSE;
}
+
offset += MsgBytes;
break;
-
case TSG_ASYNC_MESSAGE_REAUTH:
rpc_offset_align(&offset, 8);
offset += 8; // UINT64 TunnelContext, not to be confused with
- // the ContextHandle TunnelContext below.
+ // the ContextHandle TunnelContext below.
break;
-
default:
- fprintf(stderr, "Unexpected Message Type: 0x%X\n", (int) MessageSwitchValue);
+ DEBUG_WARN("Unexpected Message Type: 0x%X\n", (int) MessageSwitchValue);
free(tsgCaps);
free(versionCaps);
free(packetCapsResponse);
free(packet);
return FALSE;
-
}
rpc_offset_align(&offset, 4);
-
/* TunnelContext (20 bytes) */
CopyMemory(&tsg->TunnelContext.ContextType, &buffer[offset], 4); /* ContextType */
CopyMemory(tsg->TunnelContext.ContextUuid, &buffer[offset + 4], 16); /* ContextUuid */
offset += 20;
// UINT32 TunnelId
// HRESULT ReturnValue
-
#ifdef WITH_DEBUG_TSG
- fprintf(stderr, "TSG TunnelContext:\n");
- winpr_HexDump((void*) &tsg->TunnelContext, 20);
- fprintf(stderr, "\n");
+ DEBUG_WARN("TSG TunnelContext:\n");
+ winpr_HexDump(TAG, WLOG_DEBUG, (void*) &tsg->TunnelContext, 20);
+ DEBUG_WARN("\n");
#endif
-
free(tsgCaps);
free(versionCaps);
free(packetCapsResponse);
else if ((packet->packetId == TSG_PACKET_TYPE_QUARENC_RESPONSE) && (SwitchValue == TSG_PACKET_TYPE_QUARENC_RESPONSE))
{
packetQuarEncResponse = (PTSG_PACKET_QUARENC_RESPONSE) calloc(1, sizeof(TSG_PACKET_QUARENC_RESPONSE));
+
if (!packetQuarEncResponse) // TODO: handle cleanup
return FALSE;
- packet->tsgPacket.packetQuarEncResponse = packetQuarEncResponse;
+ packet->tsgPacket.packetQuarEncResponse = packetQuarEncResponse;
/* PacketQuarResponsePtr (4 bytes) */
packetQuarEncResponse->flags = *((UINT32*) &buffer[offset + 12]); /* Flags */
packetQuarEncResponse->certChainLen = *((UINT32*) &buffer[offset + 16]); /* CertChainLength */
{
Pointer = *((UINT32*) &buffer[offset]); /* Ptr (4 bytes): 0x0002000C */
offset += 4;
-
offset += 4; /* MaxCount (4 bytes) */
offset += 4; /* Offset (4 bytes) */
count = *((UINT32*) &buffer[offset]); /* ActualCount (4 bytes) */
offset += 4;
-
/*
* CertChainData is a wide character string, and the count is
* given in characters excluding the null terminator, therefore:
* size = (count * 2)
*/
offset += (count * 2); /* CertChainData */
-
/* 4-byte alignment */
rpc_offset_align(&offset, 4);
}
}
versionCaps = (PTSG_PACKET_VERSIONCAPS) calloc(1, sizeof(TSG_PACKET_VERSIONCAPS));
+
if (!versionCaps) // TODO: handle cleanup
return FALSE;
- packetQuarEncResponse->versionCaps = versionCaps;
+ packetQuarEncResponse->versionCaps = versionCaps;
versionCaps->tsgHeader.ComponentId = *((UINT16*) &buffer[offset]); /* ComponentId */
versionCaps->tsgHeader.PacketId = *((UINT16*) &buffer[offset + 2]); /* PacketId */
offset += 4;
if (versionCaps->tsgHeader.ComponentId != TS_GATEWAY_TRANSPORT)
{
- fprintf(stderr, "Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n",
- versionCaps->tsgHeader.ComponentId);
+ DEBUG_WARN("Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n",
+ versionCaps->tsgHeader.ComponentId);
free(versionCaps);
free(packetQuarEncResponse);
free(packet);
versionCaps->majorVersion = *((UINT16*) &buffer[offset + 10]); /* MinorVersion */
versionCaps->quarantineCapabilities = *((UINT16*) &buffer[offset + 12]); /* QuarantineCapabilities */
offset += 14;
-
/* 4-byte alignment */
rpc_offset_align(&offset, 4);
-
/* Not sure exactly what this is */
offset += 4; /* 0x00000001 (4 bytes) */
offset += 4; /* 0x00000001 (4 bytes) */
offset += 4; /* 0x00000001 (4 bytes) */
offset += 4; /* 0x00000002 (4 bytes) */
-
/* TunnelContext (20 bytes) */
CopyMemory(&tsg->TunnelContext.ContextType, &buffer[offset], 4); /* ContextType */
CopyMemory(tsg->TunnelContext.ContextUuid, &buffer[offset + 4], 16); /* ContextUuid */
offset += 20;
-
#ifdef WITH_DEBUG_TSG
- fprintf(stderr, "TSG TunnelContext:\n");
- winpr_HexDump((void*) &tsg->TunnelContext, 20);
- fprintf(stderr, "\n");
+ DEBUG_WARN("TSG TunnelContext:\n");
+ winpr_HexDump(TAG, WLOG_DEBUG, (void*) &tsg->TunnelContext, 20);
+ DEBUG_WARN("\n");
#endif
-
free(versionCaps);
free(packetQuarEncResponse);
}
else
{
- fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_CAPS_RESPONSE "
- "or TSG_PACKET_TYPE_QUARENC_RESPONSE\n", packet->packetId);
+ DEBUG_WARN("Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_CAPS_RESPONSE "
+ "or TSG_PACKET_TYPE_QUARENC_RESPONSE\n", packet->packetId);
free(packet);
return FALSE;
}
rpc_client_receive_pool_return(rpc, pdu);
free(packet);
-
return TRUE;
}
BOOL TsProxyCreateTunnel(rdpTsg* tsg, PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse,
- PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, UINT32* tunnelId)
+ PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, UINT32* tunnelId)
{
/**
* OpNum = 1
* [out] unsigned long* tunnelId
* );
*/
-
DEBUG_TSG("TsProxyCreateTunnel");
if (!TsProxyCreateTunnelWriteRequest(tsg))
{
- fprintf(stderr, "TsProxyCreateTunnel: error writing request\n");
+ DEBUG_WARN("TsProxyCreateTunnel: error writing request\n");
return FALSE;
}
UINT32 offset;
CONTEXT_HANDLE* handle;
rdpRpc* rpc = tsg->rpc;
-
count = _wcslen(tsg->MachineName) + 1;
-
offset = 64 + (count * 2);
rpc_offset_align(&offset, 4);
offset += 4;
-
length = offset;
buffer = (BYTE*) malloc(length);
-
/* TunnelContext */
handle = (CONTEXT_HANDLE*) tunnelContext;
CopyMemory(&buffer[0], &handle->ContextType, 4); /* ContextType */
CopyMemory(&buffer[4], handle->ContextUuid, 16); /* ContextUuid */
-
/* 4-byte alignment */
-
*((UINT32*) &buffer[20]) = TSG_PACKET_TYPE_QUARREQUEST; /* PacketId */
*((UINT32*) &buffer[24]) = TSG_PACKET_TYPE_QUARREQUEST; /* SwitchValue */
-
*((UINT32*) &buffer[28]) = 0x00020000; /* PacketQuarRequestPtr */
-
*((UINT32*) &buffer[32]) = 0x00000000; /* Flags */
-
*((UINT32*) &buffer[36]) = 0x00020004; /* MachineNamePtr */
-
*((UINT32*) &buffer[40]) = count; /* NameLength */
-
*((UINT32*) &buffer[44]) = 0x00020008; /* DataPtr */
*((UINT32*) &buffer[48]) = 0; /* DataLength */
-
/* MachineName */
*((UINT32*) &buffer[52]) = count; /* MaxCount */
*((UINT32*) &buffer[56]) = 0; /* Offset */
*((UINT32*) &buffer[60]) = count; /* ActualCount */
CopyMemory(&buffer[64], tsg->MachineName, count * 2); /* Array */
offset = 64 + (count * 2);
-
/* 4-byte alignment */
pad = rpc_offset_align(&offset, 4);
ZeroMemory(&buffer[offset - pad], pad);
-
*((UINT32*) &buffer[offset]) = 0x00000000; /* MaxCount */
offset += 4;
-
status = rpc_write(rpc, buffer, length, TsProxyAuthorizeTunnelOpnum);
if (status <= 0)
return FALSE;
free(buffer);
-
return TRUE;
}
packet = (PTSG_PACKET) malloc(sizeof(TSG_PACKET));
ZeroMemory(packet, sizeof(TSG_PACKET));
-
offset = 4;
packet->packetId = *((UINT32*) &buffer[offset]); /* PacketId */
SwitchValue = *((UINT32*) &buffer[offset + 4]); /* SwitchValue */
if (packet->packetId == E_PROXY_NAP_ACCESSDENIED)
{
- fprintf(stderr, "status: E_PROXY_NAP_ACCESSDENIED (0x%08X)\n", E_PROXY_NAP_ACCESSDENIED);
- fprintf(stderr, "Ensure that the Gateway Connection Authorization Policy is correct\n");
+ DEBUG_WARN("status: E_PROXY_NAP_ACCESSDENIED (0x%08X)\n", E_PROXY_NAP_ACCESSDENIED);
+ DEBUG_WARN("Ensure that the Gateway Connection Authorization Policy is correct\n");
free(packet);
return FALSE;
}
if ((packet->packetId != TSG_PACKET_TYPE_RESPONSE) || (SwitchValue != TSG_PACKET_TYPE_RESPONSE))
{
- fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_RESPONSE\n",
- packet->packetId);
+ DEBUG_WARN("Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_RESPONSE\n",
+ packet->packetId);
free(packet);
return FALSE;
}
packetResponse = (PTSG_PACKET_RESPONSE) malloc(sizeof(TSG_PACKET_RESPONSE));
ZeroMemory(packetResponse, sizeof(TSG_PACKET_RESPONSE));
packet->tsgPacket.packetResponse = packetResponse;
-
Pointer = *((UINT32*) &buffer[offset + 8]); /* PacketResponsePtr */
packetResponse->flags = *((UINT32*) &buffer[offset + 12]); /* Flags */
if (packetResponse->flags != TSG_PACKET_TYPE_QUARREQUEST)
{
- fprintf(stderr, "Unexpected Packet Response Flags: 0x%08X, Expected TSG_PACKET_TYPE_QUARREQUEST\n",
- packetResponse->flags);
+ DEBUG_WARN("Unexpected Packet Response Flags: 0x%08X, Expected TSG_PACKET_TYPE_QUARREQUEST\n",
+ packetResponse->flags);
free(packet);
free(packetResponse);
return FALSE;
/* Reserved (4 bytes) */
Pointer = *((UINT32*) &buffer[offset + 20]); /* ResponseDataPtr */
packetResponse->responseDataLen = *((UINT32*) &buffer[offset + 24]); /* ResponseDataLength */
-
packetResponse->redirectionFlags.enableAllRedirections = *((UINT32*) &buffer[offset + 28]); /* EnableAllRedirections */
packetResponse->redirectionFlags.disableAllRedirections = *((UINT32*) &buffer[offset + 32]); /* DisableAllRedirections */
packetResponse->redirectionFlags.driveRedirectionDisabled = *((UINT32*) &buffer[offset + 36]); /* DriveRedirectionDisabled */
packetResponse->redirectionFlags.clipboardRedirectionDisabled = *((UINT32*) &buffer[offset + 52]); /* ClipboardRedirectionDisabled */
packetResponse->redirectionFlags.pnpRedirectionDisabled = *((UINT32*) &buffer[offset + 56]); /* PnpRedirectionDisabled */
offset += 60;
-
SizeValue = *((UINT32*) &buffer[offset]);
offset += 4;
if (SizeValue != packetResponse->responseDataLen)
{
- fprintf(stderr, "Unexpected size value: %d, expected: %d\n",
- SizeValue, packetResponse->responseDataLen);
+ DEBUG_WARN("Unexpected size value: %d, expected: %d\n",
+ SizeValue, packetResponse->responseDataLen);
free(packetResponse);
free(packet);
return FALSE;
}
offset += SizeValue; /* ResponseData */
-
rpc_client_receive_pool_return(rpc, pdu);
free(packetResponse);
free(packet);
-
return TRUE;
}
BOOL TsProxyAuthorizeTunnel(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext,
- PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse)
+ PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse)
{
/**
* OpNum = 2
* );
*
*/
-
DEBUG_TSG("TsProxyAuthorizeTunnel");
if (!TsProxyAuthorizeTunnelWriteRequest(tsg, tunnelContext))
{
- fprintf(stderr, "TsProxyAuthorizeTunnel: error writing request\n");
+ DEBUG_WARN("TsProxyAuthorizeTunnel: error writing request\n");
return FALSE;
}
UINT32 length;
CONTEXT_HANDLE* handle;
rdpRpc* rpc = tsg->rpc;
-
length = 40;
buffer = (BYTE*) malloc(length);
-
/* TunnelContext */
handle = (CONTEXT_HANDLE*) tunnelContext;
CopyMemory(&buffer[0], &handle->ContextType, 4); /* ContextType */
CopyMemory(&buffer[4], handle->ContextUuid, 16); /* ContextUuid */
-
*((UINT32*) &buffer[20]) = procId; /* ProcId */
-
/* 4-byte alignment */
-
*((UINT32*) &buffer[24]) = TSG_PACKET_TYPE_MSGREQUEST_PACKET; /* PacketId */
*((UINT32*) &buffer[28]) = TSG_PACKET_TYPE_MSGREQUEST_PACKET; /* SwitchValue */
-
*((UINT32*) &buffer[32]) = 0x00020000; /* PacketMsgRequestPtr */
-
*((UINT32*) &buffer[36]) = 0x00000001; /* MaxMessagesPerBatch */
-
status = rpc_write(rpc, buffer, length, TsProxyMakeTunnelCallOpnum);
if (status <= 0)
return FALSE;
free(buffer);
-
return TRUE;
}
buffer = &buffer[24];
packet = (PTSG_PACKET) calloc(1, sizeof(TSG_PACKET));
+
if (!packet)
return FALSE;
if ((packet->packetId != TSG_PACKET_TYPE_MESSAGE_PACKET) || (SwitchValue != TSG_PACKET_TYPE_MESSAGE_PACKET))
{
- fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_MESSAGE_PACKET\n",
- packet->packetId);
+ DEBUG_WARN("Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_MESSAGE_PACKET\n",
+ packet->packetId);
free(packet);
return FALSE;
}
packetMsgResponse = (PTSG_PACKET_MSG_RESPONSE) malloc(sizeof(TSG_PACKET_MSG_RESPONSE));
ZeroMemory(packetMsgResponse, sizeof(TSG_PACKET_MSG_RESPONSE));
packet->tsgPacket.packetMsgResponse = packetMsgResponse;
-
Pointer = *((UINT32*) &buffer[offset + 8]); /* PacketMsgResponsePtr */
packetMsgResponse->msgID = *((UINT32*) &buffer[offset + 12]); /* MsgId */
packetMsgResponse->msgType = *((UINT32*) &buffer[offset + 16]); /* MsgType */
packetMsgResponse->isMsgPresent = *((INT32*) &buffer[offset + 20]); /* IsMsgPresent */
-
SwitchValue = *((UINT32*) &buffer[offset + 24]); /* SwitchValue */
switch (SwitchValue)
{
- case TSG_ASYNC_MESSAGE_CONSENT_MESSAGE:
- packetStringMessage = (PTSG_PACKET_STRING_MESSAGE) malloc(sizeof(TSG_PACKET_STRING_MESSAGE));
- ZeroMemory(packetStringMessage, sizeof(TSG_PACKET_STRING_MESSAGE));
- packetMsgResponse->messagePacket.consentMessage = packetStringMessage;
-
- Pointer = *((UINT32*) &buffer[offset + 28]); /* ConsentMessagePtr */
- packetStringMessage->isDisplayMandatory = *((INT32*) &buffer[offset + 32]); /* IsDisplayMandatory */
- packetStringMessage->isConsentMandatory = *((INT32*) &buffer[offset + 36]); /* IsConsentMandatory */
- packetStringMessage->msgBytes = *((UINT32*) &buffer[offset + 40]); /* MsgBytes */
-
- Pointer = *((UINT32*) &buffer[offset + 44]); /* MsgPtr */
- MaxCount = *((UINT32*) &buffer[offset + 48]); /* MaxCount */
- /* Offset */
- ActualCount = *((UINT32*) &buffer[offset + 56]); /* ActualCount */
-
- ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) &buffer[offset + 60], ActualCount, &messageText, 0, NULL, NULL);
- fprintf(stderr, "Consent Message: %s\n", messageText);
- free(messageText);
-
- break;
-
- case TSG_ASYNC_MESSAGE_SERVICE_MESSAGE:
- packetStringMessage = (PTSG_PACKET_STRING_MESSAGE) malloc(sizeof(TSG_PACKET_STRING_MESSAGE));
- ZeroMemory(packetStringMessage, sizeof(TSG_PACKET_STRING_MESSAGE));
- packetMsgResponse->messagePacket.serviceMessage = packetStringMessage;
-
- Pointer = *((UINT32*) &buffer[offset + 28]); /* ServiceMessagePtr */
- packetStringMessage->isDisplayMandatory = *((INT32*) &buffer[offset + 32]); /* IsDisplayMandatory */
- packetStringMessage->isConsentMandatory = *((INT32*) &buffer[offset + 36]); /* IsConsentMandatory */
- packetStringMessage->msgBytes = *((UINT32*) &buffer[offset + 40]); /* MsgBytes */
-
- Pointer = *((UINT32*) &buffer[offset + 44]); /* MsgPtr */
- MaxCount = *((UINT32*) &buffer[offset + 48]); /* MaxCount */
- /* Offset */
- ActualCount = *((UINT32*) &buffer[offset + 56]); /* ActualCount */
-
- ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) &buffer[offset + 60], ActualCount, &messageText, 0, NULL, NULL);
- fprintf(stderr, "Service Message: %s\n", messageText);
- free(messageText);
-
- break;
-
- case TSG_ASYNC_MESSAGE_REAUTH:
- packetReauthMessage = (PTSG_PACKET_REAUTH_MESSAGE) malloc(sizeof(TSG_PACKET_REAUTH_MESSAGE));
- ZeroMemory(packetReauthMessage, sizeof(TSG_PACKET_REAUTH_MESSAGE));
- packetMsgResponse->messagePacket.reauthMessage = packetReauthMessage;
-
- Pointer = *((UINT32*) &buffer[offset + 28]); /* ReauthMessagePtr */
- break;
-
- default:
- fprintf(stderr, "TsProxyMakeTunnelCallReadResponse: unexpected message type: %d\n",
- SwitchValue);
- rc = FALSE;
- break;
+ case TSG_ASYNC_MESSAGE_CONSENT_MESSAGE:
+ packetStringMessage = (PTSG_PACKET_STRING_MESSAGE) malloc(sizeof(TSG_PACKET_STRING_MESSAGE));
+ ZeroMemory(packetStringMessage, sizeof(TSG_PACKET_STRING_MESSAGE));
+ packetMsgResponse->messagePacket.consentMessage = packetStringMessage;
+ Pointer = *((UINT32*) &buffer[offset + 28]); /* ConsentMessagePtr */
+ packetStringMessage->isDisplayMandatory = *((INT32*) &buffer[offset + 32]); /* IsDisplayMandatory */
+ packetStringMessage->isConsentMandatory = *((INT32*) &buffer[offset + 36]); /* IsConsentMandatory */
+ packetStringMessage->msgBytes = *((UINT32*) &buffer[offset + 40]); /* MsgBytes */
+ Pointer = *((UINT32*) &buffer[offset + 44]); /* MsgPtr */
+ MaxCount = *((UINT32*) &buffer[offset + 48]); /* MaxCount */
+ /* Offset */
+ ActualCount = *((UINT32*) &buffer[offset + 56]); /* ActualCount */
+ ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) &buffer[offset + 60], ActualCount, &messageText, 0, NULL, NULL);
+ DEBUG_WARN("Consent Message: %s\n", messageText);
+ free(messageText);
+ break;
+ case TSG_ASYNC_MESSAGE_SERVICE_MESSAGE:
+ packetStringMessage = (PTSG_PACKET_STRING_MESSAGE) malloc(sizeof(TSG_PACKET_STRING_MESSAGE));
+ ZeroMemory(packetStringMessage, sizeof(TSG_PACKET_STRING_MESSAGE));
+ packetMsgResponse->messagePacket.serviceMessage = packetStringMessage;
+ Pointer = *((UINT32*) &buffer[offset + 28]); /* ServiceMessagePtr */
+ packetStringMessage->isDisplayMandatory = *((INT32*) &buffer[offset + 32]); /* IsDisplayMandatory */
+ packetStringMessage->isConsentMandatory = *((INT32*) &buffer[offset + 36]); /* IsConsentMandatory */
+ packetStringMessage->msgBytes = *((UINT32*) &buffer[offset + 40]); /* MsgBytes */
+ Pointer = *((UINT32*) &buffer[offset + 44]); /* MsgPtr */
+ MaxCount = *((UINT32*) &buffer[offset + 48]); /* MaxCount */
+ /* Offset */
+ ActualCount = *((UINT32*) &buffer[offset + 56]); /* ActualCount */
+ ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) &buffer[offset + 60], ActualCount, &messageText, 0, NULL, NULL);
+ DEBUG_WARN("Service Message: %s\n", messageText);
+ free(messageText);
+ break;
+ case TSG_ASYNC_MESSAGE_REAUTH:
+ packetReauthMessage = (PTSG_PACKET_REAUTH_MESSAGE) malloc(sizeof(TSG_PACKET_REAUTH_MESSAGE));
+ ZeroMemory(packetReauthMessage, sizeof(TSG_PACKET_REAUTH_MESSAGE));
+ packetMsgResponse->messagePacket.reauthMessage = packetReauthMessage;
+ Pointer = *((UINT32*) &buffer[offset + 28]); /* ReauthMessagePtr */
+ break;
+ default:
+ DEBUG_WARN("TsProxyMakeTunnelCallReadResponse: unexpected message type: %d\n",
+ SwitchValue);
+ rc = FALSE;
+ break;
}
if (packet)
{
if (packet->tsgPacket.packetMsgResponse->messagePacket.reauthMessage)
free(packet->tsgPacket.packetMsgResponse->messagePacket.reauthMessage);
+
free(packet->tsgPacket.packetMsgResponse);
}
+
free(packet);
}
}
BOOL TsProxyMakeTunnelCall(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext,
- UINT32 procId, PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse)
+ UINT32 procId, PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse)
{
/**
* OpNum = 3
* [out, ref] PTSG_PACKET* tsgPacketResponse
* );
*/
-
DEBUG_TSG("TsProxyMakeTunnelCall");
if (!TsProxyMakeTunnelCallWriteRequest(tsg, tunnelContext, procId))
{
- fprintf(stderr, "TsProxyMakeTunnelCall: error writing request\n");
+ DEBUG_WARN("TsProxyMakeTunnelCall: error writing request\n");
return FALSE;
}
UINT32 length;
CONTEXT_HANDLE* handle;
rdpRpc* rpc = tsg->rpc;
-
count = _wcslen(tsg->Hostname) + 1;
-
#ifdef WITH_DEBUG_TSG
- fprintf(stderr, "ResourceName:\n");
- winpr_HexDump((BYTE*) tsg->Hostname, (count - 1) * 2);
- fprintf(stderr, "\n");
+ DEBUG_WARN("ResourceName:\n");
+ winpr_HexDump(TAG, WLOG_DEBUG, (BYTE*) tsg->Hostname, (count - 1) * 2);
+ DEBUG_WARN("\n");
#endif
-
length = 60 + (count * 2);
-
buffer = (BYTE*) malloc(length);
+
if (!buffer)
return FALSE;
handle = (CONTEXT_HANDLE*) tunnelContext;
CopyMemory(&buffer[0], &handle->ContextType, 4); /* ContextType */
CopyMemory(&buffer[4], handle->ContextUuid, 16); /* ContextUuid */
-
/* TSENDPOINTINFO */
-
*((UINT32*) &buffer[20]) = 0x00020000; /* ResourceNamePtr */
*((UINT32*) &buffer[24]) = 0x00000001; /* NumResourceNames */
*((UINT32*) &buffer[28]) = 0x00000000; /* AlternateResourceNamesPtr */
*((UINT16*) &buffer[32]) = 0x0000; /* NumAlternateResourceNames */
*((UINT16*) &buffer[34]) = 0x0000; /* Pad (2 bytes) */
-
/* Port (4 bytes) */
*((UINT16*) &buffer[36]) = 0x0003; /* ProtocolId (RDP = 3) */
*((UINT16*) &buffer[38]) = tsg->Port; /* PortNumber (0xD3D = 3389) */
-
*((UINT32*) &buffer[40]) = 0x00000001; /* NumResourceNames */
*((UINT32*) &buffer[44]) = 0x00020004; /* ResourceNamePtr */
*((UINT32*) &buffer[48]) = count; /* MaxCount */
*((UINT32*) &buffer[52]) = 0; /* Offset */
*((UINT32*) &buffer[56]) = count; /* ActualCount */
CopyMemory(&buffer[60], tsg->Hostname, count * 2); /* Array */
-
status = rpc_write(rpc, buffer, length, TsProxyCreateChannelOpnum);
if (status <= 0)
return FALSE;
free(buffer);
-
return TRUE;
}
buffer = &buffer[24];
offset = 0;
-
/* ChannelContext (20 bytes) */
CopyMemory(&tsg->ChannelContext.ContextType, &buffer[offset], 4); /* ContextType (4 bytes) */
CopyMemory(tsg->ChannelContext.ContextUuid, &buffer[offset + 4], 16); /* ContextUuid (16 bytes) */
-
#ifdef WITH_DEBUG_TSG
- fprintf(stderr, "ChannelContext:\n");
- winpr_HexDump((void*) &tsg->ChannelContext, 20);
- fprintf(stderr, "\n");
+ DEBUG_WARN("ChannelContext:\n");
+ winpr_HexDump(TAG, WLOG_DEBUG, (void*) &tsg->ChannelContext, 20);
+ DEBUG_WARN("\n");
#endif
-
rpc_client_receive_pool_return(rpc, pdu);
-
return TRUE;
}
BOOL TsProxyCreateChannel(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, PTSENDPOINTINFO tsEndPointInfo,
- PCHANNEL_CONTEXT_HANDLE_SERIALIZE* channelContext, UINT32* channelId)
+ PCHANNEL_CONTEXT_HANDLE_SERIALIZE* channelContext, UINT32* channelId)
{
/**
* OpNum = 4
* [out] unsigned long* channelId
* );
*/
-
DEBUG_TSG("TsProxyCreateChannel");
if (!TsProxyCreateChannelWriteRequest(tsg, tunnelContext))
{
- fprintf(stderr, "TsProxyCreateChannel: error writing request\n");
+ DEBUG_WARN("TsProxyCreateChannel: error writing request\n");
return FALSE;
}
BYTE* buffer;
UINT32 length;
rdpRpc* rpc = tsg->rpc;
-
length = 20;
buffer = (BYTE*) malloc(length);
-
/* TunnelContext */
CopyMemory(&buffer[0], &tsg->ChannelContext.ContextType, 4); /* ContextType */
CopyMemory(&buffer[4], tsg->ChannelContext.ContextUuid, 16); /* ContextUuid */
-
status = rpc_write(rpc, buffer, length, TsProxyCloseChannelOpnum);
if (status <= 0)
return FALSE;
free(buffer);
-
return TRUE;
}
UINT32 length;
UINT32 offset;
rdpRpc* rpc = tsg->rpc;
-
pdu = rpc_recv_dequeue_pdu(rpc);
if (!pdu)
buffer = &buffer[24];
offset = 0;
-
rpc_client_receive_pool_return(rpc, pdu);
-
return TRUE;
}
HRESULT TsProxyCloseChannel(rdpTsg* tsg, PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* context)
{
RPC_PDU* pdu = NULL;
-
/**
* HRESULT TsProxyCloseChannel(
* [in, out] PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* context
* );
*/
-
DEBUG_TSG("TsProxyCloseChannel");
if (!TsProxyCloseChannelWriteRequest(tsg, context))
{
- fprintf(stderr, "TsProxyCloseChannel: error writing request\n");
+ DEBUG_WARN("TsProxyCloseChannel: error writing request\n");
return FALSE;
}
if (!TsProxyCloseChannelReadResponse(tsg, pdu))
{
- fprintf(stderr, "TsProxyCloseChannel: error reading response\n");
+ DEBUG_WARN("TsProxyCloseChannel: error reading response\n");
return FALSE;
}
BYTE* buffer;
UINT32 length;
rdpRpc* rpc = tsg->rpc;
-
length = 20;
buffer = (BYTE*) malloc(length);
-
/* TunnelContext */
CopyMemory(&buffer[0], &tsg->TunnelContext.ContextType, 4); /* ContextType */
CopyMemory(&buffer[4], tsg->TunnelContext.ContextUuid, 16); /* ContextUuid */
-
status = rpc_write(rpc, buffer, length, TsProxyCloseTunnelOpnum);
if (status <= 0)
return FALSE;
free(buffer);
-
return TRUE;
}
UINT32 length;
UINT32 offset;
rdpRpc* rpc = tsg->rpc;
-
pdu = rpc_recv_dequeue_pdu(rpc);
if (!pdu)
buffer = &buffer[24];
offset = 0;
-
rpc_client_receive_pool_return(rpc, pdu);
-
return TRUE;
}
HRESULT TsProxyCloseTunnel(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_SERIALIZE* context)
{
RPC_PDU* pdu = NULL;
-
/**
* HRESULT TsProxyCloseTunnel(
* [in, out] PTUNNEL_CONTEXT_HANDLE_SERIALIZE* context
* );
*/
-
DEBUG_TSG("TsProxyCloseTunnel");
if (!TsProxyCloseTunnelWriteRequest(tsg, context))
{
- fprintf(stderr, "TsProxyCloseTunnel: error writing request\n");
+ DEBUG_WARN("TsProxyCloseTunnel: error writing request\n");
return FALSE;
}
if (!TsProxyCloseTunnelReadResponse(tsg, pdu))
{
- fprintf(stderr, "TsProxyCloseTunnel: error reading response\n");
+ DEBUG_WARN("TsProxyCloseTunnel: error reading response\n");
return FALSE;
}
BYTE* buffer;
UINT32 length;
rdpRpc* rpc = tsg->rpc;
-
length = 20;
-
buffer = (BYTE*) malloc(length);
-
/* ChannelContext */
CopyMemory(&buffer[0], &tsg->ChannelContext.ContextType, 4); /* ContextType */
CopyMemory(&buffer[4], tsg->ChannelContext.ContextUuid, 16); /* ContextUuid */
-
status = rpc_write(rpc, buffer, length, TsProxySetupReceivePipeOpnum);
if (status <= 0)
return FALSE;
free(buffer);
-
return TRUE;
}
BOOL TsProxySetupReceivePipe(handle_t IDL_handle, BYTE* pRpcMessage)
{
rdpTsg* tsg;
-
/**
* OpNum = 8
*
* [in, max_is(32767)] byte pRpcMessage[]
* );
*/
-
tsg = (rdpTsg*) IDL_handle;
-
DEBUG_TSG("TsProxySetupReceivePipe");
if (!TsProxySetupReceivePipeWriteRequest(tsg))
{
- fprintf(stderr, "TsProxySetupReceivePipe: error writing request\n");
+ DEBUG_WARN("TsProxySetupReceivePipe: error writing request\n");
return FALSE;
}
RpcClientCall* call;
rdpRpc* rpc = tsg->rpc;
rdpSettings* settings = rpc->settings;
-
tsg->Port = port;
ConvertToUnicode(CP_UTF8, 0, hostname, -1, &tsg->Hostname, 0);
ConvertToUnicode(CP_UTF8, 0, settings->ComputerName, -1, &tsg->MachineName, 0);
if (!rpc_connect(rpc))
{
- fprintf(stderr, "rpc_connect failed!\n");
+ DEBUG_WARN("rpc_connect failed!\n");
return FALSE;
}
DEBUG_TSG("rpc_connect success");
-
tsg->state = TSG_STATE_INITIAL;
-
rpc->client->SynchronousSend = TRUE;
rpc->client->SynchronousReceive = TRUE;
if (!TsProxyCreateTunnelReadResponse(tsg, pdu))
{
- fprintf(stderr, "TsProxyCreateTunnel: error reading response\n");
+ DEBUG_WARN("TsProxyCreateTunnel: error reading response\n");
return FALSE;
}
if (!TsProxyAuthorizeTunnelReadResponse(tsg, pdu))
{
- fprintf(stderr, "TsProxyAuthorizeTunnel: error reading response\n");
+ DEBUG_WARN("TsProxyAuthorizeTunnel: error reading response\n");
return FALSE;
}
return FALSE;
pdu = rpc_recv_dequeue_pdu(rpc);
- if (!pdu) {
- fprintf(stderr, "TsProxyCreateChannel: error reading response\n");
+
+ if (!pdu)
+ {
+ DEBUG_WARN("TsProxyCreateChannel: error reading response\n");
return FALSE;
}
{
if (!TsProxyMakeTunnelCallReadResponse(tsg, pdu))
{
- fprintf(stderr, "TsProxyMakeTunnelCall: error reading response\n");
+ DEBUG_WARN("TsProxyMakeTunnelCall: error reading response\n");
return FALSE;
}
if (!TsProxyCreateChannelReadResponse(tsg, pdu))
{
- fprintf(stderr, "TsProxyCreateChannel: error reading response\n");
+ DEBUG_WARN("TsProxyCreateChannel: error reading response\n");
return FALSE;
}
if (!TsProxySetupReceivePipeReadResponse(tsg, pdu))
{
- fprintf(stderr, "TsProxySetupReceivePipe: error reading response\n");
+ DEBUG_WARN("TsProxySetupReceivePipe: error reading response\n");
return FALSE;
}
-#endif
+#endif
rpc->client->SynchronousSend = TRUE;
rpc->client->SynchronousReceive = TRUE;
-
- fprintf(stderr, "TS Gateway Connection Success\n");
-
+ DEBUG_WARN("TS Gateway Connection Success\n");
return TRUE;
}
* |<-------------TsProxyCloseTunnel Response----------|
* | |
*/
-
-
if (tsg == NULL)
return FALSE;
tsg->rpc->client->SynchronousReceive = TRUE;
/* if we are already in state pending (i.e. if a server initiated disconnect was issued)
- we have to skip TsProxyCloseChannel - see Figure 13 in section 3.2.3
+ we have to skip TsProxyCloseChannel - see Figure 13 in section 3.2.3
*/
if (tsg->state != TSG_STATE_TUNNEL_CLOSE_PENDING)
{
if (rpc->transport->layer == TRANSPORT_LAYER_CLOSED)
{
- fprintf(stderr, "tsg_read error: connection lost\n");
+ DEBUG_WARN("tsg_read error: connection lost\n");
return -1;
}
if (tsg->PendingPdu)
{
CopyLength = (length < tsg->BytesAvailable) ? length : tsg->BytesAvailable;
-
CopyMemory(data, &tsg->pdu->s->buffer[tsg->BytesRead], CopyLength);
tsg->BytesAvailable -= CopyLength;
tsg->BytesRead += CopyLength;
return CopyLength;
}
-
tsg->pdu = rpc_recv_peek_pdu(rpc);
+
if (!tsg->pdu)
{
if (!tsg->rpc->client->SynchronousReceive)
tsg->PendingPdu = TRUE;
tsg->BytesAvailable = Stream_Length(tsg->pdu->s);
tsg->BytesRead = 0;
-
CopyLength = (length < tsg->BytesAvailable) ? length : tsg->BytesAvailable;
-
CopyMemory(data, &tsg->pdu->s->buffer[tsg->BytesRead], CopyLength);
tsg->BytesAvailable -= CopyLength;
tsg->BytesRead += CopyLength;
}
return CopyLength;
-
}
int tsg_write(rdpTsg* tsg, BYTE* data, UINT32 length)
if (tsg->rpc->transport->layer == TRANSPORT_LAYER_CLOSED)
{
- fprintf(stderr, "%s: error, connection lost\n", __FUNCTION__);
+ DEBUG_WARN("%s: error, connection lost\n", __FUNCTION__);
return -1;
}
status = TsProxySendToServer((handle_t) tsg, data, 1, &length);
+
if (status < 0)
return -1;
+
return length;
}
{
tsg->rpc->client->SynchronousSend = TRUE;
tsg->rpc->client->SynchronousReceive = blocking;
-
tsg->transport->GatewayEvent = Queue_Event(tsg->rpc->client->ReceiveQueue);
-
return TRUE;
}
rdpTsg* tsg_new(rdpTransport* transport)
{
rdpTsg* tsg;
-
tsg = (rdpTsg*) calloc(1, sizeof(rdpTsg));
if (!tsg)
tsg->PendingPdu = FALSE;
return tsg;
-
out_free:
free(tsg);
return NULL;
if (!gcc_read_server_data_blocks(s, mcs, length))
{
- fprintf(stderr, "gcc_read_conference_create_response: gcc_read_server_data_blocks failed\n");
+ DEBUG_WARN( "gcc_read_conference_create_response: gcc_read_server_data_blocks failed\n");
return FALSE;
}
break;
default:
- fprintf(stderr, "Unknown GCC client data block: 0x%04X\n", type);
+ DEBUG_WARN( "Unknown GCC client data block: 0x%04X\n", type);
Stream_Seek(s, blockLength - 4);
break;
}
if (endPos != (begPos + blockLength))
{
- fprintf(stderr, "Error parsing GCC client data block 0x%04X: Actual Offset: %d Expected Offset: %d\n",
+ DEBUG_WARN( "Error parsing GCC client data block 0x%04X: Actual Offset: %d Expected Offset: %d\n",
type, endPos, begPos + blockLength);
}
{
if (settings->UseMultimon && !settings->SpanMonitors)
{
- fprintf(stderr, "WARNING: true multi monitor support was not advertised by server!\n");
+ DEBUG_WARN( "WARNING: true multi monitor support was not advertised by server!\n");
if (settings->ForceMultimon)
{
- fprintf(stderr, "Sending multi monitor information anyway (may break connectivity!)\n");
+ DEBUG_WARN( "Sending multi monitor information anyway (may break connectivity!)\n");
gcc_write_client_monitor_data(s, mcs);
}
else
{
- fprintf(stderr, "Use /multimon:force to force sending multi monitor information\n");
+ DEBUG_WARN( "Use /multimon:force to force sending multi monitor information\n");
}
}
}
if (!gcc_read_user_data_header(s, &type, &blockLength))
{
- fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_user_data_header failed\n");
+ DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_user_data_header failed\n");
return FALSE;
}
case SC_CORE:
if (!gcc_read_server_core_data(s, mcs))
{
- fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_server_core_data failed\n");
+ DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_server_core_data failed\n");
return FALSE;
}
break;
case SC_SECURITY:
if (!gcc_read_server_security_data(s, mcs))
{
- fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_server_security_data failed\n");
+ DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_server_security_data failed\n");
return FALSE;
}
break;
case SC_NET:
if (!gcc_read_server_network_data(s, mcs))
{
- fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_server_network_data failed\n");
+ DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_server_network_data failed\n");
return FALSE;
}
break;
case SC_MCS_MSGCHANNEL:
if (!gcc_read_server_message_channel_data(s, mcs))
{
- fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_server_message_channel_data failed\n");
+ DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_server_message_channel_data failed\n");
return FALSE;
}
break;
case SC_MULTITRANSPORT:
if (!gcc_read_server_multitransport_channel_data(s, mcs))
{
- fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_server_multitransport_channel_data failed\n");
+ DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_server_multitransport_channel_data failed\n");
return FALSE;
}
break;
default:
- fprintf(stderr, "gcc_read_server_data_blocks: ignoring type=%hu\n", type);
+ DEBUG_WARN( "gcc_read_server_data_blocks: ignoring type=%hu\n", type);
break;
}
offset += blockLength;
md5 = crypto_md5_init();
if (!md5)
{
- fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__);
return;
}
if (channelCount != mcs->channelCount)
{
- fprintf(stderr, "requested %d channels, got %d instead\n",
+ DEBUG_WARN( "requested %d channels, got %d instead\n",
mcs->channelCount, channelCount);
/* we ensure that the response is not bigger than the request */
if (bitmap)
{
- CopyMemory(bitmap, context->graphics->Bitmap_Prototype, sizeof(rdpBitmap));
+ ZeroMemory(bitmap, graphics->Bitmap_Prototype->size);
+ CopyMemory(bitmap, graphics->Bitmap_Prototype, sizeof(rdpBitmap));
bitmap->data = NULL;
}
if (pointer)
{
- CopyMemory(pointer, context->graphics->Pointer_Prototype, sizeof(rdpPointer));
+ ZeroMemory(pointer, graphics->Pointer_Prototype->size);
+ CopyMemory(pointer, graphics->Pointer_Prototype, sizeof(rdpPointer));
}
return pointer;
if (glyph)
{
- CopyMemory(glyph, context->graphics->Glyph_Prototype, sizeof(rdpGlyph));
+ ZeroMemory(glyph, graphics->Glyph_Prototype->size);
+ CopyMemory(glyph, graphics->Glyph_Prototype, sizeof(rdpGlyph));
}
return glyph;
char *base64;
base64 = crypto_base64_encode((BYTE *) autoReconnectCookie,
sizeof(ARC_SC_PRIVATE_PACKET));
- fprintf(stderr, "Reconnect-cookie: %s\n", base64);
+ DEBUG_WARN( "Reconnect-cookie: %s\n", base64);
free(base64);
}
return TRUE;
void rdp_write_client_auto_reconnect_cookie(wStream* s, rdpSettings* settings)
{
+ CryptoHmac hmac;
+ BYTE nullRandom[32];
+ BYTE cryptSecurityVerifier[16];
ARC_CS_PRIVATE_PACKET* autoReconnectCookie;
autoReconnectCookie = settings->ClientAutoReconnectCookie;
+ /* SecurityVerifier = HMAC(AutoReconnectRandom, ClientRandom) */
+
+ hmac = crypto_hmac_new();
+ ZeroMemory(nullRandom, sizeof(nullRandom));
+
+ crypto_hmac_md5_init(hmac, autoReconnectCookie->securityVerifier, 16);
+
+ if (settings->ClientRandomLength > 0)
+ crypto_hmac_update(hmac, settings->ClientRandom, settings->ClientRandomLength);
+ else
+ crypto_hmac_update(hmac, nullRandom, sizeof(nullRandom));
+
+ crypto_hmac_final(hmac, cryptSecurityVerifier, 16);
+ crypto_hmac_free(hmac);
+
Stream_Write_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
Stream_Write_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */
Stream_Write_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
- Stream_Write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */
+ Stream_Write(s, cryptSecurityVerifier, 16); /* SecurityVerifier */
}
/**
ARC_SC_PRIVATE_PACKET* serverCookie;
ARC_CS_PRIVATE_PACKET* clientCookie;
- printf("Sending auto reconnect\n");
+ DEBUG_MSG("Sending auto reconnect\n");
serverCookie = settings->ServerAutoReconnectCookie;
clientCookie = settings->ClientAutoReconnectCookie;
hmac = crypto_hmac_new();
if (!hmac)
{
- fprintf(stderr, "%s: unable to allocate hmac\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate hmac\n", __FUNCTION__);
goto out_free;
}
if (settings->RemoteConsoleAudio)
flags |= INFO_REMOTECONSOLEAUDIO;
+ if (settings->HiDefRemoteApp)
+ flags |= INFO_HIDEF_RAIL_SUPPORTED;
+
if (settings->CompressionEnabled)
{
flags |= INFO_COMPRESSION;
}
else
{
- /* This field MUST be filled with "*" */
- cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, "*", -1, &alternateShellW, 0) * 2;
+ if (settings->RemoteAssistancePassStub)
+ {
+ /* This field MUST be filled with "*" */
+ cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, "*", -1, &alternateShellW, 0) * 2;
+ }
+ else
+ {
+ /* This field must contain the remote assistance password */
+ cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistancePassword, -1, &alternateShellW, 0) * 2;
+ }
}
if (!settings->RemoteAssistanceMode)
{
if (securityFlags & SEC_REDIRECTION_PKT)
{
- fprintf(stderr, "Error: SEC_REDIRECTION_PKT unsupported\n");
+ DEBUG_WARN( "Error: SEC_REDIRECTION_PKT unsupported\n");
return FALSE;
}
{
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
{
- fprintf(stderr, "rdp_decrypt failed\n");
+ DEBUG_WARN( "rdp_decrypt failed\n");
return FALSE;
}
}
return FALSE;
Stream_Read_UINT32(s, infoType); /* infoType (4 bytes) */
- //fprintf(stderr, "%s\n", INFO_TYPE_LOGON_STRINGS[infoType]);
+ //DEBUG_WARN( "%s\n", INFO_TYPE_LOGON_STRINGS[infoType]);
switch (infoType)
{
#define INFO_USING_SAVED_CREDS 0x00100000
#define INFO_AUDIOCAPTURE 0x00200000
#define INFO_VIDEO_DISABLE 0x00400000
+#define INFO_HIDEF_RAIL_SUPPORTED 0x02000000
/* Logon Information Types */
#define INFO_TYPE_LOGON 0x00000000
input_send_mouse_event(input, PTR_FLAGS_MOVE, x, y);
}
+static void input_send_keyboard_pause_event(rdpInput* input)
+{
+ /* In ancient days, pause-down without control sent E1 1D 45 E1 9D C5,
+ * and pause-up sent nothing. However, reverse engineering mstsc shows
+ * it sending the following sequence:
+ */
+
+ /* Control down (0x1D) */
+ input_send_keyboard_event(input, 0,
+ RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL));
+ /* Numlock down (0x45) */
+ input_send_keyboard_event(input, 0,
+ RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK));
+ /* Control up (0x1D) */
+ input_send_keyboard_event(input, KBD_FLAGS_RELEASE,
+ RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL));
+ /* Numlock up (0x45) */
+ input_send_keyboard_event(input, KBD_FLAGS_RELEASE,
+ RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK));
+}
+
void input_send_fastpath_synchronize_event(rdpInput* input, UINT32 flags)
{
wStream* s;
fastpath_send_multiple_input_pdu(rdp->fastpath, s, 4);
}
+static void input_send_fastpath_keyboard_pause_event(rdpInput* input)
+{
+ /* In ancient days, pause-down without control sent E1 1D 45 E1 9D C5,
+ * and pause-up sent nothing. However, reverse engineering mstsc shows
+ * it sending the following sequence:
+ */
+ wStream* s;
+ rdpRdp* rdp = input->context->rdp;
+ const BYTE keyDownEvent = FASTPATH_INPUT_EVENT_SCANCODE << 5;
+ const BYTE keyUpEvent = (FASTPATH_INPUT_EVENT_SCANCODE << 5)
+ | FASTPATH_INPUT_KBDFLAGS_RELEASE;
+
+ s = fastpath_input_pdu_init_header(rdp->fastpath);
+
+ /* Control down (0x1D) */
+ Stream_Write_UINT8(s, keyDownEvent | FASTPATH_INPUT_KBDFLAGS_PREFIX_E1);
+ Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL));
+
+ /* Numlock down (0x45) */
+ Stream_Write_UINT8(s, keyDownEvent);
+ Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK));
+
+ /* Control up (0x1D) */
+ Stream_Write_UINT8(s, keyUpEvent | FASTPATH_INPUT_KBDFLAGS_PREFIX_E1);
+ Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL));
+
+ /* Numlock down (0x45) */
+ Stream_Write_UINT8(s, keyUpEvent);
+ Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK));
+
+ fastpath_send_multiple_input_pdu(rdp->fastpath, s, 4);
+}
+
static BOOL input_recv_sync_event(rdpInput* input, wStream* s)
{
UINT32 toggleFlags;
break;
default:
- fprintf(stderr, "Unknown messageType %u\n", messageType);
+ DEBUG_WARN( "Unknown messageType %u\n", messageType);
/* Each input event uses 6 bytes. */
Stream_Seek(s, 6);
break;
{
input->SynchronizeEvent = input_send_fastpath_synchronize_event;
input->KeyboardEvent = input_send_fastpath_keyboard_event;
+ input->KeyboardPauseEvent = input_send_fastpath_keyboard_pause_event;
input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event;
input->MouseEvent = input_send_fastpath_mouse_event;
input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event;
{
input->SynchronizeEvent = input_send_synchronize_event;
input->KeyboardEvent = input_send_keyboard_event;
+ input->KeyboardPauseEvent = input_send_keyboard_pause_event;
input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
input->MouseEvent = input_send_mouse_event;
input->ExtendedMouseEvent = input_send_extended_mouse_event;
IFCALL(input->FocusInEvent, input, toggleStates, x, y);
}
+void freerdp_input_send_keyboard_pause_event(rdpInput* input)
+{
+ IFCALL(input->KeyboardPauseEvent, input);
+}
+
int input_process_events(rdpInput* input)
{
return input_message_queue_process_pending_messages(input);
#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 */
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[] =
{
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);
-
- fprintf(stderr, "ProductInfo:\n");
- fprintf(stderr, "\tdwVersion: 0x%08X\n", productInfo->dwVersion);
- fprintf(stderr, "\tCompanyName: %s\n", CompanyName);
- fprintf(stderr, "\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);
}
{
int index;
LICENSE_BLOB* scope;
-
- fprintf(stderr, "ScopeList (%d):\n", scopeList->count);
+ DEBUG_WARN("ScopeList (%d):\n", scopeList->count);
for (index = 0; index < scopeList->count; index++)
{
scope = &scopeList->array[index];
- fprintf(stderr, "\t%s\n", (char*) scope->data);
+ DEBUG_WARN("\t%s\n", (char*) scope->data);
}
}
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;
}
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;
}
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;
/**
flags |= EXTENDED_ERROR_MSG_SUPPORTED;
license_write_preamble(s, type, flags, wMsgSize);
-
#ifdef WITH_DEBUG_LICENSE
- fprintf(stderr, "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;
}
if (!rdp_read_header(license->rdp, s, &length, &channelId))
{
- fprintf(stderr, "%s: Incorrect RDP header.\n", __FUNCTION__);
+ DEBUG_WARN("%s: Incorrect RDP header.\n", __FUNCTION__);
return -1;
}
{
if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags))
{
- fprintf(stderr, "%s: rdp_decrypt failed\n", __FUNCTION__);
+ DEBUG_WARN("%s: rdp_decrypt failed\n", __FUNCTION__);
return -1;
}
}
if (status < 0)
{
- fprintf(stderr, "%s: unexpected license packet.\n", __FUNCTION__);
+ DEBUG_WARN("%s: unexpected license packet.\n", __FUNCTION__);
return status;
}
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:
- fprintf(stderr, "%s: invalid bMsgType:%d\n", __FUNCTION__, bMsgType);
+ DEBUG_WARN("%s: invalid bMsgType:%d\n", __FUNCTION__, bMsgType);
return FALSE;
}
{
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
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
- fprintf(stderr, "ClientRandom:\n");
- winpr_HexDump(license->ClientRandom, CLIENT_RANDOM_LENGTH);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ServerRandom:\n");
- winpr_HexDump(license->ServerRandom, SERVER_RANDOM_LENGTH);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "PremasterSecret:\n");
- winpr_HexDump(license->PremasterSecret, PREMASTER_SECRET_LENGTH);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "MasterSecret:\n");
- winpr_HexDump(license->MasterSecret, MASTER_SECRET_LENGTH);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "SessionKeyBlob:\n");
- winpr_HexDump(license->SessionKeyBlob, SESSION_KEY_BLOB_LENGTH);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "MacSaltKey:\n");
- winpr_HexDump(license->MacSaltKey, MAC_SALT_KEY_LENGTH);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "LicensingEncryptionKey:\n");
- winpr_HexDump(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
- fprintf(stderr, "\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
}
{
CryptoMd5 md5;
BYTE* mac_address;
-
ZeroMemory(license->HardwareId, HWID_LENGTH);
mac_address = license->rdp->transport->TcpIn->mac_address;
-
md5 = crypto_md5_init();
+
if (!md5)
{
- fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__);
+ DEBUG_WARN("%s: unable to allocate a md5\n", __FUNCTION__);
return;
}
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);
void license_encrypt_premaster_secret(rdpLicense* license)
{
BYTE* EncryptedPremasterSecret;
-
license_get_server_rsa_public_key(license);
-
#ifdef WITH_DEBUG_LICENSE
- fprintf(stderr, "Modulus (%d bits):\n", license->ModulusLength * 8);
- winpr_HexDump(license->Modulus, license->ModulusLength);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Exponent:\n");
- winpr_HexDump(license->Exponent, 4);
- fprintf(stderr, "\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)
{
- fprintf(stderr, "%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);
}
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)
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)
productInfo->pbProductId = (BYTE*) malloc(productInfo->cbProductId);
Stream_Read(s, productInfo->pbProductId, productInfo->cbProductId);
-
return TRUE;
}
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;
}
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))
{
- fprintf(stderr, "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;
}
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) */
void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob, UINT32 ModulusLength)
{
UINT32 length;
-
length = ModulusLength + 8;
if (blob->length > ModulusLength)
{
- fprintf(stderr, "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) */
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;
}
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;
SCOPE_LIST* license_new_scope_list()
{
SCOPE_LIST* scopeList;
-
scopeList = (SCOPE_LIST*) malloc(sizeof(SCOPE_LIST));
scopeList->count = 0;
scopeList->array = NULL;
-
return scopeList;
}
license_generate_keys(license);
license_generate_hwid(license);
license_encrypt_premaster_secret(license);
-
#ifdef WITH_DEBUG_LICENSE
- fprintf(stderr, "ServerRandom:\n");
- winpr_HexDump(license->ServerRandom, 32);
- fprintf(stderr, "\n");
-
+ DEBUG_WARN("ServerRandom:\n");
+ winpr_HexDump(TAG, WLOG_DEBUG, license->ServerRandom, 32);
+ DEBUG_WARN("\n");
license_print_product_info(license->ProductInfo);
- fprintf(stderr, "\n");
-
+ DEBUG_WARN("\n");
license_print_scope_list(license->ScopeList);
- fprintf(stderr, "\n");
+ DEBUG_WARN("\n");
#endif
-
return TRUE;
}
{
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);
return FALSE;
Stream_Read(s, MacData, 16); /* MACData (16 bytes) */
-
license_decrypt_platform_challenge(license);
-
#ifdef WITH_DEBUG_LICENSE
- fprintf(stderr, "ConnectFlags: 0x%08X\n", ConnectFlags);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "EncryptedPlatformChallenge:\n");
- winpr_HexDump(license->EncryptedPlatformChallenge->data, license->EncryptedPlatformChallenge->length);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "PlatformChallenge:\n");
- winpr_HexDump(license->PlatformChallenge->data, license->PlatformChallenge->length);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "MacData:\n");
- winpr_HexDump(MacData, 16);
- fprintf(stderr, "\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;
}
return FALSE;
#ifdef WITH_DEBUG_LICENSE
- fprintf(stderr, "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)
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;
}
{
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
- fprintf(stderr, "PreferredKeyExchangeAlg: 0x%08X\n", PreferredKeyExchangeAlg);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ClientRandom:\n");
- winpr_HexDump(license->ClientRandom, 32);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "EncryptedPremasterSecret\n");
- winpr_HexDump(license->EncryptedPremasterSecret->data, license->EncryptedPremasterSecret->length);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ClientUserName (%d): %s\n", license->ClientUserName->length, (char*) license->ClientUserName->data);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ClientMachineName (%d): %s\n", license->ClientMachineName->length, (char*) license->ClientMachineName->data);
- fprintf(stderr, "\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
}
{
wStream* s;
char* username;
-
DEBUG_LICENSE("Sending New License Packet");
-
s = license_send_stream_init(license);
if (license->rdp->settings->Username != NULL)
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;
}
{
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 */
}
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)
{
- fprintf(stderr, "%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
- fprintf(stderr, "LicensingEncryptionKey:\n");
- winpr_HexDump(license->LicensingEncryptionKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "HardwareId:\n");
- winpr_HexDump(license->HardwareId, HWID_LENGTH);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "EncryptedHardwareId:\n");
- winpr_HexDump(license->EncryptedHardwareId->data, HWID_LENGTH);
- fprintf(stderr, "\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);
}
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);
}
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();
#ifdef _WIN32
_tprintf(_T("getaddrinfo error: %s\n"), gai_strerror(status));
#else
- perror("getaddrinfo");
+ DEBUG_WARN("getaddrinfo");
#endif
return FALSE;
}
if (sockfd == -1)
{
- perror("socket");
+ DEBUG_WARN("socket");
continue;
}
option_value = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*) &option_value, sizeof(option_value)) == -1)
- perror("setsockopt");
+ DEBUG_WARN("setsockopt");
#ifndef _WIN32
fcntl(sockfd, F_SETFL, O_NONBLOCK);
_tprintf(L"bind() failed with error: %u\n", WSAGetLastError());
WSACleanup();
#else
- perror("bind");
+ DEBUG_WARN("bind");
close(sockfd);
#endif
continue;
if (status != 0)
{
- perror("listen");
+ DEBUG_WARN("listen");
close(sockfd);
continue;
}
+ /* FIXME: these file descriptors do not work on Windows */
+
listener->sockfds[listener->num_sockfds] = sockfd;
listener->events[listener->num_sockfds] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, sockfd);
listener->num_sockfds++;
else
sin_addr = &(((struct sockaddr_in6*) ai->ai_addr)->sin6_addr);
- fprintf(stderr, "Listening on %s port %s.\n", inet_ntop(ai->ai_family, sin_addr, buf, sizeof(buf)), servname);
+ DEBUG_WARN( "Listening on %s port %s.\n", inet_ntop(ai->ai_family, sin_addr, buf, sizeof(buf)), servname);
}
freeaddrinfo(res);
if (sockfd == -1)
{
- perror("socket");
+ DEBUG_WARN("socket");
return FALSE;
}
if (status != 0)
{
- perror("bind");
+ DEBUG_WARN("bind");
close(sockfd);
return FALSE;
}
if (status != 0)
{
- perror("listen");
+ DEBUG_WARN("listen");
close(sockfd);
return FALSE;
}
listener->events[listener->num_sockfds] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, sockfd);
listener->num_sockfds++;
- fprintf(stderr, "Listening on socket %s.\n", addr.sun_path);
+ DEBUG_WARN( "Listening on socket %s.\n", addr.sun_path);
return TRUE;
#else
if (errno == EAGAIN || errno == EWOULDBLOCK)
continue;
#endif
- perror("accept");
+ DEBUG_WARN("accept");
if (client)
free(client);
return FALSE;
freerdp_listener* instance;
rdpListener* listener;
- instance = (freerdp_listener*) malloc(sizeof(freerdp_listener));
- ZeroMemory(instance, sizeof(freerdp_listener));
+ instance = (freerdp_listener*) calloc(1, sizeof(freerdp_listener));
+
+ if (!instance)
+ return NULL;
instance->Open = freerdp_listener_open;
instance->OpenLocal = freerdp_listener_open_local;
instance->CheckFileDescriptor = freerdp_listener_check_fds;
instance->Close = freerdp_listener_close;
- listener = (rdpListener*) malloc(sizeof(rdpListener));
- ZeroMemory(listener, sizeof(rdpListener));
+ listener = (rdpListener*) calloc(1, sizeof(rdpListener));
+
+ if (!listener)
+ return NULL;
listener->instance = instance;
void mcs_print_domain_parameters(DomainParameters* domainParameters)
{
- fprintf(stderr, "DomainParameters {\n");
- fprintf(stderr, "\tmaxChannelIds:%d\n", domainParameters->maxChannelIds);
- fprintf(stderr, "\tmaxUserIds:%d\n", domainParameters->maxUserIds);
- fprintf(stderr, "\tmaxTokenIds:%d\n", domainParameters->maxTokenIds);
- fprintf(stderr, "\tnumPriorities:%d\n", domainParameters->numPriorities);
- fprintf(stderr, "\tminThroughput:%d\n", domainParameters->minThroughput);
- fprintf(stderr, "\tmaxHeight:%d\n", domainParameters->maxHeight);
- fprintf(stderr, "\tmaxMCSPDUsize:%d\n", domainParameters->maxMCSPDUsize);
- fprintf(stderr, "\tprotocolVersion:%d\n", domainParameters->protocolVersion);
- fprintf(stderr, "}\n");
+ DEBUG_WARN( "DomainParameters {\n");
+ DEBUG_WARN( "\tmaxChannelIds:%d\n", domainParameters->maxChannelIds);
+ DEBUG_WARN( "\tmaxUserIds:%d\n", domainParameters->maxUserIds);
+ DEBUG_WARN( "\tmaxTokenIds:%d\n", domainParameters->maxTokenIds);
+ DEBUG_WARN( "\tnumPriorities:%d\n", domainParameters->numPriorities);
+ DEBUG_WARN( "\tminThroughput:%d\n", domainParameters->minThroughput);
+ DEBUG_WARN( "\tmaxHeight:%d\n", domainParameters->maxHeight);
+ DEBUG_WARN( "\tmaxMCSPDUsize:%d\n", domainParameters->maxMCSPDUsize);
+ DEBUG_WARN( "\tprotocolVersion:%d\n", domainParameters->protocolVersion);
+ DEBUG_WARN( "}\n");
}
/**
if (!gcc_read_conference_create_response(s, mcs))
{
- fprintf(stderr, "mcs_recv_connect_response: gcc_read_conference_create_response failed\n");
+ DEBUG_WARN( "mcs_recv_connect_response: gcc_read_conference_create_response failed\n");
return FALSE;
}
lParam = (WINDOW_ICON_ORDER*) malloc(sizeof(WINDOW_ICON_ORDER));
CopyMemory(lParam, windowIcon, sizeof(WINDOW_ICON_ORDER));
- fprintf(stderr, "update_message_WindowIcon\n");
+ DEBUG_WARN( "update_message_WindowIcon\n");
if (windowIcon->iconInfo->cbBitsColor > 0)
{
}
if (status < 0)
- fprintf(stderr, "Unknown message: class: %d type: %d\n", msgClass, msgType);
+ DEBUG_WARN( "Unknown message: class: %d type: %d\n", msgClass, msgType);
return status;
}
}
if (status < 0)
- fprintf(stderr, "Unknown message: class: %d type: %d\n", msgClass, msgType);
+ DEBUG_WARN( "Unknown message: class: %d type: %d\n", msgClass, msgType);
return status;
}
pointer->PointerCached = update_message_PointerCached;
}
-rdpUpdateProxy* update_message_proxy_new(rdpUpdate* update)
+static void *update_message_proxy_thread(void *arg)
{
- rdpUpdateProxy* message;
+ rdpUpdate *update = (rdpUpdate *)arg;
+ wMessage message;
+
+ if (!update || !update->queue)
+ {
+ DEBUG_WARN("update=%p, update->queue=%p", update, update ? update->queue : NULL);
+ ExitThread(-1);
+ return NULL;
+ }
+
+ while (MessageQueue_Wait(update->queue))
+ {
+ int status = 0;
+
+ if (MessageQueue_Peek(update->queue, &message, TRUE))
+ status = update_message_queue_process_message(update, &message);
- message = (rdpUpdateProxy*) malloc(sizeof(rdpUpdateProxy));
+ if (!status)
+ break;
+ }
+
+ ExitThread(0);
+ return NULL;
+}
+
+rdpUpdateProxy *update_message_proxy_new(rdpUpdate *update)
+{
+ rdpUpdateProxy *message;
+ message = (rdpUpdateProxy *) malloc(sizeof(rdpUpdateProxy));
if (message)
{
message->update = update;
update_message_register_interface(message, update);
+ message->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) update_message_proxy_thread, update, 0, NULL);
}
return message;
{
if (message)
{
+ MessageQueue_PostQuit(message->update->queue, 0);
+ WaitForSingleObject(message->thread, INFINITE);
+ CloseHandle(message->thread);
free(message);
}
}
}
if (status < 0)
- fprintf(stderr, "Unknown event: class: %d type: %d\n", msgClass, msgType);
+ DEBUG_WARN( "Unknown event: class: %d type: %d\n", msgClass, msgType);
return status;
}
}
if (status < 0)
- fprintf(stderr, "Unknown event: class: %d type: %d\n", msgClass, msgType);
+ DEBUG_WARN( "Unknown event: class: %d type: %d\n", msgClass, msgType);
return status;
}
pPointerColor PointerColor;
pPointerNew PointerNew;
pPointerCached PointerCached;
+
+ HANDLE thread;
};
int update_message_queue_process_message(rdpUpdate* update, wMessage* message);
#include "transport.h"
+#ifdef WITH_DEBUG_NEGO
static const char* const NEGO_STATE_STRINGS[] =
{
"NEGO_STATE_INITIAL",
"UNK",
"EXT"
};
+#endif /* WITH_DEBUG_NEGO */
BOOL nego_security_connect(rdpNego* nego);
}
else
{
- fprintf(stderr, "invalid negotiation response\n");
+ DEBUG_WARN( "invalid negotiation response\n");
nego->state = NEGO_STATE_FAIL;
}
if (li != Stream_GetRemainingLength(s) + 6)
{
- fprintf(stderr, "Incorrect TPDU length indicator.\n");
+ DEBUG_WARN( "Incorrect TPDU length indicator.\n");
return FALSE;
}
if (type != TYPE_RDP_NEG_REQ)
{
- fprintf(stderr, "Incorrect negotiation request type %d\n", type);
+ DEBUG_WARN( "Incorrect negotiation request type %d\n", type);
return FALSE;
}
bm = Stream_GetPosition(s);
Stream_Seek(s, length);
- if (nego->selected_protocol > PROTOCOL_RDP)
- {
- flags = EXTENDED_CLIENT_DATA_SUPPORTED;
-
- if (settings->SupportGraphicsPipeline)
- flags |= DYNVC_GFX_PROTOCOL_SUPPORTED;
-
- /* RDP_NEG_DATA must be present for TLS and NLA */
- Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP);
- Stream_Write_UINT8(s, flags); /* flags */
- Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
- Stream_Write_UINT32(s, nego->selected_protocol); /* selectedProtocol */
- length += 8;
- }
- else if (!settings->RdpSecurity)
+ if ((nego->selected_protocol == PROTOCOL_RDP) && !settings->RdpSecurity)
{
flags = 0;
Stream_Write_UINT8(s, TYPE_RDP_NEG_FAILURE);
Stream_Write_UINT8(s, flags); /* flags */
Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
+
/*
* TODO: Check for other possibilities,
* like SSL_NOT_ALLOWED_BY_SERVER.
*/
- fprintf(stderr, "%s: client supports only Standard RDP Security\n", __FUNCTION__);
+ DEBUG_WARN( "%s: client supports only Standard RDP Security\n", __FUNCTION__);
+
Stream_Write_UINT32(s, SSL_REQUIRED_BY_SERVER);
length += 8;
status = FALSE;
}
+ else
+ {
+ flags = EXTENDED_CLIENT_DATA_SUPPORTED;
+
+ if (settings->SupportGraphicsPipeline)
+ flags |= DYNVC_GFX_PROTOCOL_SUPPORTED;
+
+ /* RDP_NEG_DATA must be present for TLS, NLA, and RDP */
+ Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP);
+ Stream_Write_UINT8(s, flags); /* flags */
+ Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
+ Stream_Write_UINT32(s, nego->selected_protocol); /* selectedProtocol */
+ length += 8;
+ }
em = Stream_GetPosition(s);
Stream_SetPosition(s, bm);
if (!settings->LocalConnection)
{
- settings->DisableEncryption = TRUE;
+ settings->DisableEncryption = FALSE;
settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
}
- if (settings->DisableEncryption && !settings->RdpServerRsaKey && !settings->RdpKeyFile)
+ if (settings->DisableEncryption)
+ {
+ fprintf(stderr, "Encryption is disabled.\n");
+ return FALSE;
+ }
+
+ if (!settings->RdpServerRsaKey && !settings->RdpKeyFile)
+ {
+ fprintf(stderr, "Missing server certificate\n");
return FALSE;
+ }
}
else if (settings->SelectedProtocol == PROTOCOL_TLS)
{
#include <unistd.h>
#endif
+#include <freerdp/log.h>
#include <freerdp/crypto/tls.h>
#include <winpr/crt.h>
#include "nla.h"
+#define TAG FREERDP_TAG("core")
+
/**
* TSRequest ::= SEQUENCE {
* version [0] INTEGER,
rdpTls* tls = NULL;
freerdp* instance;
rdpSettings* settings;
-
PromptPassword = FALSE;
settings = credssp->settings;
instance = (freerdp*) settings->instance;
}
#ifndef _WIN32
+
if (PromptPassword)
{
if (settings->RestrictedAdminModeRequired)
PromptPassword = FALSE;
}
}
+
#endif
if (PromptPassword)
if (instance->Authenticate)
{
BOOL proceed = instance->Authenticate(instance,
- &settings->Username, &settings->Password, &settings->Domain);
+ &settings->Username, &settings->Password, &settings->Domain);
if (!proceed)
{
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);
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.
}
}
#endif
-
#ifdef WITH_DEBUG_NLA
- _tprintf(_T("User: %s Domain: %s Password: %s\n"),
- (char*) credssp->identity.User, (char*) credssp->identity.Domain, (char*) credssp->identity.Password);
+ DEBUG_MSG("User: %s Domain: %s Password: %s\n",
+ (char*) credssp->identity.User, (char*) credssp->identity.Domain, (char*) credssp->identity.Password);
#endif
if (credssp->transport->layer == TRANSPORT_LAYER_TLS)
}
else
{
- fprintf(stderr, "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;
}
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;
}
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)
{
- fprintf(stderr, "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)
{
- fprintf(stderr, "AcquireCredentialsHandle status: 0x%08X\n", status);
+ DEBUG_WARN("AcquireCredentialsHandle status: 0x%08X\n", status);
return 0;
}
ZeroMemory(&input_buffer, sizeof(SecBuffer));
ZeroMemory(&output_buffer, sizeof(SecBuffer));
ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes));
-
/*
* from tspkg.dll: 0x00000132
* ISC_REQ_MUTUAL_AUTH
* ISC_REQ_USE_SESSION_KEY
* ISC_REQ_ALLOCATE_MEMORY
*/
-
fContextReq = ISC_REQ_MUTUAL_AUTH | ISC_REQ_CONFIDENTIALITY | ISC_REQ_USE_SESSION_KEY;
while (TRUE)
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))
{
if (credssp->table->QueryContextAttributes(&credssp->context, SECPKG_ATTR_SIZES, &credssp->ContextSizes) != SEC_E_OK)
{
- fprintf(stderr, "QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
+ DEBUG_WARN("QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
return 0;
}
{
credssp->negoToken.pvBuffer = output_buffer.pvBuffer;
credssp->negoToken.cbBuffer = output_buffer.cbBuffer;
-
#ifdef WITH_DEBUG_CREDSSP
- fprintf(stderr, "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);
}
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;
return -1;
#ifdef WITH_DEBUG_CREDSSP
- fprintf(stderr, "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;
}
return -1;
/* Verify Server Public Key Echo */
-
status = credssp_decrypt_public_key_echo(credssp);
credssp_buffer_free(credssp);
if (status != SEC_E_OK)
{
- fprintf(stderr, "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)
{
- fprintf(stderr, "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;
}
BOOL have_context;
BOOL have_input_buffer;
BOOL have_pub_key_auth;
-
sspi_GlobalInit();
if (credssp_ntlm_server_init(credssp) == 0)
{
HMODULE hSSPI;
INIT_SECURITY_INTERFACE pInitSecurityInterface;
-
hSSPI = LoadLibrary(credssp->SspiModule);
if (!hSSPI)
{
- _tprintf(_T("Failed to load SSPI module: %s\n"), credssp->SspiModule);
+ DEBUG_WARN("Failed to load SSPI module: %s\n", credssp->SspiModule);
return 0;
}
#else
pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA");
#endif
-
credssp->table = pInitSecurityInterface();
}
else
if (status != SEC_E_OK)
{
- fprintf(stderr, "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)
{
- fprintf(stderr, "AcquireCredentialsHandle status: 0x%08X\n", status);
+ DEBUG_WARN("AcquireCredentialsHandle status: 0x%08X\n", status);
return 0;
}
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)
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;
return -1;
#ifdef WITH_DEBUG_CREDSSP
- fprintf(stderr, "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)
{
- fprintf(stderr, "CredSSP: invalid negoToken!\n");
+ DEBUG_WARN("CredSSP: invalid negoToken!\n");
return -1;
}
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;
if (credssp->table->QueryContextAttributes(&credssp->context, SECPKG_ATTR_SIZES, &credssp->ContextSizes) != SEC_E_OK)
{
- fprintf(stderr, "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)
{
- fprintf(stderr, "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))
{
- fprintf(stderr, "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
- fprintf(stderr, "Sending Authentication Token\n");
+ DEBUG_WARN("Sending Authentication Token\n");
credssp_buffer_print(credssp);
#endif
-
credssp_send(credssp);
credssp_buffer_free(credssp);
if (credssp_decrypt_ts_credentials(credssp) != SEC_E_OK)
{
- fprintf(stderr, "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)
{
- fprintf(stderr, "AcceptSecurityContext status: 0x%08X\n", status);
+ DEBUG_WARN("AcceptSecurityContext status: 0x%08X\n", status);
return 0;
}
if (status != SEC_E_OK)
{
- fprintf(stderr, "ImpersonateSecurityContext status: 0x%08X\n", status);
+ DEBUG_WARN("ImpersonateSecurityContext status: 0x%08X\n", status);
return 0;
}
else
if (status != SEC_E_OK)
{
- fprintf(stderr, "RevertSecurityContext status: 0x%08X\n", status);
+ DEBUG_WARN("RevertSecurityContext status: 0x%08X\n", status);
return 0;
}
}
credssp->table->FreeContextBuffer(pPackageInfo);
-
return 1;
}
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);
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)
{
- fprintf(stderr, "EncryptMessage status: 0x%08X\n", status);
+ DEBUG_WARN("EncryptMessage status: 0x%08X\n", status);
return status;
}
if (credssp->PublicKey.cbBuffer + credssp->ContextSizes.cbMaxSignature != credssp->pubKeyAuth.cbBuffer)
{
- fprintf(stderr, "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)
{
- fprintf(stderr, "DecryptMessage failure: 0x%08X\n", status);
+ DEBUG_WARN("DecryptMessage failure: 0x%08X\n", status);
return status;
}
if (memcmp(public_key1, public_key2, public_key_length) != 0)
{
- fprintf(stderr, "Could not verify server's public key echo\n");
-
- fprintf(stderr, "Expected (length = %d):\n", public_key_length);
- winpr_HexDump(public_key1, public_key_length);
-
- fprintf(stderr, "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);
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);
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);
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;
}
{
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;
}
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);
}
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;
}
int DomainLength;
int UserLength;
int PasswordLength;
-
DomainLength = credssp->identity.DomainLength;
UserLength = credssp->identity.UserLength;
PasswordLength = credssp->identity.PasswordLength;
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);
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)
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)
{
- fprintf(stderr, "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;
}
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 */
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
}
{
length = auth_info_length;
length -= ber_write_sequence_octet_string(s, 2, credssp->authInfo.pvBuffer, credssp->authInfo.cbBuffer);
-
// assert length == 0
}
{
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);
}
int length;
int status;
UINT32 version;
-
s = Stream_New(NULL, 4096);
-
status = transport_read_pdu(credssp->transport, s);
if (status < 0)
{
- fprintf(stderr, "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;
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;
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;
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;
}
{
if (credssp->negoToken.cbBuffer > 0)
{
- fprintf(stderr, "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)
{
- fprintf(stderr, "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)
{
- fprintf(stderr, "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);
}
}
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);
ServicePrincipalName = (LPTSTR) _tcsdup(hostnameX);
free(ServiceClassX);
free(hostnameX);
-
return ServicePrincipalName;
}
}
ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR));
+
if (!ServicePrincipalName)
return NULL;
free(ServiceClassX);
free(hostnameX);
-
return ServicePrincipalName;
}
rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings* settings)
{
rdpCredssp* credssp;
-
credssp = (rdpCredssp*) calloc(1, sizeof(rdpCredssp));
if (credssp)
LONG status;
DWORD dwType;
DWORD dwSize;
-
credssp->instance = instance;
credssp->settings = settings;
credssp->server = settings->ServerMode;
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)
{
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)
{
- _tprintf(_T("Using SSPI Module: %s\n"), credssp->SspiModule);
+ DEBUG_WARN("Using SSPI Module: %s\n", credssp->SspiModule);
RegCloseKey(hKey);
}
}
sspi_SecBufferFree(&credssp->PublicKey);
sspi_SecBufferFree(&credssp->ts_credentials);
-
free(credssp->ServicePrincipalName);
-
free(credssp->identity.User);
free(credssp->identity.Domain);
free(credssp->identity.Password);
if (orderInfo->fieldFlags & (1 << (NO-1))) \
{ \
if (Stream_GetRemainingLength(s) < 1) {\
- fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \
+ DEBUG_WARN( "%s: error reading %s\n", __FUNCTION__, #TARGET); \
return FALSE; \
} \
Stream_Read_UINT8(s, TARGET); \
if (orderInfo->fieldFlags & (1 << (NO-1))) \
{ \
if (Stream_GetRemainingLength(s) < 2) { \
- fprintf(stderr, "%s: error reading %s or %s\n", __FUNCTION__, #TARGET1, #TARGET2); \
+ DEBUG_WARN( "%s: error reading %s or %s\n", __FUNCTION__, #TARGET1, #TARGET2); \
return FALSE; \
} \
Stream_Read_UINT8(s, TARGET1); \
if (orderInfo->fieldFlags & (1 << (NO-1))) \
{ \
if (Stream_GetRemainingLength(s) < 2) { \
- fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \
+ DEBUG_WARN( "%s: error reading %s\n", __FUNCTION__, #TARGET); \
return FALSE; \
} \
Stream_Read_UINT16(s, TARGET); \
if (orderInfo->fieldFlags & (1 << (NO-1))) \
{ \
if (Stream_GetRemainingLength(s) < 4) { \
- fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \
+ DEBUG_WARN( "%s: error reading %s\n", __FUNCTION__, #TARGET); \
return FALSE; \
} \
Stream_Read_UINT32(s, TARGET); \
#define ORDER_FIELD_COORD(NO, TARGET) \
do { \
if ((orderInfo->fieldFlags & (1 << (NO-1))) && !update_read_coord(s, &TARGET, orderInfo->deltaCoordinates)) { \
- fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \
+ DEBUG_WARN( "%s: error reading %s\n", __FUNCTION__, #TARGET); \
return FALSE; \
} \
} while(0)
#define ORDER_FIELD_COLOR(NO, TARGET) \
do { \
if ((orderInfo->fieldFlags & (1 << (NO-1))) && !update_read_color(s, &TARGET)) { \
- fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \
+ DEBUG_WARN( "%s: error reading %s\n", __FUNCTION__, #TARGET); \
return FALSE; \
} \
} while(0)
#define FIELD_SKIP_BUFFER16(s, TARGET_LEN) \
do { \
if (Stream_GetRemainingLength(s) < 2) {\
- fprintf(stderr, "%s: error reading length %s\n", __FUNCTION__, #TARGET_LEN); \
+ DEBUG_WARN( "%s: error reading length %s\n", __FUNCTION__, #TARGET_LEN); \
return FALSE; \
}\
Stream_Read_UINT16(s, TARGET_LEN); \
if (!Stream_SafeSeek(s, TARGET_LEN)) { \
- fprintf(stderr, "%s: error skipping %d bytes\n", __FUNCTION__, TARGET_LEN); \
+ DEBUG_WARN( "%s: error skipping %d bytes\n", __FUNCTION__, TARGET_LEN); \
return FALSE; \
} \
} while(0)
Stream_Read_UINT8(s, cache_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */
if ((cache_bitmap->bitmapBpp < 1) || (cache_bitmap->bitmapBpp > 32))
{
- fprintf(stderr, "%s: invalid bitmap bpp %d\n", __FUNCTION__, cache_bitmap->bitmapBpp);
+ DEBUG_WARN( "%s: invalid bitmap bpp %d\n", __FUNCTION__, cache_bitmap->bitmapBpp);
return FALSE;
}
Stream_Read_UINT16(s, cache_bitmap->bitmapLength); /* bitmapLength (2 bytes) */
Stream_Read_UINT8(s, bitmapData->bpp);
if ((bitmapData->bpp < 1) || (bitmapData->bpp > 32))
{
- fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, bitmapData->bpp);
+ DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, bitmapData->bpp);
return FALSE;
}
Stream_Seek_UINT8(s); /* reserved1 (1 byte) */
{
if (cache_brush->length != 8)
{
- fprintf(stderr, "incompatible 1bpp brush of length:%d\n", cache_brush->length);
+ DEBUG_WARN( "incompatible 1bpp brush of length:%d\n", cache_brush->length);
return TRUE; // should be FALSE ?
}
{
if (cache_brush->length != 8)
{
- fprintf(stderr, "incompatible 1bpp brush of length:%d\n", cache_brush->length);
+ DEBUG_WARN( "incompatible 1bpp brush of length:%d\n", cache_brush->length);
return FALSE;
}
Stream_Read_UINT8(s, create_nine_grid_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */
if ((create_nine_grid_bitmap->bitmapBpp < 1) || (create_nine_grid_bitmap->bitmapBpp > 32))
{
- fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, create_nine_grid_bitmap->bitmapBpp);
+ DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, create_nine_grid_bitmap->bitmapBpp);
return FALSE;
}
Stream_Read_UINT16(s, create_nine_grid_bitmap->bitmapId); /* bitmapId (2 bytes) */
Stream_Read_UINT8(s, stream_bitmap_first->bitmapBpp); /* bitmapBpp (1 byte) */
if ((stream_bitmap_first->bitmapBpp < 1) || (stream_bitmap_first->bitmapBpp > 32))
{
- fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, stream_bitmap_first->bitmapBpp);
+ DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, stream_bitmap_first->bitmapBpp);
return FALSE;
}
if (orderInfo->orderType >= PRIMARY_DRAWING_ORDER_COUNT)
{
- fprintf(stderr, "Invalid Primary Drawing Order (0x%02X)\n", orderInfo->orderType);
+ DEBUG_WARN( "Invalid Primary Drawing Order (0x%02X)\n", orderInfo->orderType);
return FALSE;
}
orderInfo->deltaCoordinates = (flags & ORDER_DELTA_COORDINATES) ? TRUE : FALSE;
#ifdef WITH_DEBUG_ORDERS
- fprintf(stderr, "%s Primary Drawing Order (0x%02X)\n", PRIMARY_DRAWING_ORDER_STRINGS[orderInfo->orderType], orderInfo->orderType);
+ DEBUG_WARN( "%s Primary Drawing Order (0x%02X)\n", PRIMARY_DRAWING_ORDER_STRINGS[orderInfo->orderType], orderInfo->orderType);
#endif
switch (orderInfo->orderType)
#ifdef WITH_DEBUG_ORDERS
if (orderType < SECONDARY_DRAWING_ORDER_COUNT)
- fprintf(stderr, "%s Secondary Drawing Order (0x%02X)\n", SECONDARY_DRAWING_ORDER_STRINGS[orderType], orderType);
+ DEBUG_WARN( "%s Secondary Drawing Order (0x%02X)\n", SECONDARY_DRAWING_ORDER_STRINGS[orderType], orderType);
else
- fprintf(stderr, "Unknown Secondary Drawing Order (0x%02X)\n", orderType);
+ DEBUG_WARN( "Unknown Secondary Drawing Order (0x%02X)\n", orderType);
#endif
switch (orderType)
#ifdef WITH_DEBUG_ORDERS
if (orderType < ALTSEC_DRAWING_ORDER_COUNT)
- fprintf(stderr, "%s Alternate Secondary Drawing Order (0x%02X)\n", ALTSEC_DRAWING_ORDER_STRINGS[orderType], orderType);
+ DEBUG_WARN( "%s Alternate Secondary Drawing Order (0x%02X)\n", ALTSEC_DRAWING_ORDER_STRINGS[orderType], orderType);
else
- fprintf(stderr, "Unknown Alternate Secondary Drawing Order: 0x%02X\n", orderType);
+ DEBUG_WARN( "Unknown Alternate Secondary Drawing Order: 0x%02X\n", orderType);
#endif
switch (orderType)
static BOOL freerdp_peer_initialize(freerdp_peer* client)
{
- rdpRdp *rdp = client->context->rdp;
- rdpSettings *settings = rdp->settings;
+ rdpRdp* rdp = client->context->rdp;
+ rdpSettings* settings = rdp->settings;
settings->ServerMode = TRUE;
settings->FrameAcknowledge = 0;
settings->LocalConnection = client->local;
rdp->state = CONNECTION_STATE_INITIAL;
- if (settings->RdpKeyFile != NULL)
+ if (settings->RdpKeyFile)
{
settings->RdpServerRsaKey = key_new(settings->RdpKeyFile);
+
if (!settings->RdpServerRsaKey)
{
- fprintf(stderr, "%s: inavlid RDP key file %s\n", __FUNCTION__, settings->RdpKeyFile);
+ DEBUG_WARN( "%s: inavlid RDP key file %s\n", __FUNCTION__, settings->RdpKeyFile);
return FALSE;
}
if (settings->RdpServerRsaKey->ModulusLength > 256)
{
- fprintf(stderr, "%s: Key sizes > 2048 are currently not supported for RDP security.\n", __FUNCTION__);
- fprintf(stderr, "%s: Set a different key file than %s\n", __FUNCTION__, settings->RdpKeyFile);
+ DEBUG_WARN( "%s: Key sizes > 2048 are currently not supported for RDP security.\n", __FUNCTION__);
+ DEBUG_WARN( "%s: Set a different key file than %s\n", __FUNCTION__, settings->RdpKeyFile);
exit(1);
}
}
return client->context->rdp->transport->TcpIn->event;
}
-
static BOOL freerdp_peer_check_fds(freerdp_peer* peer)
{
int status;
return FALSE;
#ifdef WITH_DEBUG_RDP
- printf("recv %s Data PDU (0x%02X), length: %d\n",
+ DEBUG_MSG("recv %s Data PDU (0x%02X), length: %d\n",
type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length);
#endif
break;
default:
- fprintf(stderr, "Data PDU type %d\n", type);
+ DEBUG_WARN( "Data PDU type %d\n", type);
break;
}
if (!rdp_read_header(rdp, s, &length, &channelId))
{
- fprintf(stderr, "Incorrect RDP header.\n");
+ DEBUG_WARN( "Incorrect RDP header.\n");
return -1;
}
+ if (rdp->disconnect)
+ return 0;
+
if (rdp->settings->DisableEncryption)
{
if (!rdp_read_security_header(s, &securityFlags))
{
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
{
- fprintf(stderr, "rdp_decrypt failed\n");
+ DEBUG_WARN( "rdp_decrypt failed\n");
return -1;
}
}
break;
default:
- fprintf(stderr, "Client sent pduType %d\n", pduType);
+ DEBUG_WARN( "Client sent pduType %d\n", pduType);
return -1;
}
}
if ((length == 0) || (length > Stream_GetRemainingLength(s)))
{
- fprintf(stderr, "incorrect FastPath PDU header length %d\n", length);
+ DEBUG_WARN( "incorrect FastPath PDU header length %d\n", length);
return -1;
}
break;
default:
- fprintf(stderr, "Invalid state %d\n", rdp->state);
+ DEBUG_WARN( "Invalid state %d\n", rdp->state);
return -1;
}
{
rdpRdp* rdp;
- client->context = (rdpContext *)calloc(1, client->ContextSize);
+ client->context = (rdpContext*) calloc(1, client->ContextSize);
client->context->ServerMode = TRUE;
rdp_set_error_info(rdp, ERRINFO_RPC_INITIATED_DISCONNECT);
}
- fprintf(stderr, "DisconnectProviderUltimatum: reason: %d\n", reason);
+ DEBUG_WARN( "DisconnectProviderUltimatum: reason: %d\n", reason);
rdp->disconnect = TRUE;
if (Stream_GetRemainingLength(s) < (size_t) SrcSize)
{
- fprintf(stderr, "bulk_decompress: not enough bytes for compressedLength %d\n", compressedLength);
+ DEBUG_WARN( "bulk_decompress: not enough bytes for compressedLength %d\n", compressedLength);
return -1;
}
}
else
{
- fprintf(stderr, "bulk_decompress() failed\n");
+ DEBUG_WARN( "bulk_decompress() failed\n");
return -1;
}
}
#ifdef WITH_DEBUG_RDP
- printf("recv %s Data PDU (0x%02X), length: %d\n",
+ DEBUG_MSG("recv %s Data PDU (0x%02X), length: %d\n",
type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length);
#endif
if (!security_fips_decrypt(Stream_Pointer(s), length, rdp))
{
- fprintf(stderr, "FATAL: cannot decrypt\n");
+ DEBUG_WARN( "FATAL: cannot decrypt\n");
return FALSE; /* TODO */
}
if (!security_fips_check_signature(Stream_Pointer(s), length - pad, sig, rdp))
{
- fprintf(stderr, "FATAL: invalid packet signature\n");
+ DEBUG_WARN( "FATAL: invalid packet signature\n");
return FALSE; /* TODO */
}
if (memcmp(wmac, cmac, sizeof(wmac)) != 0)
{
- fprintf(stderr, "WARNING: invalid packet signature\n");
+ DEBUG_WARN( "WARNING: invalid packet signature\n");
/*
* Because Standard RDP Security is totally broken,
* and cannot protect against MITM, don't treat signature
if (!rdp_read_header(rdp, s, &length, &channelId))
{
- fprintf(stderr, "Incorrect RDP header.\n");
+ DEBUG_WARN( "Incorrect RDP header.\n");
return -1;
}
+ if (rdp->disconnect)
+ return 0;
+
if (rdp->settings->DisableEncryption)
{
if (!rdp_read_security_header(s, &securityFlags))
{
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
{
- fprintf(stderr, "rdp_decrypt failed\n");
+ DEBUG_WARN( "rdp_decrypt failed\n");
return -1;
}
}
case PDU_TYPE_DATA:
if (rdp_recv_data_pdu(rdp, s) < 0)
{
- fprintf(stderr, "rdp_recv_data_pdu failed\n");
+ DEBUG_WARN( "rdp_recv_data_pdu failed\n");
return -1;
}
break;
break;
default:
- fprintf(stderr, "incorrect PDU type: 0x%04X\n", pduType);
+ DEBUG_WARN( "incorrect PDU type: 0x%04X\n", pduType);
break;
}
if ((length == 0) || (length > Stream_GetRemainingLength(s)))
{
- fprintf(stderr, "incorrect FastPath PDU header length %d\n", length);
+ DEBUG_WARN( "incorrect FastPath PDU header length %d\n", length);
return -1;
}
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:
break;
default:
- fprintf(stderr, "Invalid state %d\n", rdp->state);
+ DEBUG_WARN( "Invalid state %d\n", rdp->state);
status = -1;
break;
}
#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)
{
- fprintf(stderr, "redirectionFlags = {\n");
+ DEBUG_WARN("redirectionFlags = {\n");
if (flags & LB_TARGET_NET_ADDRESS)
- fprintf(stderr, "\tLB_TARGET_NET_ADDRESS\n");
+ DEBUG_WARN("\tLB_TARGET_NET_ADDRESS\n");
+
if (flags & LB_LOAD_BALANCE_INFO)
- fprintf(stderr, "\tLB_LOAD_BALANCE_INFO\n");
+ DEBUG_WARN("\tLB_LOAD_BALANCE_INFO\n");
+
if (flags & LB_USERNAME)
- fprintf(stderr, "\tLB_USERNAME\n");
+ DEBUG_WARN("\tLB_USERNAME\n");
+
if (flags & LB_DOMAIN)
- fprintf(stderr, "\tLB_DOMAIN\n");
+ DEBUG_WARN("\tLB_DOMAIN\n");
+
if (flags & LB_PASSWORD)
- fprintf(stderr, "\tLB_PASSWORD\n");
+ DEBUG_WARN("\tLB_PASSWORD\n");
+
if (flags & LB_DONTSTOREUSERNAME)
- fprintf(stderr, "\tLB_DONTSTOREUSERNAME\n");
+ DEBUG_WARN("\tLB_DONTSTOREUSERNAME\n");
+
if (flags & LB_SMARTCARD_LOGON)
- fprintf(stderr, "\tLB_SMARTCARD_LOGON\n");
+ DEBUG_WARN("\tLB_SMARTCARD_LOGON\n");
+
if (flags & LB_NOREDIRECT)
- fprintf(stderr, "\tLB_NOREDIRECT\n");
+ DEBUG_WARN("\tLB_NOREDIRECT\n");
+
if (flags & LB_TARGET_FQDN)
- fprintf(stderr, "\tLB_TARGET_FQDN\n");
+ DEBUG_WARN("\tLB_TARGET_FQDN\n");
+
if (flags & LB_TARGET_NETBIOS_NAME)
- fprintf(stderr, "\tLB_TARGET_NETBIOS_NAME\n");
+ DEBUG_WARN("\tLB_TARGET_NETBIOS_NAME\n");
+
if (flags & LB_TARGET_NET_ADDRESSES)
- fprintf(stderr, "\tLB_TARGET_NET_ADDRESSES\n");
+ DEBUG_WARN("\tLB_TARGET_NET_ADDRESSES\n");
+
if (flags & LB_CLIENT_TSV_URL)
- fprintf(stderr, "\tLB_CLIENT_TSV_URL\n");
+ DEBUG_WARN("\tLB_CLIENT_TSV_URL\n");
+
if (flags & LB_SERVER_TSV_CAPABLE)
- fprintf(stderr, "\tLB_SERVER_TSV_CAPABLE\n");
+ DEBUG_WARN("\tLB_SERVER_TSV_CAPABLE\n");
- fprintf(stderr, "}\n");
+ DEBUG_WARN("}\n");
}
BOOL rdp_redirection_read_string(wStream* s, char** str)
if (Stream_GetRemainingLength(s) < 4)
{
- fprintf(stderr, "rdp_redirection_read_string failure: cannot read length\n");
+ DEBUG_WARN("rdp_redirection_read_string failure: cannot read length\n");
return FALSE;
}
if (Stream_GetRemainingLength(s) < length)
{
- fprintf(stderr, "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;
}
{
rdpSettings* settings = rdp->settings;
rdpRedirection* redirection = rdp->redirection;
-
settings->RedirectionFlags = redirection->flags;
settings->RedirectedSessionId = redirection->sessionID;
* 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;
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);
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
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
}
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
}
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
}
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++)
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
sha1 = crypto_sha1_init();
if (!sha1)
{
- fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__);
return;
}
crypto_sha1_update(sha1, input, length); /* Input */
md5 = crypto_md5_init();
if (!md5)
{
- fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__);
return;
}
crypto_md5_update(md5, salt, 48); /* Salt (48 bytes) */
md5 = crypto_md5_init();
if (!md5)
{
- fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__);
return;
}
crypto_md5_update(md5, in0, 16);
sha1 = crypto_sha1_init();
if (!sha1)
{
- fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__);
return;
}
crypto_sha1_update(sha1, mac_salt_key, 16); /* MacSaltKey */
md5 = crypto_md5_init();
if (!md5)
{
- fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__);
return;
}
crypto_md5_update(md5, mac_salt_key, 16); /* MacSaltKey */
sha1 = crypto_sha1_init();
if (!sha1)
{
- fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__);
return;
}
crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
md5 = crypto_md5_init();
if (!md5)
{
- fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__);
return;
}
crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
sha1 = crypto_sha1_init();
if (!sha1)
{
- fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__);
return;
}
crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
md5 = crypto_md5_init();
if (!md5)
{
- fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__);
return;
}
crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
BYTE client_encrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1];
BYTE client_decrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1];
- fprintf(stderr, "FIPS Compliant encryption level.\n");
+ DEBUG_WARN( "FIPS Compliant encryption level.\n");
sha1 = crypto_sha1_init();
if (!sha1)
{
- fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__);
return FALSE;
}
crypto_sha1_update(sha1, client_random + 16, 16);
sha1 = crypto_sha1_init();
if (!sha1)
{
- fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__);
return FALSE;
}
crypto_sha1_update(sha1, client_random, 16);
sha1 = crypto_sha1_init();
if (!sha1)
{
- fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__);
return FALSE;
}
crypto_sha1_update(sha1, client_decrypt_key_t, 20);
sha1 = crypto_sha1_init();
if (!sha1)
{
- fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__);
return FALSE;
}
crypto_sha1_update(sha1, update_key, key_len);
md5 = crypto_md5_init();
if (!md5)
{
- fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__);
return FALSE;
}
crypto_md5_update(md5, update_key, key_len);
rc4 = crypto_rc4_init(key, key_len);
if (!rc4)
{
- fprintf(stderr, "%s: unable to allocate a rc4\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate a rc4\n", __FUNCTION__);
return FALSE;
}
crypto_rc4(rc4, key_len, key, key);
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_encrypt_key)
{
- fprintf(stderr, "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__);
return FALSE;
}
rdp->encrypt_use_count = 0;
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_decrypt_key)
{
- fprintf(stderr, "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__);
return FALSE;
}
if (Stream_GetPosition(channel->receiveData) + length > channel->dvc_total_length)
{
channel->dvc_total_length = 0;
- fprintf(stderr, "wts_read_drdynvc_data: incorrect fragment data, discarded.\n");
+ DEBUG_WARN( "wts_read_drdynvc_data: incorrect fragment data, discarded.\n");
return;
}
break;
default:
- fprintf(stderr, "wts_read_drdynvc_pdu: Cmd %d not recognized.\n", Cmd);
+ DEBUG_WARN( "wts_read_drdynvc_pdu: Cmd %d not recognized.\n", Cmd);
break;
}
}
}
else
{
- fprintf(stderr, "wts_read_drdynvc_pdu: received Cmd %d but channel is not ready.\n", Cmd);
+ DEBUG_WARN( "wts_read_drdynvc_pdu: received Cmd %d but channel is not ready.\n", Cmd);
}
}
{
if (Stream_GetPosition(channel->receiveData) != totalSize)
{
- fprintf(stderr, "WTSProcessChannelData: read error\n");
+ DEBUG_WARN( "WTSProcessChannelData: read error\n");
}
if (channel == channel->vcm->drdynvc_channel)
{
settings->DrawGdiPlusEnabled = FALSE;
- settings->FrameMarkerCommandEnabled = FALSE;
+ settings->DrawAllowSkipAlpha = TRUE;
+ settings->DrawAllowColorSubsampling = FALSE;
+ settings->DrawAllowDynamicColorFidelity = FALSE;
+
+ settings->FrameMarkerCommandEnabled = TRUE;
settings->SurfaceFrameMarkerEnabled = TRUE;
settings->BitmapCacheV3Enabled = FALSE;
_settings->EncryptionLevel = settings->EncryptionLevel; /* 195 */
_settings->ServerRandomLength = settings->ServerRandomLength; /* 197 */
_settings->ServerCertificateLength = settings->ServerCertificateLength; /* 199 */
+ _settings->ClientRandomLength = settings->ClientRandomLength; /* 201 */
_settings->ChannelCount = settings->ChannelCount; /* 256 */
_settings->ChannelDefArraySize = settings->ChannelDefArraySize; /* 257 */
_settings->ClusterInfoFlags = settings->ClusterInfoFlags; /* 320 */
_settings->KeyboardType = settings->KeyboardType; /* 2625 */
_settings->KeyboardSubType = settings->KeyboardSubType; /* 2626 */
_settings->KeyboardFunctionKey = settings->KeyboardFunctionKey; /* 2627 */
+ _settings->KeyboardHook = settings->KeyboardHook; /* 2633 */
_settings->BrushSupportLevel = settings->BrushSupportLevel; /* 2688 */
_settings->GlyphSupportLevel = settings->GlyphSupportLevel; /* 2752 */
_settings->OffscreenSupportLevel = settings->OffscreenSupportLevel; /* 2816 */
* Manual Code
*/
+ if (_settings->ServerRandomLength)
+ {
+ _settings->ServerRandom = (BYTE*) malloc(_settings->ServerRandomLength);
+ CopyMemory(_settings->ServerRandom, settings->ServerRandom, _settings->ServerRandomLength);
+ }
+
+ if (_settings->ClientRandomLength)
+ {
+ _settings->ClientRandom = (BYTE*) malloc(_settings->ClientRandomLength);
+ CopyMemory(_settings->ClientRandom, settings->ClientRandom, _settings->ClientRandomLength);
+ }
+
_settings->ChannelCount = settings->ChannelCount;
_settings->ChannelDefArraySize = settings->ChannelDefArraySize;
_settings->ChannelDefArray = (CHANNEL_DEF*) malloc(sizeof(CHANNEL_DEF) * settings->ChannelDefArraySize);
free(settings->ClientHostname);
free(settings->ClientProductId);
free(settings->ServerRandom);
- if (settings->ClientRandom) free(settings->ClientRandom);
+ free(settings->ClientRandom);
free(settings->ServerCertificate);
free(settings->RdpKeyFile);
certificate_free(settings->RdpServerCertificate);
Stream_Read_UINT8(s, cmd->bpp);
if ((cmd->bpp < 1) || (cmd->bpp > 32))
{
- fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, cmd->bpp);
+ DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, cmd->bpp);
return FALSE;
}
#endif
+#include <freerdp/utils/debug.h>
#include <freerdp/utils/tcp.h>
#include <freerdp/utils/uds.h>
#include <winpr/stream.h>
*/
if (buf && num && !ringbuffer_write(&tcp->xmitBuffer, (const BYTE*) buf, num))
{
- fprintf(stderr, "%s: an error occured when writing(toWrite=%d)\n", __FUNCTION__, num);
+ DEBUG_WARN( "%s: an error occured when writing(toWrite=%d)\n", __FUNCTION__, num);
return -1;
}
if (ioctl(tcp->sockfd, SIOCGIFHWADDR, &if_req) != 0)
{
- fprintf(stderr, "failed to obtain MAC address\n");
+ DEBUG_WARN( "failed to obtain MAC address\n");
return;
}
memmove((void*) mac, (void*) &if_req.ifr_ifru.ifru_hwaddr.sa_data[0], 6);
#endif
- /* fprintf(stderr, "MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ /* DEBUG_WARN( "MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); */
}
return FALSE;
if (hostname[0] == '/')
+ tcp->ipcSocket = TRUE;
+
+ if (tcp->ipcSocket)
{
tcp->sockfd = freerdp_uds_connect(hostname);
if (tcp->sockfd < 0)
return FALSE;
- tcp->socketBio = BIO_new_fd(tcp->sockfd, 1);
+ tcp->socketBio = BIO_new(BIO_s_simple_socket());
if (!tcp->socketBio)
return FALSE;
+
+ BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
}
else
{
}
}
- BIO_set_close(tcp->socketBio, BIO_NOCLOSE);
+ (void)BIO_set_close(tcp->socketBio, BIO_NOCLOSE);
BIO_free(tcp->socketBio);
tcp->socketBio = BIO_new(BIO_s_simple_socket());
if (!tcp->socketBio)
- return -1;
+ return FALSE;
BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
}
option_value = 1;
option_len = sizeof(option_value);
- if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
- fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__);
+ if (!tcp->ipcSocket)
+ {
+ if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
+ fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__);
+ }
/* receive buffer must be a least 32 K */
if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
{
- fprintf(stderr, "%s: unable to set receive buffer len\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to set receive buffer len\n", __FUNCTION__);
return FALSE;
}
}
}
- if (!tcp_set_keep_alive_mode(tcp))
- return FALSE;
+ if (!tcp->ipcSocket)
+ {
+ if (!tcp_set_keep_alive_mode(tcp))
+ return FALSE;
+ }
tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());
if (flags == -1)
{
- fprintf(stderr, "%s: fcntl failed, %s.\n", __FUNCTION__, strerror(errno));
+ DEBUG_WARN( "%s: fcntl failed, %s.\n", __FUNCTION__, strerror(errno));
return FALSE;
}
else
fcntl(tcp->sockfd, F_SETFL, flags | O_NONBLOCK);
#else
- int status;
- u_long arg = blocking;
-
- status = ioctlsocket(tcp->sockfd, FIONBIO, &arg);
+ /**
+ * ioctlsocket function:
+ * msdn.microsoft.com/en-ca/library/windows/desktop/ms738573/
+ *
+ * The WSAAsyncSelect and WSAEventSelect functions automatically set a socket to nonblocking mode.
+ * If WSAAsyncSelect or WSAEventSelect has been issued on a socket, then any attempt to use
+ * ioctlsocket to set the socket back to blocking mode will fail with WSAEINVAL.
+ *
+ * To set the socket back to blocking mode, an application must first disable WSAAsyncSelect
+ * by calling WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect
+ * by calling WSAEventSelect with the lNetworkEvents parameter equal to zero.
+ */
- if (status != NO_ERROR)
- fprintf(stderr, "ioctlsocket() failed with error: %ld\n", status);
+ if (blocking == TRUE)
+ {
+ if (tcp->event)
+ WSAEventSelect(tcp->sockfd, tcp->event, 0);
+ }
+ else
+ {
+ if (!tcp->event)
+ tcp->event = WSACreateEvent();
- tcp->wsa_event = WSACreateEvent();
- WSAEventSelect(tcp->sockfd, tcp->wsa_event, FD_READ);
+ WSAEventSelect(tcp->sockfd, tcp->event, FD_READ);
+ }
#endif
return TRUE;
if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_KEEPALIVE, (void*) &option_value, option_len) < 0)
{
- perror("setsockopt() SOL_SOCKET, SO_KEEPALIVE:");
+ DEBUG_WARN("setsockopt() SOL_SOCKET, SO_KEEPALIVE:");
return FALSE;
}
if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (void*) &option_value, option_len) < 0)
{
- perror("setsockopt() IPPROTO_TCP, TCP_KEEPIDLE:");
+ DEBUG_WARN("setsockopt() IPPROTO_TCP, TCP_KEEPIDLE:");
return FALSE;
}
#endif
if (setsockopt(tcp->sockfd, SOL_TCP, TCP_KEEPCNT, (void *) &option_value, option_len) < 0)
{
- perror("setsockopt() SOL_TCP, TCP_KEEPCNT:");
+ DEBUG_WARN("setsockopt() SOL_TCP, TCP_KEEPCNT:");
return FALSE;
}
#endif
if (setsockopt(tcp->sockfd, SOL_TCP, TCP_KEEPINTVL, (void *) &option_value, option_len) < 0)
{
- perror("setsockopt() SOL_TCP, TCP_KEEPINTVL:");
+ DEBUG_WARN("setsockopt() SOL_TCP, TCP_KEEPINTVL:");
return FALSE;
}
#endif
option_len = sizeof(option_value);
if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *) &option_value, option_len) < 0)
{
- perror("setsockopt() SOL_SOCKET, SO_NOSIGPIPE:");
+ DEBUG_WARN("setsockopt() SOL_SOCKET, SO_NOSIGPIPE:");
}
#endif
return TRUE;
if (!tcp)
return NULL;
-#ifndef _WIN32
return tcp->event;
-#else
- return (HANDLE) tcp->wsa_event;
-#endif
}
-
int tcp_wait_read(rdpTcp* tcp, DWORD dwMilliSeconds)
{
int status;
struct rdp_tcp
{
int sockfd;
+ BOOL ipcSocket;
char ip_address[32];
BYTE mac_address[6];
rdpSettings* settings;
-#ifdef _WIN32
- WSAEVENT wsa_event;
-#endif
BIO* socketBio;
BIO* bufferedBio;
RingBuffer xmitBuffer;
#include <stdio.h>
#include <winpr/print.h>
+#include <freerdp/utils/debug.h>
+
#include "tpdu.h"
/**
if (code != X224_TPDU_CONNECTION_REQUEST)
{
- fprintf(stderr, "Error: expected X224_TPDU_CONNECTION_REQUEST\n");
+ DEBUG_WARN( "Error: expected X224_TPDU_CONNECTION_REQUEST\n");
return FALSE;
}
if (code != X224_TPDU_CONNECTION_CONFIRM)
{
- fprintf(stderr, "Error: expected X224_TPDU_CONNECTION_CONFIRM\n");
+ DEBUG_WARN( "Error: expected X224_TPDU_CONNECTION_CONFIRM: 0x%02X\n", code);
return FALSE;
}
/*
*/
bytes_read = (Stream_GetPosition(s) - position) - 1;
- return (Stream_GetRemainingLength(s) >= (*li - bytes_read));
+ return (Stream_GetRemainingLength(s) >= (size_t) (*li - bytes_read));
}
/**
#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>
#include "transport.h"
#include "rdp.h"
+#define TAG FREERDP_TAG("core")
#define BUFFER_SIZE 16384
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;
}
{
SetEvent(transport->stopEvent);
WaitForSingleObject(transport->thread, INFINITE);
-
CloseHandle(transport->thread);
CloseHandle(transport->stopEvent);
-
transport->thread = NULL;
transport->stopEvent = NULL;
}
return FALSE;
transport_stop(transport);
-
BIO_free_all(transport->frontBio);
-
transport->frontBio = 0;
return status;
}
BOOL transport_connect_rdp(rdpTransport* transport)
{
/* RDP encryption */
-
return TRUE;
}
{
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)
{
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)
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;
{
transport->TsgTls = tls_new(transport->settings);
transport->layer = TRANSPORT_LAYER_TSG_TLS;
-
targetTls = transport->TsgTls;
targetBio = transport->frontBio;
}
targetTls = transport->TlsIn;
targetBio = transport->TcpIn->bufferedBio;
-
transport->layer = TRANSPORT_LAYER_TLS;
}
-
targetTls->hostname = settings->ServerHostname;
targetTls->port = settings->ServerPort;
targetTls->port = 3389;
targetTls->isGatewayTransport = FALSE;
-
tls_status = tls_connect(targetTls, targetBio);
if (tls_status < 1)
}
transport->frontBio = targetTls->bio;
+
if (!transport->frontBio)
{
- fprintf(stderr, "%s: unable to prepend a filtering TLS bio", __FUNCTION__);
+ DEBUG_WARN("%s: unable to prepend a filtering TLS bio", __FUNCTION__);
return FALSE;
}
{
freerdp* instance;
rdpSettings* settings;
- rdpCredssp *credSsp;
-
+ rdpCredssp* credSsp;
settings = transport->settings;
instance = (freerdp*) settings->instance;
if (!transport->credssp)
{
transport->credssp = credssp_new(instance, transport, settings);
+
if (!transport->credssp)
return FALSE;
{
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)
freerdp_set_last_error(instance->context, FREERDP_ERROR_AUTHENTICATION_FAILED);
}
- fprintf(stderr, "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;
}
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)
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)
}
transport->TlsOut->isGatewayTransport = TRUE;
-
tls_status = tls_connect(transport->TlsOut, transport->TcpOut->bufferedBio);
if (tls_status < 1)
transport->frontBio = BIO_new(BIO_s_tsg());
transport->frontBio->ptr = tsg;
-
return TRUE;
}
{
BOOL status = FALSE;
rdpSettings* settings = transport->settings;
-
transport->async = settings->AsyncTransport;
if (transport->GatewayEnabled)
else
{
status = tcp_connect(transport->TcpIn, hostname, port, timeout);
-
transport->SplitInputOutput = FALSE;
transport->TcpOut = transport->TcpIn;
transport->frontBio = transport->TcpIn->bufferedBio;
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);
}
}
BOOL transport_accept_rdp(rdpTransport* transport)
{
/* RDP encryption */
-
return TRUE;
}
{
freerdp* instance;
rdpSettings* settings;
-
settings = transport->settings;
instance = (freerdp*) settings->instance;
if (!tls_accept(transport->TlsIn, transport->TcpIn->bufferedBio, settings->CertificateFile, settings->PrivateKeyFile))
return FALSE;
+
transport->frontBio = transport->TlsIn->bio;
/* Network Level Authentication */
if (credssp_authenticate(transport->credssp) < 0)
{
- fprintf(stderr, "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)
{
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);
* requested bytes */
if (transport_wait_for_read(transport) < 0)
{
- fprintf(stderr, "%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;
}
{
int status;
status = transport_read_layer(transport, Stream_Pointer(s), toRead);
+
if (status <= 0)
return status;
int status;
int position;
int pduLength;
- BYTE *header;
-
+ BYTE* header;
position = 0;
pduLength = 0;
return -1;
position = Stream_GetPosition(s);
-
/* Make sure there is enough space for the longest header within the stream */
Stream_EnsureCapacity(s, 4);
{
if ((status = transport_read_layer_bytes(transport, s, 1)) != 1)
return status;
+
pduLength = header[2];
pduLength += 3;
}
{
if ((status = transport_read_layer_bytes(transport, s, 2)) != 1)
return status;
+
pduLength = (header[2] << 8) | header[3];
pduLength += 4;
}
else
{
- fprintf(stderr, "Error reading TSRequest!\n");
+ DEBUG_WARN("Error reading TSRequest!\n");
return -1;
}
}
/* min and max values according to ITU-T Rec. T.123 (01/2007) section 8 */
if (pduLength < 7 || pduLength > 0xFFFF)
{
- fprintf(stderr, "%s: tpkt - invalid pduLength: %d\n", __FUNCTION__, pduLength);
+ DEBUG_WARN("%s: tpkt - invalid pduLength: %d\n", __FUNCTION__, pduLength);
return -1;
}
}
{
if ((status = transport_read_layer_bytes(transport, s, 1)) != 1)
return status;
+
pduLength = ((header[1] & 0x7F) << 8) | header[2];
}
else
*/
if (pduLength < 3 || pduLength > 0x8000)
{
- fprintf(stderr, "%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)
{
- fprintf(stderr, "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)
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)
{
- fprintf(stderr, "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)
if (transport_wait_for_write(transport) < 0)
{
- fprintf(stderr, "%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)
{
- fprintf(stderr, "%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))
{
- fprintf(stderr, "%s: error when draining outputBuffer\n", __FUNCTION__);
+ DEBUG_WARN("%s: error when draining outputBuffer\n", __FUNCTION__);
return -1;
}
}
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->wsa_event;
+ rfds[*rcount] = transport->TcpIn->event;
(*rcount)++;
if (transport->SplitInputOutput)
{
- rfds[*rcount] = transport->TcpOut->wsa_event;
+ rfds[*rcount] = transport->TcpOut->event;
(*rcount)++;
}
+
#else
rfds[*rcount] = (void*)(long)(transport->TcpIn->sockfd);
(*rcount)++;
rfds[*rcount] = (void*)(long)(transport->TcpOut->sockfd);
(*rcount)++;
}
-#endif
+#endif
pfd = GetEventWaitObject(transport->ReceiveEvent);
if (pfd)
return TRUE;
return transport->SplitInputOutput &&
- transport->TcpOut &&
- transport->TcpOut->writeBlocked;
+ transport->TcpOut &&
+ transport->TcpOut->writeBlocked;
}
int tranport_drain_output_buffer(rdpTransport* transport)
{
if (!transport_bio_buffered_drain(transport->TcpIn->bufferedBio))
return -1;
+
ret |= transport->TcpIn->writeBlocked;
}
{
if (!transport_bio_buffered_drain(transport->TcpOut->bufferedBio))
return -1;
+
ret |= transport->TcpOut->writeBlocked;
}
return -1;
#ifdef _WIN32
- WSAResetEvent(transport->TcpIn->wsa_event);
+ WSAResetEvent(transport->TcpIn->event);
#endif
ResetEvent(transport->ReceiveEvent);
* 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;
* 0: success
* 1: redirection
*/
-
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
+ Stream_Release(received);
- if (recv_status == 1)
+ /* session redirection or activation */
+ if (recv_status == 1 || recv_status == 2)
{
- return 1; /* session redirection */
+ return recv_status;
}
- Stream_Release(received);
if (recv_status < 0)
return -1;
BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking)
{
BOOL status;
-
status = TRUE;
transport->blocking = blocking;
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");
{
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)
if (!freerdp_check_fds(instance))
{
-
}
}
}
WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread");
-
ExitThread(0);
return NULL;
}
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;
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:
Stream_Release(transport->ReceiveBuffer);
StreamPool_Free(transport->ReceivePool);
-
CloseHandle(transport->ReceiveEvent);
CloseHandle(transport->connectedEvent);
transport->TcpIn = NULL;
transport->TcpOut = NULL;
-
tsg_free(transport->tsg);
transport->tsg = NULL;
-
DeleteCriticalSection(&(transport->ReadLock));
DeleteCriticalSection(&(transport->WriteLock));
-
free(transport);
}
Stream_Read_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */
+ WLog_Print(update->log, WLOG_DEBUG, "BitmapUpdate: %d", bitmapUpdate->number);
+
if (bitmapUpdate->number > bitmapUpdate->count)
{
UINT16 count;
scanlineSize = ((scanlineSize + 1) / 2) * 2;
if (scanlineSize * pointer_color->height != pointer_color->lengthXorMask)
{
- fprintf(stderr, "%s: invalid lengthXorMask: width=%d height=%d, %d instead of %d\n", __FUNCTION__,
+ DEBUG_WARN( "%s: invalid lengthXorMask: width=%d height=%d, %d instead of %d\n", __FUNCTION__,
pointer_color->width, pointer_color->height,
pointer_color->lengthXorMask, scanlineSize * pointer_color->height);
return FALSE;
scanlineSize = ((1 + scanlineSize) / 2) * 2;
if (scanlineSize * pointer_color->height != pointer_color->lengthAndMask)
{
- fprintf(stderr, "%s: invalid lengthAndMask: %d instead of %d\n", __FUNCTION__,
+ DEBUG_WARN( "%s: invalid lengthAndMask: %d instead of %d\n", __FUNCTION__,
pointer_color->lengthAndMask, scanlineSize * pointer_color->height);
return FALSE;
}
Stream_Read_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */
if ((pointer_new->xorBpp < 1) || (pointer_new->xorBpp > 32))
{
- fprintf(stderr, "%s: invalid xorBpp %d\n", __FUNCTION__, pointer_new->xorBpp);
+ DEBUG_WARN( "%s: invalid xorBpp %d\n", __FUNCTION__, pointer_new->xorBpp);
return FALSE;
}
return update_read_pointer_color(s, &pointer_new->colorPtrAttr, pointer_new->xorBpp); /* colorPtrAttr */
Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */
- //printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]);
+ //DEBUG_MSG("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]);
IFCALL(update->BeginPaint, context);
update->initialState = FALSE;
}
+void update_post_disconnect(rdpUpdate* update)
+{
+ update->asynchronous = update->context->settings->AsyncUpdate;
+
+ if (update->asynchronous)
+ update_message_proxy_free(update->proxy);
+}
+
static void update_begin_paint(rdpContext* context)
{
wStream* s;
if (update->numberOrders > 0)
{
- fprintf(stderr, "%s: sending %d orders\n", __FUNCTION__, update->numberOrders);
+ DEBUG_WARN( "%s: sending %d orders\n", __FUNCTION__, update->numberOrders);
fastpath_send_update_pdu(context->rdp->fastpath, FASTPATH_UPDATETYPE_ORDERS, s);
}
free(update->altsec);
free(update->window);
- if (update->asynchronous)
- update_message_proxy_free(update->proxy);
-
MessageQueue_Free(update->queue);
free(update);
void update_reset_state(rdpUpdate* update);
void update_post_connect(rdpUpdate* update);
+void update_post_disconnect(rdpUpdate* update);
BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmapUpdate);
BOOL update_read_palette(rdpUpdate* update, wStream* s, PALETTE_UPDATE* palette_update);
Stream_Read_UINT8(s, iconInfo->bpp); /* bpp (1 byte) */
if ((iconInfo->bpp < 1) || (iconInfo->bpp > 32))
{
- fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, iconInfo->bpp);
+ DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, iconInfo->bpp);
return FALSE;
}
#include <stdio.h>
#include <winpr/crt.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/crypto/ber.h>
BOOL ber_read_length(wStream* s, int* length)
}
else if (length == 8)
{
- fprintf(stderr, "%s: should implement reading an 8 bytes integer\n", __FUNCTION__);
+ DEBUG_WARN( "%s: should implement reading an 8 bytes integer\n", __FUNCTION__);
return FALSE;
}
else
{
- fprintf(stderr, "%s: should implement reading an integer with length=%d\n", __FUNCTION__, length);
+ DEBUG_WARN( "%s: should implement reading an integer with length=%d\n", __FUNCTION__, length);
return FALSE;
}
static const char certificate_server_dir[] = "server";
static const char certificate_known_hosts_file[] = "known_hosts";
+#include <freerdp/utils/debug.h>
#include <freerdp/crypto/certificate.h>
-void certificate_store_init(rdpCertificateStore* certificate_store)
+int certificate_store_init(rdpCertificateStore* certificate_store)
{
char* server_path;
rdpSettings* settings;
if (!PathFileExistsA(settings->ConfigPath))
{
CreateDirectoryA(settings->ConfigPath, 0);
- fprintf(stderr, "creating directory %s\n", settings->ConfigPath);
+ DEBUG_WARN( "creating directory %s\n", settings->ConfigPath);
}
certificate_store->path = GetCombinedPath(settings->ConfigPath, (char*) certificate_store_dir);
+ if (!certificate_store->path)
+ return -1;
+
if (!PathFileExistsA(certificate_store->path))
{
CreateDirectoryA(certificate_store->path, 0);
- fprintf(stderr, "creating directory %s\n", certificate_store->path);
+ DEBUG_WARN( "creating directory %s\n", certificate_store->path);
}
server_path = GetCombinedPath(settings->ConfigPath, (char*) certificate_server_dir);
+ if (!server_path)
+ return -1;
+
if (!PathFileExistsA(server_path))
{
CreateDirectoryA(server_path, 0);
- fprintf(stderr, "creating directory %s\n", server_path);
+ DEBUG_WARN( "creating directory %s\n", server_path);
}
free(server_path);
certificate_store->file = GetCombinedPath(settings->ConfigPath, (char*) certificate_known_hosts_file);
+ if (!certificate_store->file)
+ return -1;
+
if (PathFileExistsA(certificate_store->file) == FALSE)
{
certificate_store->fp = fopen((char*) certificate_store->file, "w+");
- if (certificate_store->fp == NULL)
+ if (!certificate_store->fp)
{
- fprintf(stderr, "certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
- return;
+ DEBUG_WARN( "certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
+ return -1;
}
fflush(certificate_store->fp);
{
certificate_store->fp = fopen((char*) certificate_store->file, "r+");
}
+
+ return 1;
}
int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
{
rdpCertificateStore* certificate_store;
- certificate_store = (rdpCertificateStore *)calloc(1, sizeof(rdpCertificateStore));
+ certificate_store = (rdpCertificateStore*) calloc(1, sizeof(rdpCertificateStore));
if (!certificate_store)
return NULL;
certificate_store->settings = settings;
+
certificate_store_init(certificate_store);
- /* TODO: certificate_store_init should not fail silently */
return certificate_store;
}
#include <winpr/crt.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/crypto/crypto.h>
CryptoSha1 crypto_sha1_init(void)
pkey = X509_get_pubkey(cert->px509);
if (!pkey)
{
- fprintf(stderr, "%s: X509_get_pubkey() failed\n", __FUNCTION__);
+ DEBUG_WARN( "%s: X509_get_pubkey() failed\n", __FUNCTION__);
status = FALSE;
goto exit;
}
length = i2d_PublicKey(pkey, NULL);
if (length < 1)
{
- fprintf(stderr, "%s: i2d_PublicKey() failed\n", __FUNCTION__);
+ DEBUG_WARN( "%s: i2d_PublicKey() failed\n", __FUNCTION__);
status = FALSE;
goto exit;
}
fp = crypto_cert_fingerprint(xcert);
if (!fp)
{
- fprintf(stderr, "%s: error computing fingerprint\n", __FUNCTION__);
+ DEBUG_WARN( "%s: error computing fingerprint\n", __FUNCTION__);
goto out_free_issuer;
}
- fprintf(stderr, "Certificate details:\n");
- fprintf(stderr, "\tSubject: %s\n", subject);
- fprintf(stderr, "\tIssuer: %s\n", issuer);
- fprintf(stderr, "\tThumbprint: %s\n", fp);
- fprintf(stderr, "The above X.509 certificate could not be verified, possibly because you do not have "
+ DEBUG_WARN( "Certificate details:\n");
+ DEBUG_WARN( "\tSubject: %s\n", subject);
+ DEBUG_WARN( "\tIssuer: %s\n", issuer);
+ DEBUG_WARN( "\tThumbprint: %s\n", fp);
+ DEBUG_WARN( "The above X.509 certificate could not be verified, possibly because you do not have "
"the CA certificate in your certificate store, or the certificate has expired. "
"Please look at the documentation on how to create local certificate store for a private CA.\n");
#include <freerdp/utils/tcp.h>
#include <freerdp/utils/ringbuffer.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/crypto/tls.h>
#include "../core/tcp.h"
if (!remote_cert)
{
- fprintf(stderr, "%s: failed to get the server TLS certificate\n", __FUNCTION__);
+ DEBUG_WARN( "%s: failed to get the server TLS certificate\n", __FUNCTION__);
return NULL;
}
tls->ctx = SSL_CTX_new(method);
if (!tls->ctx)
{
- fprintf(stderr, "%s: SSL_CTX_new failed\n", __FUNCTION__);
+ DEBUG_WARN( "%s: SSL_CTX_new failed\n", __FUNCTION__);
return FALSE;
}
if (tls->settings->PermittedTLSCiphers) {
if(!SSL_CTX_set_cipher_list(tls->ctx, tls->settings->PermittedTLSCiphers)) {
- fprintf(stderr, "SSL_CTX_set_cipher_list %s failed\n", tls->settings->PermittedTLSCiphers);
+ DEBUG_WARN( "SSL_CTX_set_cipher_list %s failed\n", tls->settings->PermittedTLSCiphers);
return FALSE;
}
}
if (BIO_get_ssl(tls->bio, &tls->ssl) < 0)
{
- fprintf(stderr, "%s: unable to retrieve the SSL of the connection\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to retrieve the SSL of the connection\n", __FUNCTION__);
return FALSE;
}
if (fd < 0)
{
- fprintf(stderr, "%s: unable to retrieve BIO fd\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to retrieve BIO fd\n", __FUNCTION__);
return -1;
}
#endif
if (status < 0)
{
- fprintf(stderr, "%s: error during select()\n", __FUNCTION__);
+ DEBUG_WARN( "%s: error during select()\n", __FUNCTION__);
return -1;
}
}
cert = tls_get_certificate(tls, clientMode);
if (!cert)
{
- fprintf(stderr, "%s: tls_get_certificate failed to return the server certificate.\n", __FUNCTION__);
+ DEBUG_WARN( "%s: tls_get_certificate failed to return the server certificate.\n", __FUNCTION__);
return -1;
}
tls->Bindings = tls_get_channel_bindings(cert->px509);
if (!tls->Bindings)
{
- fprintf(stderr, "%s: unable to retrieve bindings\n", __FUNCTION__);
+ DEBUG_WARN( "%s: unable to retrieve bindings\n", __FUNCTION__);
verify_status = -1;
goto out;
}
if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength))
{
- fprintf(stderr, "%s: crypto_cert_get_public_key failed to return the server public key.\n", __FUNCTION__);
+ DEBUG_WARN( "%s: crypto_cert_get_public_key failed to return the server public key.\n", __FUNCTION__);
verify_status = -1;
goto out;
}
if (verify_status < 1)
{
- fprintf(stderr, "%s: certificate not trusted, aborting.\n", __FUNCTION__);
+ DEBUG_WARN( "%s: certificate not trusted, aborting.\n", __FUNCTION__);
tls_disconnect(tls);
verify_status = 0;
}
if (SSL_use_RSAPrivateKey_file(tls->ssl, privatekey_file, SSL_FILETYPE_PEM) <= 0)
{
- fprintf(stderr, "%s: SSL_CTX_use_RSAPrivateKey_file failed\n", __FUNCTION__);
- fprintf(stderr, "PrivateKeyFile: %s\n", privatekey_file);
+ DEBUG_WARN( "%s: SSL_CTX_use_RSAPrivateKey_file failed\n", __FUNCTION__);
+ DEBUG_WARN( "PrivateKeyFile: %s\n", privatekey_file);
return FALSE;
}
if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0)
{
- fprintf(stderr, "%s: SSL_use_certificate_file failed\n", __FUNCTION__);
+ DEBUG_WARN( "%s: SSL_use_certificate_file failed\n", __FUNCTION__);
return FALSE;
}
if (!bufferedBio)
{
- fprintf(stderr, "%s: error unable to retrieve the bufferedBio in the BIO chain\n", __FUNCTION__);
+ DEBUG_WARN( "%s: error unable to retrieve the bufferedBio in the BIO chain\n", __FUNCTION__);
return -1;
}
}
else
{
- fprintf(stderr, "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__);
+ DEBUG_WARN( "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__);
USleep(10);
continue;
}
}
else
{
- fprintf(stderr, "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__);
+ DEBUG_WARN( "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__);
USleep(10);
continue;
}
if (!bio)
{
- fprintf(stderr, "%s: BIO_new() failure\n", __FUNCTION__);
+ DEBUG_WARN( "%s: BIO_new() failure\n", __FUNCTION__);
return -1;
}
if (status < 0)
{
- fprintf(stderr, "%s: PEM_write_bio_X509 failure: %d\n", __FUNCTION__, status);
+ DEBUG_WARN( "%s: PEM_write_bio_X509 failure: %d\n", __FUNCTION__, status);
return -1;
}
if (status < 0)
{
- fprintf(stderr, "%s: failed to read certificate\n", __FUNCTION__);
+ DEBUG_WARN( "%s: failed to read certificate\n", __FUNCTION__);
return -1;
}
if (status < 0)
{
- fprintf(stderr, "%s: failed to read certificate\n", __FUNCTION__);
+ DEBUG_WARN( "%s: failed to read certificate\n", __FUNCTION__);
return -1;
}
status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, tls->isGatewayTransport);
}
- fprintf(stderr, "%s: (length = %d) status: %d\n%s\n", __FUNCTION__, length, status, pemCert);
+ DEBUG_WARN( "%s: (length = %d) status: %d\n%s\n", __FUNCTION__, length, status, pemCert);
free(pemCert);
BIO_free(bio);
void tls_print_certificate_error(char* hostname, char* fingerprint, char *hosts_file)
{
- fprintf(stderr, "The host key for %s has changed\n", hostname);
- fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
- fprintf(stderr, "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\n");
- fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
- fprintf(stderr, "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n");
- fprintf(stderr, "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n");
- fprintf(stderr, "It is also possible that a host key has just been changed.\n");
- fprintf(stderr, "The fingerprint for the host key sent by the remote host is\n%s\n", fingerprint);
- fprintf(stderr, "Please contact your system administrator.\n");
- fprintf(stderr, "Add correct host key in %s to get rid of this message.\n", hosts_file);
- fprintf(stderr, "Host key for %s has changed and you have requested strict checking.\n", hostname);
- fprintf(stderr, "Host key verification failed.\n");
+ DEBUG_WARN( "The host key for %s has changed\n", hostname);
+ DEBUG_WARN( "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+ DEBUG_WARN( "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\n");
+ DEBUG_WARN( "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+ DEBUG_WARN( "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n");
+ DEBUG_WARN( "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n");
+ DEBUG_WARN( "It is also possible that a host key has just been changed.\n");
+ DEBUG_WARN( "The fingerprint for the host key sent by the remote host is\n%s\n", fingerprint);
+ DEBUG_WARN( "Please contact your system administrator.\n");
+ DEBUG_WARN( "Add correct host key in %s to get rid of this message.\n", hosts_file);
+ DEBUG_WARN( "Host key for %s has changed and you have requested strict checking.\n", hostname);
+ DEBUG_WARN( "Host key verification failed.\n");
}
void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count)
assert(NULL != hostname);
- fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
- fprintf(stderr, "@ WARNING: CERTIFICATE NAME MISMATCH! @\n");
- fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
- fprintf(stderr, "The hostname used for this connection (%s) \n", hostname);
- fprintf(stderr, "does not match %s given in the certificate:\n", alt_names_count < 1 ? "the name" : "any of the names");
- fprintf(stderr, "Common Name (CN):\n");
- fprintf(stderr, "\t%s\n", common_name ? common_name : "no CN found in certificate");
+ DEBUG_WARN( "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+ DEBUG_WARN( "@ WARNING: CERTIFICATE NAME MISMATCH! @\n");
+ DEBUG_WARN( "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+ DEBUG_WARN( "The hostname used for this connection (%s) \n", hostname);
+ DEBUG_WARN( "does not match %s given in the certificate:\n", alt_names_count < 1 ? "the name" : "any of the names");
+ DEBUG_WARN( "Common Name (CN):\n");
+ DEBUG_WARN( "\t%s\n", common_name ? common_name : "no CN found in certificate");
if (alt_names_count > 0)
{
assert(NULL != alt_names);
- fprintf(stderr, "Alternative names:\n");
+ DEBUG_WARN( "Alternative names:\n");
for (index = 0; index < alt_names_count; index++)
{
assert(alt_names[index]);
- fprintf(stderr, "\t %s\n", alt_names[index]);
+ DEBUG_WARN( "\t %s\n", alt_names[index]);
}
}
- fprintf(stderr, "A valid certificate for the wrong name should NOT be trusted!\n");
+ DEBUG_WARN( "A valid certificate for the wrong name should NOT be trusted!\n");
}
rdpTls* tls_new(rdpSettings* settings)
winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
tls->settings = settings;
- tls->certificate_store = certificate_store_new(settings);
- if (!tls->certificate_store)
- goto out_free;
+ if (!settings->ServerMode)
+ {
+ tls->certificate_store = certificate_store_new(settings);
+
+ if (!tls->certificate_store)
+ goto out_free;
+ }
tls->alertLevel = TLS_ALERT_LEVEL_WARNING;
tls->alertDescription = TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY;
tls->Bindings = NULL;
}
- certificate_store_free(tls->certificate_store);
- tls->certificate_store = NULL;
+ if (tls->certificate_store)
+ {
+ certificate_store_free(tls->certificate_store);
+ tls->certificate_store = NULL;
+ }
free(tls);
}
if (hdcSrc->bytesPerPixel != 1)
{
- fprintf(stderr, "BitBlt_DSPDxax expects 1 bpp, unimplemented for %d\n", hdcSrc->bytesPerPixel);
+ DEBUG_WARN( "BitBlt_DSPDxax expects 1 bpp, unimplemented for %d\n", hdcSrc->bytesPerPixel);
return 0;
}
break;
}
- fprintf(stderr, "BitBlt: unknown rop: 0x%08X\n", rop);
+ DEBUG_WARN( "BitBlt: unknown rop: 0x%08X\n", rop);
return 1;
}
break;
}
- fprintf(stderr, "PatBlt: unknown rop: 0x%08X\n", rop);
+ DEBUG_WARN( "PatBlt: unknown rop: 0x%08X\n", rop);
return 1;
}
break;
}
- fprintf(stderr, "BitBlt: unknown rop: 0x%08X\n", rop);
+ DEBUG_WARN( "BitBlt: unknown rop: 0x%08X\n", rop);
return 1;
}
break;
}
- fprintf(stderr, "PatBlt: unknown rop: 0x%08X\n", rop);
+ DEBUG_WARN( "PatBlt: unknown rop: 0x%08X\n", rop);
return 1;
}
break;
}
- fprintf(stderr, "BitBlt: unknown rop: 0x%08X\n", rop);
+ DEBUG_WARN( "BitBlt: unknown rop: 0x%08X\n", rop);
return 1;
}
break;
}
- fprintf(stderr, "PatBlt: unknown rop: 0x%08X\n", rop);
+ DEBUG_WARN( "PatBlt: unknown rop: 0x%08X\n", rop);
return 1;
}
#include <stdlib.h>
#include <winpr/crt.h>
+#include <winpr/image.h>
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/constants.h>
-#include <freerdp/utils/bitmap.h>
#include <freerdp/codec/color.h>
#include <freerdp/codec/bitmap.h>
#include <freerdp/codec/rfx.h>
}
else
{
- fprintf(stderr, "gdi_get_bitmap_pointer: requesting invalid pointer: (%d,%d) in %dx%d\n", x, y, hBmp->width, hBmp->height);
+ DEBUG_WARN( "gdi_get_bitmap_pointer: requesting invalid pointer: (%d,%d) in %dx%d\n", x, y, hBmp->width, hBmp->height);
return 0;
}
}
}
else
{
- fprintf(stderr, "unimplemented brush style:%d\n", brush->style);
+ DEBUG_WARN( "unimplemented brush style:%d\n", brush->style);
}
gdi_SetTextColor(gdi->drawing->hdc, originalColor);
}
else
{
- fprintf(stderr, "Mem3Blt unimplemented brush style:%d\n", brush->style);
+ DEBUG_WARN( "Mem3Blt unimplemented brush style:%d\n", brush->style);
}
gdi_SetTextColor(gdi->drawing->hdc, originalColor);
void gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
{
- fprintf(stderr, "PolygonSC\n");
+ DEBUG_WARN( "PolygonSC\n");
}
void gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
{
- fprintf(stderr, "PolygonCB\n");
+ DEBUG_WARN( "PolygonCB\n");
}
void gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
{
- fprintf(stderr, "EllipseSC\n");
+ DEBUG_WARN( "EllipseSC\n");
}
void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
{
- fprintf(stderr, "EllipseCB\n");
+ DEBUG_WARN( "EllipseCB\n");
+}
+
+void gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker)
+{
+
}
void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
int tilenum = 0;
-void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
+void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
{
int i, j;
int tx, ty;
char* tile_bitmap;
RFX_MESSAGE* message;
rdpGdi* gdi = context->gdi;
- RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) gdi->rfx_context;
- NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) gdi->nsc_context;
DEBUG_GDI("destLeft %d destTop %d destRight %d destBottom %d "
"bpp %d codecID %d width %d height %d length %d",
- surface_bits_command->destLeft, surface_bits_command->destTop,
- surface_bits_command->destRight, surface_bits_command->destBottom,
- surface_bits_command->bpp, surface_bits_command->codecID,
- surface_bits_command->width, surface_bits_command->height,
- surface_bits_command->bitmapDataLength);
+ cmd->destLeft, cmd->destTop,
+ cmd->destRight, cmd->destBottom,
+ cmd->bpp, cmd->codecID,
+ cmd->width, cmd->height,
+ cmd->bitmapDataLength);
tile_bitmap = (char*) _aligned_malloc(32, 16);
if (!tile_bitmap)
return;
- if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX)
+ if (cmd->codecID == RDP_CODEC_ID_REMOTEFX)
{
- message = rfx_process_message(rfx_context,
- surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
+ freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX);
+
+ message = rfx_process_message(gdi->codecs->rfx,
+ cmd->bitmapData, cmd->bitmapDataLength);
DEBUG_GDI("num_rects %d num_tiles %d", message->numRects, message->numTiles);
/* blit each tile */
for (i = 0; i < message->numTiles; i++)
{
- 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;
freerdp_image_convert(message->tiles[i]->data, gdi->tile->bitmap->data, 64, 64, 32, 32, gdi->clrconv);
-#ifdef DUMP_REMOTEFX_TILES
- sprintf(tile_bitmap, "/tmp/rfx/tile_%d.bmp", tilenum++);
- freerdp_bitmap_write(tile_bitmap, gdi->tile->bitmap->data, 64, 64, 32);
-#endif
-
-
for (j = 0; j < message->numRects; j++)
{
gdi_SetClipRgn(gdi->primary->hdc,
- surface_bits_command->destLeft + message->rects[j].x,
- surface_bits_command->destTop + message->rects[j].y,
+ cmd->destLeft + message->rects[j].x,
+ cmd->destTop + message->rects[j].y,
message->rects[j].width, message->rects[j].height);
gdi_BitBlt(gdi->primary->hdc, tx, ty, 64, 64, gdi->tile->hdc, 0, 0, GDI_SRCCOPY);
}
gdi_SetNullClipRgn(gdi->primary->hdc);
- rfx_message_free(rfx_context, message);
+ rfx_message_free(gdi->codecs->rfx, message);
}
- else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC)
+ else if (cmd->codecID == RDP_CODEC_ID_NSCODEC)
{
- nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
- surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
- gdi->image->bitmap->width = surface_bits_command->width;
- gdi->image->bitmap->height = surface_bits_command->height;
- gdi->image->bitmap->bitsPerPixel = surface_bits_command->bpp;
+ freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_NSCODEC);
+
+ nsc_process_message(gdi->codecs->nsc, cmd->bpp, cmd->width, cmd->height,
+ cmd->bitmapData, cmd->bitmapDataLength);
+ gdi->image->bitmap->width = cmd->width;
+ gdi->image->bitmap->height = cmd->height;
+ gdi->image->bitmap->bitsPerPixel = cmd->bpp;
gdi->image->bitmap->bytesPerPixel = gdi->image->bitmap->bitsPerPixel / 8;
gdi->image->bitmap->data = (BYTE*) _aligned_realloc(gdi->image->bitmap->data, gdi->image->bitmap->width * gdi->image->bitmap->height * 4, 16);
- freerdp_image_convert(nsc_context->BitmapData, gdi->image->bitmap->data,
- surface_bits_command->width, surface_bits_command->height,
- surface_bits_command->bpp, gdi->dstBpp, gdi->clrconv);
+ freerdp_image_convert(gdi->codecs->nsc->BitmapData, gdi->image->bitmap->data,
+ cmd->width, cmd->height,
+ cmd->bpp, gdi->dstBpp, gdi->clrconv);
freerdp_image_flip(gdi->image->bitmap->data, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, gdi->dstBpp);
- gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY);
+ gdi_BitBlt(gdi->primary->hdc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY);
}
- else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE)
+ else if (cmd->codecID == RDP_CODEC_ID_NONE)
{
- gdi->image->bitmap->width = surface_bits_command->width;
- gdi->image->bitmap->height = surface_bits_command->height;
- gdi->image->bitmap->bitsPerPixel = surface_bits_command->bpp;
+ gdi->image->bitmap->width = cmd->width;
+ gdi->image->bitmap->height = cmd->height;
+ gdi->image->bitmap->bitsPerPixel = cmd->bpp;
gdi->image->bitmap->bytesPerPixel = gdi->image->bitmap->bitsPerPixel / 8;
gdi->image->bitmap->data = (BYTE*) _aligned_realloc(gdi->image->bitmap->data,
gdi->image->bitmap->width * gdi->image->bitmap->height * 4, 16);
- if ((surface_bits_command->bpp != 32) || (gdi->clrconv->alpha == TRUE))
+ if ((cmd->bpp != 32) || (gdi->clrconv->alpha))
{
BYTE* temp_image;
- freerdp_image_convert(surface_bits_command->bitmapData, gdi->image->bitmap->data,
+ freerdp_image_convert(cmd->bitmapData, gdi->image->bitmap->data,
gdi->image->bitmap->width, gdi->image->bitmap->height,
gdi->image->bitmap->bitsPerPixel, 32, gdi->clrconv);
- surface_bits_command->bpp = 32;
- surface_bits_command->bitmapData = gdi->image->bitmap->data;
+ cmd->bpp = 32;
+ cmd->bitmapData = gdi->image->bitmap->data;
temp_image = (BYTE*) _aligned_malloc(gdi->image->bitmap->width * gdi->image->bitmap->height * 4, 16);
freerdp_image_flip(gdi->image->bitmap->data, temp_image, gdi->image->bitmap->width, gdi->image->bitmap->height, 32);
}
else
{
- freerdp_image_flip(surface_bits_command->bitmapData, gdi->image->bitmap->data,
+ freerdp_image_flip(cmd->bitmapData, gdi->image->bitmap->data,
gdi->image->bitmap->width, gdi->image->bitmap->height, 32);
}
- gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
- surface_bits_command->width, surface_bits_command->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY);
+ gdi_BitBlt(gdi->primary->hdc, cmd->destLeft, cmd->destTop,
+ cmd->width, cmd->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY);
}
else
{
- fprintf(stderr, "Unsupported codecID %d\n", surface_bits_command->codecID);
+ DEBUG_WARN( "Unsupported codecID %d\n", cmd->codecID);
}
if (tile_bitmap)
update->SurfaceBits = gdi_surface_bits;
update->SurfaceFrameMarker = gdi_surface_frame_marker;
+
+ update->altsec->FrameMarker = gdi_frame_marker;
}
void gdi_init_primary(rdpGdi* gdi)
gdi->width = width;
gdi->height = height;
gdi_bitmap_free_ex(gdi->primary);
+ gdi->primary_buffer = NULL;
gdi_init_primary(gdi);
}
}
instance->context->gdi = gdi;
cache = instance->context->cache;
+ gdi->codecs = instance->context->codecs;
gdi->width = instance->settings->DesktopWidth;
gdi->height = instance->settings->DesktopHeight;
gdi->srcBpp = instance->settings->ColorDepth;
gdi_register_graphics(instance->context->graphics);
- gdi->rfx_context = rfx_context_new(FALSE);
- gdi->nsc_context = nsc_context_new();
-
return 0;
}
gdi_bitmap_free_ex(gdi->tile);
gdi_bitmap_free_ex(gdi->image);
gdi_DeleteDC(gdi->hdc);
- rfx_context_free((RFX_CONTEXT*) gdi->rfx_context);
- nsc_context_free((NSC_CONTEXT*) gdi->nsc_context);
free(gdi->clrconv->palette);
free(gdi->clrconv);
free(gdi);
BYTE* data, int width, int height, int bpp, int length,
BOOL compressed, int codecId)
{
- BOOL status;
+ int status;
UINT16 size;
BYTE* src;
BYTE* dst;
rdpGdi* gdi;
RFX_MESSAGE* msg;
+ gdi = context->gdi;
+
size = width * height * ((bpp + 7) / 8);
if (!bitmap->data)
switch (codecId)
{
case RDP_CODEC_ID_NSCODEC:
- gdi = context->gdi;
- nsc_process_message(gdi->nsc_context, bpp, width, height, data, length);
- freerdp_image_flip(((NSC_CONTEXT*) gdi->nsc_context)->BitmapData, bitmap->data, width, height, bpp);
+ 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;
case RDP_CODEC_ID_REMOTEFX:
- gdi = context->gdi;
- rfx_context_set_pixel_format(gdi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
- msg = rfx_process_message(gdi->rfx_context, data, length);
+ 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);
+
if (!msg)
{
- fprintf(stderr, "gdi_Bitmap_Decompress: rfx Decompression Failed\n");
+ DEBUG_WARN( "gdi_Bitmap_Decompress: rfx Decompression Failed\n");
}
else
{
{
src = msg->tiles[0]->data + yindex * 64 * 4;
dst = bitmap->data + yindex * width * 3;
+
for (xindex = 0; xindex < width; xindex++)
{
*(dst++) = *(src++);
src++;
}
}
- rfx_message_free(gdi->rfx_context, msg);
+ 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))
{
- fprintf(stderr, "gdi_Bitmap_Decompress: jpeg Decompression Failed\n");
+ DEBUG_WARN( "gdi_Bitmap_Decompress: jpeg Decompression Failed\n");
}
#endif
break;
default:
if (compressed)
{
- status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
+ BYTE* pDstData;
+ UINT32 SrcSize;
+
+ 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)
+ if (status < 0)
+ {
+ DEBUG_WARN("gdi_Bitmap_Decompress: Bitmap Decompression Failed\n");
+ }
+ }
+ else
{
- fprintf(stderr, "gdi_Bitmap_Decompress: Bitmap Decompression Failed\n");
+ 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
return tzid;
}
- fprintf(stderr, "Unable to detect time zone\n");
+ DEBUG_WARN( "Unable to detect time zone\n");
return tzid;
#else
return 0;
}
}
- fprintf(stderr, "Unable to find a match for unix timezone: %s\n", tzid);
+ DEBUG_WARN( "Unable to find a match for unix timezone: %s\n", tzid);
free(tzid);
return NULL;
}
{
if ((rules[i].TicksStart >= windows_time) && (windows_time >= rules[i].TicksEnd))
{
- /*fprintf(stderr, "Got rule %d from table at %p with count %u\n", i, rules, count);*/
+ /*DEBUG_WARN( "Got rule %d from table at %p with count %u\n", i, rules, count);*/
return &rules[i];
}
}
- fprintf(stderr, "Unable to get current timezone rule\n");
+ DEBUG_WARN( "Unable to get current timezone rule\n");
return NULL;
}
prim_set.c
prim_shift.c
prim_sign.c
+ prim_YUV.c
prim_YCoCg.c
primitives.c
prim_internal.h)
prim_set_opt.c
prim_shift_opt.c
prim_sign_opt.c
+ prim_YUV_opt.c
prim_YCoCg_opt.c)
add_definitions(-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE})
if(WITH_SSE2)
if(CMAKE_COMPILER_IS_GNUCC)
- set(OPTIMIZATION "${OPTIMIZATION} -msse2 -mssse3 -Wdeclaration-after-statement")
+ set(OPTIMIZATION "${OPTIMIZATION} -msse2 -mssse3 -O2 -Wdeclaration-after-statement")
endif()
if(MSVC)
set_property(SOURCE ${${MODULE_PREFIX}_OPT_SRCS} PROPERTY COMPILE_FLAGS ${OPTIMIZATION})
+# always compile with optimization
+if(CMAKE_COMPILER_IS_GNUCC)
+ set_property(SOURCE ${${MODULE_PREFIX}_SRCS} PROPERTY COMPILE_FLAGS "-O2")
+endif()
+
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_OPT_SRCS})
add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT"
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp")
-if(BUILD_TESTING AND ((NOT WIN32) AND (NOT APPLE)))
-# add_subdirectory(test)
+if(BUILD_TESTING AND NOT WIN32 AND NOT APPLE)
+ add_subdirectory(test)
endif()
#endif /* !MINMAX */
/* ------------------------------------------------------------------------- */
-pstatus_t general_YCoCgRToRGB_8u_AC4R(
+pstatus_t general_YCoCgToRGB_8u_AC4R(
const BYTE *pSrc, INT32 srcStep,
BYTE *pDst, INT32 dstStep,
UINT32 width, UINT32 height,
BOOL withAlpha,
BOOL invert)
{
- const BYTE *sptr = pSrc;
+ BYTE A;
+ int x, y;
BYTE *dptr = pDst;
+ const BYTE *sptr = pSrc;
+ INT16 Cg, Co, Y, T, R, G, B;
int cll = shift - 1; /* -1 builds in the /2's */
- int x,y;
- int srcRowBump = srcStep - width*sizeof(UINT32);
- int dstRowBump = dstStep - width*sizeof(UINT32);
+ int srcPad = srcStep - (width * 4);
+ int dstPad = dstStep - (width * 4);
+
if (invert)
{
- for (y=0; y<height; y++)
+ for (y = 0; y < height; y++)
{
- for (x=0; x<width; x++)
+ for (x = 0; x < width; x++)
{
- INT16 cg, co, y, t, r, g, b;
- BYTE a;
-
/* Note: shifts must be done before sign-conversion. */
- cg = (INT16) ((INT8) ((*sptr++) << cll));
- co = (INT16) ((INT8) ((*sptr++) << cll));
- y = (INT16) (*sptr++); /* UINT8->INT16 */
- a = *sptr++;
- if (!withAlpha) a = 0xFFU;
- t = y - cg;
- r = t + co;
- g = y + cg;
- b = t - co;
- *dptr++ = (BYTE) MINMAX(r, 0, 255);
- *dptr++ = (BYTE) MINMAX(g, 0, 255);
- *dptr++ = (BYTE) MINMAX(b, 0, 255);
- *dptr++ = a;
+ Cg = (INT16) ((INT8) ((*sptr++) << cll));
+ Co = (INT16) ((INT8) ((*sptr++) << cll));
+ Y = (INT16) (*sptr++); /* UINT8->INT16 */
+
+ A = *sptr++;
+
+ if (!withAlpha)
+ A = 0xFFU;
+
+ T = Y - Cg;
+ R = T + Co;
+ G = Y + Cg;
+ B = T - Co;
+
+ *dptr++ = (BYTE) MINMAX(R, 0, 255);
+ *dptr++ = (BYTE) MINMAX(G, 0, 255);
+ *dptr++ = (BYTE) MINMAX(B, 0, 255);
+ *dptr++ = A;
}
- sptr += srcRowBump;
- dptr += dstRowBump;
+
+ sptr += srcPad;
+ dptr += dstPad;
}
}
else
{
- for (y=0; y<height; y++)
+ for (y = 0; y < height; y++)
{
- for (x=0; x<width; x++)
+ for (x = 0; x < width; x++)
{
- INT16 cg, co, y, t, r, g, b;
- BYTE a;
-
/* Note: shifts must be done before sign-conversion. */
- cg = (INT16) ((INT8) ((*sptr++) << cll));
- co = (INT16) ((INT8) ((*sptr++) << cll));
- y = (INT16) (*sptr++); /* UINT8->INT16 */
- a = *sptr++;
- if (!withAlpha) a = 0xFFU;
- t = y - cg;
- r = t + co;
- g = y + cg;
- b = t - co;
- *dptr++ = (BYTE) MINMAX(b, 0, 255);
- *dptr++ = (BYTE) MINMAX(g, 0, 255);
- *dptr++ = (BYTE) MINMAX(r, 0, 255);
- *dptr++ = a;
+ Cg = (INT16) ((INT8) ((*sptr++) << cll));
+ Co = (INT16) ((INT8) ((*sptr++) << cll));
+ Y = (INT16) (*sptr++); /* UINT8->INT16 */
+
+ A = *sptr++;
+
+ if (!withAlpha)
+ A = 0xFFU;
+
+ T = Y - Cg;
+ R = T + Co;
+ G = Y + Cg;
+ B = T - Co;
+
+ *dptr++ = (BYTE) MINMAX(B, 0, 255);
+ *dptr++ = (BYTE) MINMAX(G, 0, 255);
+ *dptr++ = (BYTE) MINMAX(R, 0, 255);
+ *dptr++ = A;
}
- sptr += srcRowBump;
- dptr += dstRowBump;
+
+ sptr += srcPad;
+ dptr += dstPad;
}
}
+
return PRIMITIVES_SUCCESS;
}
/* ------------------------------------------------------------------------- */
void primitives_init_YCoCg(primitives_t* prims)
{
- prims->YCoCgRToRGB_8u_AC4R = general_YCoCgRToRGB_8u_AC4R;
+ prims->YCoCgToRGB_8u_AC4R = general_YCoCgToRGB_8u_AC4R;
primitives_init_YCoCg_opt(prims);
}
#ifndef __PRIM_YCOCG_H_INCLUDED__
#define __PRIM_YCOCG_H_INCLUDED__
-pstatus_t general_YCoCgRToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, UINT8 shift, BOOL withAlpha, BOOL invert);
+pstatus_t general_YCoCgToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, UINT8 shift, BOOL withAlpha, BOOL invert);
void primitives_init_YCoCg_opt(primitives_t* prims);
if ((width < 8) || (ULONG_PTR) dptr & 0x03)
{
/* Too small, or we'll never hit a 16-byte boundary. Punt. */
- return general_YCoCgRToRGB_8u_AC4R(pSrc, srcStep,
+ return general_YCoCgToRGB_8u_AC4R(pSrc, srcStep,
pDst, dstStep, width, height, shift, withAlpha, TRUE);
}
{
int startup = (16 - ((ULONG_PTR) dptr & 0x0f)) / 4;
if (startup > width) startup = width;
- general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep,
+ general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep,
startup, 1, shift, withAlpha, TRUE);
sptr += startup * sizeof(UINT32);
dptr += startup * sizeof(UINT32);
/* Handle any remainder pixels. */
if (w > 0) {
- general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep,
+ general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep,
w, 1, shift, withAlpha, TRUE);
sptr += w * sizeof(UINT32);
dptr += w * sizeof(UINT32);
if ((width < 8) || (ULONG_PTR) dptr & 0x03)
{
/* Too small, or we'll never hit a 16-byte boundary. Punt. */
- return general_YCoCgRToRGB_8u_AC4R(pSrc, srcStep,
+ return general_YCoCgToRGB_8u_AC4R(pSrc, srcStep,
pDst, dstStep, width, height, shift, withAlpha, FALSE);
}
{
int startup = (16 - ((ULONG_PTR) dptr & 0x0f)) / 4;
if (startup > width) startup = width;
- general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep,
+ general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep,
startup, 1, shift, withAlpha, FALSE);
sptr += startup * sizeof(UINT32);
dptr += startup * sizeof(UINT32);
/* Handle any remainder pixels. */
if (w > 0) {
- general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep,
+ general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep,
w, 1, shift, withAlpha, FALSE);
sptr += w * sizeof(UINT32);
dptr += w * sizeof(UINT32);
if (IsProcessorFeaturePresentEx(PF_EX_SSSE3)
&& IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE))
{
- prims->YCoCgRToRGB_8u_AC4R = ssse3_YCoCgRToRGB_8u_AC4R;
+ prims->YCoCgToRGB_8u_AC4R = ssse3_YCoCgRToRGB_8u_AC4R;
}
#endif /* WITH_SSE2 */
}
--- /dev/null
+/**
+ * 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 <freerdp/types.h>
+#include <freerdp/primitives.h>
+#include <freerdp/codec/color.h>
+
+#include "prim_internal.h"
+#include "prim_YUV.h"
+
+/**
+ * | R | ( | 256 0 403 | | Y | )
+ * | G | = ( | 256 -48 -120 | | U - 128 | ) >> 8
+ * | B | ( | 256 475 0 | | V - 128 | )
+ *
+ * | Y | ( | 54 183 18 | | R | ) | 0 |
+ * | U | = ( | -29 -99 128 | | G | ) >> 8 + | 128 |
+ * | V | ( | 128 -116 -12 | | B | ) | 128 |
+ */
+
+pstatus_t general_YUV420ToRGB_8u_P3AC4R(const BYTE* pSrc[3], int srcStep[3],
+ BYTE* pDst, int dstStep, const prim_size_t* roi)
+{
+ int x, y;
+ int dstPad;
+ int srcPad[3];
+ BYTE Y, U, V;
+ int halfWidth;
+ int halfHeight;
+ const BYTE* pY;
+ const BYTE* pU;
+ const BYTE* pV;
+ int R, G, B;
+ int Yp, Up, Vp;
+ int Up48, Up475;
+ int Vp403, Vp120;
+ BYTE* pRGB = pDst;
+ int nWidth, nHeight;
+ int lastRow, lastCol;
+
+ pY = pSrc[0];
+ pU = pSrc[1];
+ pV = pSrc[2];
+
+ lastCol = roi->width & 0x01;
+ lastRow = roi->height & 0x01;
+
+ nWidth = (roi->width + 1) & ~0x0001;
+ nHeight = (roi->height + 1) & ~0x0001;
+
+ halfWidth = nWidth / 2;
+ halfHeight = nHeight / 2;
+
+ srcPad[0] = (srcStep[0] - nWidth);
+ srcPad[1] = (srcStep[1] - halfWidth);
+ srcPad[2] = (srcStep[2] - halfWidth);
+
+ dstPad = (dstStep - (nWidth * 4));
+
+ for (y = 0; y < halfHeight; )
+ {
+ if (++y == halfHeight)
+ lastRow <<= 1;
+
+ for (x = 0; x < halfWidth; )
+ {
+ if (++x == halfWidth)
+ lastCol <<= 1;
+
+ U = *pU++;
+ V = *pV++;
+
+ Up = U - 128;
+ Vp = V - 128;
+
+ Up48 = 48 * Up;
+ Up475 = 475 * Up;
+
+ Vp403 = Vp * 403;
+ Vp120 = Vp * 120;
+
+ /* 1st pixel */
+
+ Y = *pY++;
+ Yp = Y << 8;
+
+ R = (Yp + Vp403) >> 8;
+ G = (Yp - Up48 - Vp120) >> 8;
+ B = (Yp + Up475) >> 8;
+
+ if (R < 0)
+ R = 0;
+ else if (R > 255)
+ R = 255;
+
+ if (G < 0)
+ G = 0;
+ else if (G > 255)
+ G = 255;
+
+ if (B < 0)
+ B = 0;
+ else if (B > 255)
+ B = 255;
+
+ *pRGB++ = (BYTE) B;
+ *pRGB++ = (BYTE) G;
+ *pRGB++ = (BYTE) R;
+ *pRGB++ = 0xFF;
+
+ /* 2nd pixel */
+
+ if (!(lastCol & 0x02))
+ {
+ Y = *pY++;
+ Yp = Y << 8;
+
+ R = (Yp + Vp403) >> 8;
+ G = (Yp - Up48 - Vp120) >> 8;
+ B = (Yp + Up475) >> 8;
+
+ if (R < 0)
+ R = 0;
+ else if (R > 255)
+ R = 255;
+
+ if (G < 0)
+ G = 0;
+ else if (G > 255)
+ G = 255;
+
+ if (B < 0)
+ B = 0;
+ else if (B > 255)
+ B = 255;
+
+ *pRGB++ = (BYTE) B;
+ *pRGB++ = (BYTE) G;
+ *pRGB++ = (BYTE) R;
+ *pRGB++ = 0xFF;
+ }
+ else
+ {
+ pY++;
+ pRGB += 4;
+ lastCol >>= 1;
+ }
+ }
+
+ pY += srcPad[0];
+ pU -= halfWidth;
+ pV -= halfWidth;
+ pRGB += dstPad;
+
+ for (x = 0; x < halfWidth; )
+ {
+ if (++x == halfWidth)
+ lastCol <<= 1;
+
+ U = *pU++;
+ V = *pV++;
+
+ Up = U - 128;
+ Vp = V - 128;
+
+ Up48 = 48 * Up;
+ Up475 = 475 * Up;
+
+ Vp403 = Vp * 403;
+ Vp120 = Vp * 120;
+
+ /* 3rd pixel */
+
+ Y = *pY++;
+ Yp = Y << 8;
+
+ R = (Yp + Vp403) >> 8;
+ G = (Yp - Up48 - Vp120) >> 8;
+ B = (Yp + Up475) >> 8;
+
+ if (R < 0)
+ R = 0;
+ else if (R > 255)
+ R = 255;
+
+ if (G < 0)
+ G = 0;
+ else if (G > 255)
+ G = 255;
+
+ if (B < 0)
+ B = 0;
+ else if (B > 255)
+ B = 255;
+
+ *pRGB++ = (BYTE) B;
+ *pRGB++ = (BYTE) G;
+ *pRGB++ = (BYTE) R;
+ *pRGB++ = 0xFF;
+
+ /* 4th pixel */
+
+ if (!(lastCol & 0x02))
+ {
+ Y = *pY++;
+ Yp = Y << 8;
+
+ R = (Yp + Vp403) >> 8;
+ G = (Yp - Up48 - Vp120) >> 8;
+ B = (Yp + Up475) >> 8;
+
+ if (R < 0)
+ R = 0;
+ else if (R > 255)
+ R = 255;
+
+ if (G < 0)
+ G = 0;
+ else if (G > 255)
+ G = 255;
+
+ if (B < 0)
+ B = 0;
+ else if (B > 255)
+ B = 255;
+
+ *pRGB++ = (BYTE) B;
+ *pRGB++ = (BYTE) G;
+ *pRGB++ = (BYTE) R;
+ *pRGB++ = 0xFF;
+ }
+ else
+ {
+ pY++;
+ pRGB += 4;
+ lastCol >>= 1;
+ }
+ }
+
+ pY += srcPad[0];
+ pU += srcPad[1];
+ pV += srcPad[2];
+ pRGB += dstPad;
+ }
+
+ return PRIMITIVES_SUCCESS;
+}
+
+void primitives_init_YUV(primitives_t* prims)
+{
+ prims->YUV420ToRGB_8u_P3AC4R = general_YUV420ToRGB_8u_P3AC4R;
+
+ primitives_init_YUV_opt(prims);
+}
+
+void primitives_deinit_YUV(primitives_t* prims)
+{
+
+}
--- /dev/null
+/**
+ * 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 FREERDP_PRIMITIVES_YUV_H
+#define FREERDP_PRIMITIVES_YUV_H
+
+pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(const INT16* pSrc[3], int srcStep, BYTE* pDst, int dstStep, const prim_size_t* roi);
+
+void primitives_init_YUV(primitives_t* prims);
+void primitives_init_YUV_opt(primitives_t* prims);
+void primitives_deinit_YUV(primitives_t* prims);
+
+#endif /* FREERDP_PRIMITIVES_YUV_H */
--- /dev/null
+/** function for converting YUV420p data to the RGB format (but without any special upconverting)
+ * It's completely written in nasm-x86-assembly for intel processors supporting SSSE3 and higher.
+ * The target dstStep (6th parameter) must be a multiple of 16.
+ * srcStep[0] must be (target dstStep) / 4 or bigger and srcStep[1] the next multiple of four
+ * of the half of srcStep[0] or bigger
+ */
+
+#include <stdio.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <winpr/sysinfo.h>
+#include <winpr/crt.h>
+#include <freerdp/types.h>
+#include <freerdp/primitives.h>
+
+
+#ifdef WITH_SSE2
+
+#include <emmintrin.h>
+#include <tmmintrin.h>
+
+pstatus_t ssse3_YUV420ToRGB_8u_P3AC4R(const BYTE **pSrc, int *srcStep,
+ BYTE *pDst, int dstStep, const prim_size_t *roi)
+{
+ int lastRow, lastCol;
+ BYTE *UData,*VData,*YData;
+ int i,nWidth,nHeight,VaddDst,VaddY,VaddU,VaddV;
+ __m128i r0,r1,r2,r3,r4,r5,r6,r7;
+ __m128i *buffer;
+
+ /* last_line: if the last (U,V doubled) line should be skipped, set to 10B
+ * last_column: if it's the last column in a line, set to 10B (for handling line-endings not multiple by four) */
+
+ buffer = _aligned_malloc(4 * 16, 16);
+
+ YData = (BYTE*) pSrc[0];
+ UData = (BYTE*) pSrc[1];
+ VData = (BYTE*) pSrc[2];
+
+ nWidth = roi->width;
+ nHeight = roi->height;
+
+ if ((lastCol = (nWidth & 3)))
+ {
+ switch (lastCol)
+ {
+ case 1:
+ r7 = _mm_set_epi32(0,0,0,0xFFFFFFFF);
+ break;
+
+ case 2:
+ r7 = _mm_set_epi32(0,0,0xFFFFFFFF,0xFFFFFFFF);
+ break;
+
+ case 3:
+ r7 = _mm_set_epi32(0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF);
+ break;
+ }
+
+ _mm_store_si128(buffer+3,r7);
+ lastCol = 1;
+ }
+
+ nWidth += 3;
+ nWidth = nWidth >> 2;
+
+ lastRow = nHeight & 1;
+ nHeight++;
+ nHeight = nHeight >> 1;
+
+ VaddDst = (dstStep << 1) - (nWidth << 4);
+ VaddY = (srcStep[0] << 1) - (nWidth << 2);
+ VaddU = srcStep[1] - (((nWidth << 1) + 2) & 0xFFFC);
+ VaddV = srcStep[2] - (((nWidth << 1) + 2) & 0xFFFC);
+
+ while (nHeight-- > 0)
+ {
+ if (nHeight == 0)
+ lastRow <<= 1;
+
+ i = 0;
+
+ do
+ {
+ if (!(i & 0x01))
+ {
+ /* Y-, U- and V-data is stored in different arrays.
+ * We start with processing U-data.
+ *
+ * at first we fetch four U-values from its array and shuffle them like this:
+ * 0d0d 0c0c 0b0b 0a0a
+ * we've done two things: converting the values to signed words and duplicating
+ * each value, because always two pixel "share" the same U- (and V-) data */
+ r0 = _mm_cvtsi32_si128(*(UINT32 *)UData);
+ r5 = _mm_set_epi32(0x80038003,0x80028002,0x80018001,0x80008000);
+ r0 = _mm_shuffle_epi8(r0,r5);
+
+ UData += 4;
+
+ /* then we subtract 128 from each value, so we get D */
+ r3 = _mm_set_epi16(128,128,128,128,128,128,128,128);
+ r0 = _mm_subs_epi16(r0,r3);
+
+ /* we need to do two things with our D, so let's store it for later use */
+ r2 = r0;
+
+ /* now we can multiply our D with 48 and unpack it to xmm4:xmm0
+ * this is what we need to get G data later on */
+ r4 = r0;
+ r7 = _mm_set_epi16(48,48,48,48,48,48,48,48);
+ r0 = _mm_mullo_epi16(r0,r7);
+ r4 = _mm_mulhi_epi16(r4,r7);
+ r7 = r0;
+ r0 = _mm_unpacklo_epi16(r0,r4);
+ r4 = _mm_unpackhi_epi16(r7,r4);
+
+ /* to get B data, we need to prepare a second value, D*475 */
+ r1 = r2;
+ r7 = _mm_set_epi16(475,475,475,475,475,475,475,475);
+ r1 = _mm_mullo_epi16(r1,r7);
+ r2 = _mm_mulhi_epi16(r2,r7);
+ r7 = r1;
+ r1 = _mm_unpacklo_epi16(r1,r2);
+ r7 = _mm_unpackhi_epi16(r7,r2);
+
+ /* so we got something like this: xmm7:xmm1
+ * this pair contains values for 16 pixel:
+ * aabbccdd
+ * aabbccdd, but we can only work on four pixel at once, so we need to save upper values */
+ _mm_store_si128(buffer+1,r7);
+
+ /* Now we've prepared U-data. Preparing V-data is actually the same, just with other coefficients */
+ r2 = _mm_cvtsi32_si128(*(UINT32 *)VData);
+ r2 = _mm_shuffle_epi8(r2,r5);
+
+ VData += 4;
+
+ r2 = _mm_subs_epi16(r2,r3);
+
+ r5 = r2;
+
+ /* this is also known as E*403, we need it to convert R data */
+ r3 = r2;
+ r7 = _mm_set_epi16(403,403,403,403,403,403,403,403);
+ r2 = _mm_mullo_epi16(r2,r7);
+ r3 = _mm_mulhi_epi16(r3,r7);
+ r7 = r2;
+ r2 = _mm_unpacklo_epi16(r2,r3);
+ r7 = _mm_unpackhi_epi16(r7,r3);
+
+ /* and preserve upper four values for future ... */
+ _mm_store_si128(buffer+2,r7);
+
+ /* doing this step: E*120 */
+ r3 = r5;
+ r7 = _mm_set_epi16(120,120,120,120,120,120,120,120);
+ r3 = _mm_mullo_epi16(r3,r7);
+ r5 = _mm_mulhi_epi16(r5,r7);
+ r7 = r3;
+ r3 = _mm_unpacklo_epi16(r3,r5);
+ r7 = _mm_unpackhi_epi16(r7,r5);
+
+ /* now we complete what we've begun above:
+ * (48*D) + (120*E) = (48*D +120*E) */
+ r0 = _mm_add_epi32(r0,r3);
+ r4 = _mm_add_epi32(r4,r7);
+
+ /* and store to memory ! */
+ _mm_store_si128(buffer,r4);
+ }
+ else
+ {
+ /* maybe you've wondered about the conditional above ?
+ * Well, we prepared UV data for eight pixel in each line, but can only process four
+ * per loop. So we need to load the upper four pixel data from memory each secound loop! */
+ r1 = _mm_load_si128(buffer+1);
+ r2 = _mm_load_si128(buffer+2);
+ r0 = _mm_load_si128(buffer);
+ }
+
+ if (++i == nWidth)
+ lastCol <<= 1;
+
+ /* We didn't produce any output yet, so let's do so!
+ * Ok, fetch four pixel from the Y-data array and shuffle them like this:
+ * 00d0 00c0 00b0 00a0, to get signed dwords and multiply by 256 */
+ r4 = _mm_cvtsi32_si128(*(UINT32 *)YData);
+ r7 = _mm_set_epi32(0x80800380,0x80800280,0x80800180,0x80800080);
+ r4 = _mm_shuffle_epi8(r4,r7);
+
+ r5 = r4;
+ r6 = r4;
+
+ /* no we can perform the "real" conversion itself and produce output! */
+ r4 = _mm_add_epi32(r4,r2);
+ r5 = _mm_sub_epi32(r5,r0);
+ r6 = _mm_add_epi32(r6,r1);
+
+ /* in the end, we only need bytes for RGB values.
+ * So, what do we do? right! shifting left makes values bigger and thats always good.
+ * before we had dwords of data, and by shifting left and treating the result
+ * as packed words, we get not only signed words, but do also divide by 256
+ * imagine, data is now ordered this way: ddx0 ccx0 bbx0 aax0, and x is the least
+ * significant byte, that we don't need anymore, because we've done some rounding */
+ r4 = _mm_slli_epi32(r4,8);
+ r5 = _mm_slli_epi32(r5,8);
+ r6 = _mm_slli_epi32(r6,8);
+
+ /* one thing we still have to face is the clip() function ...
+ * we have still signed words, and there are those min/max instructions in SSE2 ...
+ * the max instruction takes always the bigger of the two operands and stores it in the first one,
+ * and it operates with signs !
+ * if we feed it with our values and zeros, it takes the zeros if our values are smaller than
+ * zero and otherwise our values */
+ r7 = _mm_set_epi32(0,0,0,0);
+ r4 = _mm_max_epi16(r4,r7);
+ r5 = _mm_max_epi16(r5,r7);
+ r6 = _mm_max_epi16(r6,r7);
+
+ /* the same thing just completely different can be used to limit our values to 255,
+ * but now using the min instruction and 255s */
+ r7 = _mm_set_epi32(0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000);
+ r4 = _mm_min_epi16(r4,r7);
+ r5 = _mm_min_epi16(r5,r7);
+ r6 = _mm_min_epi16(r6,r7);
+
+ /* Now we got our bytes.
+ * the moment has come to assemble the three channels R,G and B to the xrgb dwords
+ * on Red channel we just have to and each futural dword with 00FF0000H */
+ //r7=_mm_set_epi32(0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000);
+ r4 = _mm_and_si128(r4,r7);
+
+ /* on Green channel we have to shuffle somehow, so we get something like this:
+ * 00d0 00c0 00b0 00a0 */
+ r7 = _mm_set_epi32(0x80800E80,0x80800A80,0x80800680,0x80800280);
+ r5 = _mm_shuffle_epi8(r5,r7);
+
+ /* and on Blue channel that one:
+ * 000d 000c 000b 000a */
+ r7 = _mm_set_epi32(0x8080800E,0x8080800A,0x80808006,0x80808002);
+ r6 = _mm_shuffle_epi8(r6,r7);
+
+ /* and at last we or it together and get this one:
+ * xrgb xrgb xrgb xrgb */
+ r4 = _mm_or_si128(r4,r5);
+ r4 = _mm_or_si128(r4,r6);
+
+ /* Only thing to do know is writing data to memory, but this gets a bit more
+ * complicated if the width is not a multiple of four and it is the last column in line. */
+ if (lastCol & 0x02)
+ {
+ /* let's say, we need to only convert six pixel in width
+ * Ok, the first 4 pixel will be converted just like every 4 pixel else, but
+ * if it's the last loop in line, last_column is shifted left by one (curious? have a look above),
+ * and we land here. Through initialisation a mask was prepared. In this case it looks like
+ * 0000FFFFH 0000FFFFH 0000FFFFH 0000FFFFH */
+ r6 = _mm_load_si128(buffer+3);
+ /* we and our output data with this mask to get only the valid pixel */
+ r4 = _mm_and_si128(r4,r6);
+ /* then we fetch memory from the destination array ... */
+ r5 = _mm_lddqu_si128((__m128i *)pDst);
+ /* ... and and it with the inverse mask. We get only those pixel, which should not be updated */
+ r6 = _mm_andnot_si128(r6,r5);
+ /* we only have to or the two values together and write it back to the destination array,
+ * and only the pixel that should be updated really get changed. */
+ r4 = _mm_or_si128(r4,r6);
+ }
+ _mm_storeu_si128((__m128i *)pDst,r4);
+
+ if (!(lastRow & 0x02))
+ {
+ /* Because UV data is the same for two lines, we can process the secound line just here,
+ * in the same loop. Only thing we need to do is to add some offsets to the Y- and destination
+ * pointer. These offsets are iStride[0] and the target scanline.
+ * But if we don't need to process the secound line, like if we are in the last line of processing nine lines,
+ * we just skip all this. */
+ r4 = _mm_cvtsi32_si128(*(UINT32 *)(YData+srcStep[0]));
+ r7 = _mm_set_epi32(0x80800380,0x80800280,0x80800180,0x80800080);
+ r4 = _mm_shuffle_epi8(r4,r7);
+
+ r5 = r4;
+ r6 = r4;
+
+ r4 = _mm_add_epi32(r4,r2);
+ r5 = _mm_sub_epi32(r5,r0);
+ r6 = _mm_add_epi32(r6,r1);
+
+ r4 = _mm_slli_epi32(r4,8);
+ r5 = _mm_slli_epi32(r5,8);
+ r6 = _mm_slli_epi32(r6,8);
+
+ r7 = _mm_set_epi32(0,0,0,0);
+ r4 = _mm_max_epi16(r4,r7);
+ r5 = _mm_max_epi16(r5,r7);
+ r6 = _mm_max_epi16(r6,r7);
+
+ r7 = _mm_set_epi32(0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000);
+ r4 = _mm_min_epi16(r4,r7);
+ r5 = _mm_min_epi16(r5,r7);
+ r6 = _mm_min_epi16(r6,r7);
+
+ r7 = _mm_set_epi32(0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000);
+ r4 = _mm_and_si128(r4,r7);
+
+ r7 = _mm_set_epi32(0x80800E80,0x80800A80,0x80800680,0x80800280);
+ r5 = _mm_shuffle_epi8(r5,r7);
+
+ r7 = _mm_set_epi32(0x8080800E,0x8080800A,0x80808006,0x80808002);
+ r6 = _mm_shuffle_epi8(r6,r7);
+
+ r4 = _mm_or_si128(r4,r5);
+ r4 = _mm_or_si128(r4,r6);
+
+ if (lastCol & 0x02)
+ {
+ r6 = _mm_load_si128(buffer+3);
+ r4 = _mm_and_si128(r4,r6);
+ r5 = _mm_lddqu_si128((__m128i *)(pDst+dstStep));
+ r6 = _mm_andnot_si128(r6,r5);
+ r4 = _mm_or_si128(r4,r6);
+
+ /* only thing is, we should shift [rbp-42] back here, because we have processed the last column,
+ * and this "special condition" can be released */
+ lastCol >>= 1;
+ }
+ _mm_storeu_si128((__m128i *)(pDst+dstStep),r4);
+ }
+
+ /* after all we have to increase the destination- and Y-data pointer by four pixel */
+ pDst += 16;
+ YData += 4;
+ }
+ while (i < nWidth);
+
+ /* after each line we have to add the scanline to the destination pointer, because
+ * we are processing two lines at once, but only increasing the destination pointer
+ * in the first line. Well, we only have one pointer, so it's the easiest way to access
+ * the secound line with the one pointer and an offset (scanline)
+ * if we're not converting the full width of the scanline, like only 64 pixel, but the
+ * output buffer was "designed" for 1920p HD, we have to add the remaining length for each line,
+ * to get into the next line. */
+ pDst += VaddDst;
+
+ /* same thing has to be done for Y-data, but with iStride[0] instead of the target scanline */
+ YData += VaddY;
+
+ /* and again for UV data, but here it's enough to add the remaining length, because
+ * UV data is the same for two lines and there exists only one "UV line" on two "real lines" */
+ UData += VaddU;
+ VData += VaddV;
+ }
+
+ _aligned_free(buffer);
+
+ return PRIMITIVES_SUCCESS;
+}
+#endif
+
+void primitives_init_YUV_opt(primitives_t *prims)
+{
+#ifdef WITH_SSE2
+ if (IsProcessorFeaturePresentEx(PF_EX_SSSE3) && IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE))
+ {
+ prims->YUV420ToRGB_8u_P3AC4R = ssse3_YUV420ToRGB_8u_P3AC4R;
+ }
+#endif
+}
#endif /* !MINMAX */
/* ------------------------------------------------------------------------- */
+
+pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(const INT16* pSrc[3], int srcStep,
+ BYTE* pDst, int dstStep, const prim_size_t* roi)
+{
+ int x, y;
+ INT16 R, G, B;
+ float Y, Cb, Cr;
+ BYTE* pRGB = pDst;
+ const INT16* pY = pSrc[0];
+ const INT16* pCb = pSrc[1];
+ const INT16* pCr = pSrc[2];
+ int srcPad = (srcStep - (roi->width * 2)) / 2;
+ int dstPad = (dstStep - (roi->width * 4)) / 4;
+
+ for (y = 0; y < roi->height; y++)
+ {
+ for (x = 0; x < roi->width; x++)
+ {
+ Y = (float) (pY[0] + 4096);
+ Cb = (float) (pCb[0]);
+ Cr = (float) (pCr[0]);
+
+ R = ((INT16) (((Cr * 1.402525f) + Y + 16.0f)) >> 5);
+ G = ((INT16) ((Y - (Cb * 0.343730f) - (Cr * 0.714401f) + 16.0f)) >> 5);
+ B = ((INT16) (((Cb * 1.769905f) + Y + 16.0f)) >> 5);
+
+ if (R < 0)
+ R = 0;
+ else if (R > 255)
+ R = 255;
+
+ if (G < 0)
+ G = 0;
+ else if (G > 255)
+ G = 255;
+
+ if (B < 0)
+ B = 0;
+ else if (B > 255)
+ B = 255;
+
+ *pRGB++ = (BYTE) B;
+ *pRGB++ = (BYTE) G;
+ *pRGB++ = (BYTE) R;
+ *pRGB++ = 0xFF;
+
+ pY++;
+ pCb++;
+ pCr++;
+ }
+
+ pY += srcPad;
+ pCb += srcPad;
+ pCr += srcPad;
+ pRGB += dstPad;
+ }
+
+ return PRIMITIVES_SUCCESS;
+}
+
+/* ------------------------------------------------------------------------- */
+
pstatus_t general_yCbCrToRGB_16s16s_P3P3(
const INT16 *pSrc[3], INT32 srcStep,
INT16 *pDst[3], INT32 dstStep,
/* ------------------------------------------------------------------------- */
void primitives_init_colors(primitives_t* prims)
{
- prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R;
+ prims->yCbCrToRGB_16s8u_P3AC4R = general_yCbCrToRGB_16s8u_P3AC4R;
prims->yCbCrToRGB_16s16s_P3P3 = general_yCbCrToRGB_16s16s_P3P3;
prims->RGBToYCbCr_16s16s_P3P3 = general_RGBToYCbCr_16s16s_P3P3;
+ prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R;
primitives_init_colors_opt(prims);
}
#ifndef __PRIM_COLORS_H_INCLUDED__
#define __PRIM_COLORS_H_INCLUDED__
+pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(const INT16* pSrc[3], int srcStep, BYTE* pDst, int dstStep, const prim_size_t* roi);
pstatus_t general_yCbCrToRGB_16s16s_P3P3(const INT16 *pSrc[3], INT32 srcStep, INT16 *pDst[3], INT32 dstStep, const prim_size_t *roi);
pstatus_t general_RGBToYCbCr_16s16s_P3P3(const INT16 *pSrc[3], INT32 srcStep, INT16 *pDst[3], INT32 dstStep, const prim_size_t *roi);
pstatus_t general_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3], int srcStep, BYTE *pDst, int dstStep, const prim_size_t *roi);
: _mm_load_si128((__m128i *) (_ptr_)))
/* Function prototypes for all the init/deinit routines. */
-extern void primitives_init_copy(
- primitives_t *prims);
-extern void primitives_deinit_copy(
- primitives_t *prims);
-
-extern void primitives_init_set(
- primitives_t *prims);
-extern void primitives_deinit_set(
- primitives_t *prims);
-
-extern void primitives_init_add(
- primitives_t *prims);
-extern void primitives_deinit_add(
- primitives_t *prims);
-
-extern void primitives_init_andor(
- primitives_t *prims);
-extern void primitives_deinit_andor(
- primitives_t *prims);
-
-extern void primitives_init_shift(
- primitives_t *prims);
-extern void primitives_deinit_shift(
- primitives_t *prims);
-
-extern void primitives_init_sign(
- primitives_t *prims);
-extern void primitives_deinit_sign(
- primitives_t *prims);
-
-extern void primitives_init_alphaComp(
- primitives_t *prims);
-extern void primitives_deinit_alphaComp(
- primitives_t *prims);
-
-extern void primitives_init_colors(
- primitives_t *prims);
-extern void primitives_deinit_colors(
- primitives_t *prims);
-
-extern void primitives_init_YCoCg(
- primitives_t *prims);
-extern void primitives_deinit_YCoCg(
- primitives_t *prims);
-
-extern void primitives_init_16to32bpp(
- primitives_t *prims);
-extern void primitives_deinit_16to32bpp(
- primitives_t *prims);
+extern void primitives_init_copy(primitives_t *prims);
+extern void primitives_deinit_copy(primitives_t *prims);
+
+extern void primitives_init_set(primitives_t *prims);
+extern void primitives_deinit_set(primitives_t *prims);
+
+extern void primitives_init_add(primitives_t *prims);
+extern void primitives_deinit_add(primitives_t *prims);
+
+extern void primitives_init_andor(primitives_t *prims);
+extern void primitives_deinit_andor(primitives_t *prims);
+
+extern void primitives_init_shift(primitives_t *prims);
+extern void primitives_deinit_shift(primitives_t *prims);
+
+extern void primitives_init_sign(primitives_t *prims);
+extern void primitives_deinit_sign(primitives_t *prims);
+
+extern void primitives_init_alphaComp(primitives_t *prims);
+extern void primitives_deinit_alphaComp(primitives_t *prims);
+
+extern void primitives_init_colors(primitives_t *prims);
+extern void primitives_deinit_colors(primitives_t *prims);
+
+extern void primitives_init_YCoCg(primitives_t *prims);
+extern void primitives_deinit_YCoCg(primitives_t *prims);
+
+extern void primitives_init_YUV(primitives_t *prims);
+extern void primitives_deinit_YUV(primitives_t *prims);
+
+extern void primitives_init_16to32bpp(primitives_t *prims);
+extern void primitives_deinit_16to32bpp(primitives_t *prims);
#endif /* !__PRIM_INTERNAL_H_INCLUDED__ */
/* ------------------------------------------------------------------------- */
void primitives_init(void)
{
- if (pPrimitives == NULL)
+ if (!pPrimitives)
{
pPrimitives = calloc(1, sizeof(primitives_t));
- if (pPrimitives == NULL)
+ if (!pPrimitives)
return;
}
primitives_init_sign(pPrimitives);
primitives_init_colors(pPrimitives);
primitives_init_YCoCg(pPrimitives);
+ primitives_init_YUV(pPrimitives);
primitives_init_16to32bpp(pPrimitives);
}
/* ------------------------------------------------------------------------- */
primitives_t* primitives_get(void)
{
- if (pPrimitives == NULL)
+ if (!pPrimitives)
primitives_init();
return pPrimitives;
/* ------------------------------------------------------------------------- */
void primitives_deinit(void)
{
- if (pPrimitives == NULL)
+ if (!pPrimitives)
return;
/* Call each section's de-initialization routine. */
primitives_deinit_sign(pPrimitives);
primitives_deinit_colors(pPrimitives);
primitives_deinit_YCoCg(pPrimitives);
+ primitives_deinit_YUV(pPrimitives);
primitives_deinit_16to32bpp(pPrimitives);
free((void*) pPrimitives);
prim_test
+TestPrimitives.c
-# FreeRDP: A Remote Desktop Protocol Client
-# primitives test makefile builder
-# vi:ts=4 sw=4:
-#
-# (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-# 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.
-#
-# TODO: Integrate this into the testing framework, in some form.
-# Right now this produces a standalone test that covers both functionality
-# and performance of the primitives library entrypoints.
-
-cmake_minimum_required(VERSION 2.8)
-set(MODULE_NAME "prim_test")
-set(MODULE_PREFIX "PRIMITIVES_LIBRARY_TEST")
-
-set(PRIMITIVE_TEST_CFILES
+set(MODULE_NAME "TestPrimitives")
+set(MODULE_PREFIX "TEST_FREERDP_PRIMITIVES")
+
+set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
+
+set(${MODULE_PREFIX}_TESTS
+ TestPrimitives16to32bpp.c
+ TestPrimitivesAdd.c
+ TestPrimitivesAlphaComp.c
+ TestPrimitivesAndOr.c
+ TestPrimitivesColors.c
+ TestPrimitivesCopy.c
+ TestPrimitivesSet.c
+ TestPrimitivesShift.c
+ TestPrimitivesSign.c
+ TestPrimitivesYCbCr.c
+ TestPrimitivesYCoCg.c)
+
+create_test_sourcelist(${MODULE_PREFIX}_SRCS
+ ${${MODULE_PREFIX}_DRIVER}
+ ${${MODULE_PREFIX}_TESTS})
+
+set(${MODULE_PREFIX}_EXTRA_SRCS
prim_test.c
- test_16to32bpp.c
- test_add.c
- test_alphaComp.c
- test_andor.c
- test_colors.c
- test_copy.c
- test_set.c
- test_shift.c
- test_sign.c
- test_YCoCg.c
- ../prim_16to32bpp.c
- ../prim_add.c
- ../prim_andor.c
- ../prim_alphaComp.c
- ../prim_colors.c
- ../prim_copy.c
- ../prim_set.c
- ../prim_shift.c
- ../prim_sign.c
- ../prim_YCoCg.c
- ../prim_16to32bpp_opt.c
- ../prim_add_opt.c
- ../prim_alphaComp_opt.c
- ../prim_andor_opt.c
- ../prim_colors_opt.c
- ../prim_set_opt.c
- ../prim_shift_opt.c
- ../prim_sign_opt.c
- ../prim_YCoCg_opt.c
- ../primitives.c
- )
-
-set(PRIMITIVE_TEST_HEADERS
- measure.h
prim_test.h
- ../prim_internal.h
-)
-
-set(PRIMITIVE_TEST_SRCS
- ${PRIMITIVE_TEST_CFILES}
- ${PRIMITIVE_TEST_HEADERS}
- )
-
-include_directories(. ../../.. ../../../include ../../../winpr/include)
-add_definitions(-DPRIM_STATIC=auto -DALL_PRIMITIVES_VERSIONS -DHAVE_CONFIG_H)
+ measure.h)
-# If these haven't been set by the caller, set them now to defaults.
-if(NOT DEFINED WITH_IPP)
- set(WITH_IPP FALSE)
-endif()
-if(NOT DEFINED WITH_SSE2)
- if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*")
- set(WITH_SSE2 FALSE)
- else()
- set(WITH_SSE2 TRUE)
- endif()
-endif()
-if(NOT DEFINED WITH_NEON)
- if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*")
- set(WITH_NEON TRUE)
- else()
- set(WITH_NEON FALSE)
- endif()
-endif()
+add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_EXTRA_SRCS})
-if(WITH_SSE2)
- if(CMAKE_COMPILER_IS_GNUCC)
- set(OPTFLAGS "${OPTFLAGS} -msse2 -mssse3 -O2 -Wdeclaration-after-statement")
- endif()
+set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
+ MONOLITHIC ${MONOLITHIC_BUILD}
+ MODULE freerdp
+ MODULES freerdp-primitives)
+
+set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr)
- if(MSVC)
- set(OPTFLAGS "${OPTFLAGS} /arch:SSE2")
- endif()
-elseif(WITH_NEON)
- if(CMAKE_COMPILER_IS_GNUCC)
- set(OPTFLAGS "${OPTFLAGS} -mfpu=neon -mfloat-abi=${ARM_FP_ABI} -O2")
- endif()
- # TODO: Add MSVC equivalent
-endif()
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
-add_executable(prim_test ${PRIMITIVE_TEST_SRCS})
+add_definitions(-DPRIM_STATIC=auto -DALL_PRIMITIVES_VERSIONS)
-if(WITH_IPP)
- if(NOT DEFINED IPP_FOUND)
- include(../../../cmake/FindIPP.cmake)
- endif()
+set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
- # IPP PATH debugging messages
- message(IPP_FOUND=${IPP_FOUND})
- message(IPP_VERSION_STR=${IPP_VERSION_STR})
- message(IPP_VERSION_MAJOR=${IPP_VERSION_MAJOR})
- message(IPP_VERSION_MINOR=${IPP_VERSION_MINOR})
- message(IPP_VERSION_BUILD=${IPP_VERSION_BUILD})
- message(IPP_ROOT_DIR=${IPP_ROOT_DIR})
- message(IPP_INCLUDE_DIRS=${IPP_INCLUDE_DIRS})
- message(IPP_LIBRARY_DIRS=${IPP_LIBRARY_DIRS})
- message(IPP_LIBRARIES=${IPP_LIBRARIES})
- message(IPP_COMPILER_LIBRARY_DIRS=${IPP_COMPILER_LIBRARY_DIRS})
- message(IPP_COMPILER_LIBRARIES=${IPP_COMPILER_LIBRARIES})
- message(IPP_LIBRARY_LIST=${IPP_LIBRARY_LIST})
- message(IPP_LIB_PREFIX=${IPP_LIB_PREFIX})
- message(IPP_LIB_SUFFIX=${IPP_LIB_SUFFIX})
- message(IPP_PREFIX=${IPP_PREFIX})
- message(IPP_SUFFIX=${IPP_SUFFIX})
- message(IPPCORE=${IPPCORE})
- message(IPPS=${IPPS})
- message(IPPI=${IPPI})
- message(IPPCC=${IPPCC})
- message(IPPCV=${IPPCV})
- message(IPPVM=${IPPVM})
-
- if(CMAKE_COMPILER_IS_GNUCC)
- foreach(INCLDIR ${IPP_INCLUDE_DIRS})
- set(OPTFLAGS "${OPTFLAGS} -I${INCLDIR}")
- endforeach(INCLDIR)
- endif()
- target_link_libraries(prim_test ${IPP_LIBRARY_LIST})
-endif()
-
-set_property(SOURCE ${PRIMITIVE_TEST_CFILES} PROPERTY COMPILE_FLAGS ${OPTFLAGS})
-
-find_library(WINPR_SYSINFO NAMES winpr-sysinfo HINTS ../../../winpr/libwinpr/sysinfo)
-target_link_libraries(prim_test rt ${WINPR_SYSINFO})
-
-if(NOT TESTING_OUTPUT_DIRECTORY)
- set(TESTING_OUTPUT_DIRECTORY .)
-endif()
-add_test(prim_test ${TESTING_OUTPUT_DIRECTORY}/prim_test functionality)
+foreach(test ${${MODULE_PREFIX}_TESTS})
+ get_filename_component(TestName ${test} NAME_WE)
+ add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
+endforeach()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Test")
+
static const int RGB_TRIAL_ITERATIONS = 1000;
static const float TEST_TIME = 4.0;
+extern BOOL g_TestPrimitivesPerformance;
+
extern pstatus_t general_RGB565ToARGB_16u32u_C3C4(
const UINT16* pSrc, INT32 srcStep,
UINT32* pDst, INT32 dstStep,
/* ------------------------------------------------------------------------- */
int test_RGB565ToARGB_16u32u_C3C4_func(void)
{
- INT16 ALIGN(data16[4096+3]);
+ UINT16 ALIGN(data16[4096+3]);
BOOL success;
success = TRUE;
{
UINT16 ALIGN(src[4096]);
UINT32 ALIGN(dst[4096]);
- int i;
int size_array[] = { 64 };
get_random_data(src, sizeof(src));
size_array, 1, RGB_TRIAL_ITERATIONS, TEST_TIME);
return SUCCESS;
}
+
+int TestPrimitives16to32bpp(int argc, char* argv[])
+{
+ int status;
+
+ status = test_RGB565ToARGB_16u32u_C3C4_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_RGB565ToARGB_16u32u_C3C4_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ return 0;
+}
static const int ADD16S_PRETEST_ITERATIONS = 300000*64;
static const int TEST_TIME = 2.0; // seconds
+extern BOOL g_TestPrimitivesPerformance;
+
extern pstatus_t general_add_16s(
const INT16 *pSrc1, const INT16 *pSrc2, INT16 *pDst, int len);
extern pstatus_t sse3_add_16s(
test_sizes, NUM_TEST_SIZES, ADD16S_PRETEST_ITERATIONS, TEST_TIME);
return SUCCESS;
}
+
+int TestPrimitivesAdd(int argc, char* argv[])
+{
+ int status;
+
+ status = test_add16s_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_add16s_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ return 0;
+}
static const int ALPHA_PRETEST_ITERATIONS = 5000000;
static const float TEST_TIME = 5.0;
+extern BOOL g_TestPrimitivesPerformance;
+
static const int block_size[] = { 4, 64, 256 };
#define NUM_BLOCK_SIZES (sizeof(block_size)/sizeof(int))
#define MAX_BLOCK_SIZE 256
return SUCCESS;
}
+
+int TestPrimitivesAlphaComp(int argc, char* argv[])
+{
+ int status;
+
+ status = test_alphaComp_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_alphaComp_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ return 0;
+}
static const int ANDOR_PRETEST_ITERATIONS = 100000;
static const int TEST_TIME = 2.0; // seconds
+extern BOOL g_TestPrimitivesPerformance;
+
extern pstatus_t general_andC_32u(const UINT32 *pSrc, UINT32 val,
UINT32 *pDst, int len);
extern pstatus_t sse3_andC_32u(const UINT32 *pSrc, UINT32 val,
test_sizes, NUM_TEST_SIZES, ANDOR_PRETEST_ITERATIONS, TEST_TIME);
return SUCCESS;
}
+
+int TestPrimitivesAndOr(int argc, char* argv[])
+{
+ int status;
+
+ status = test_and_32u_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_and_32u_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ status = test_or_32u_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_or_32u_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ return 0;
+}
static const int YCBCR_TRIAL_ITERATIONS = 1000;
static const float TEST_TIME = 4.0;
+extern BOOL g_TestPrimitivesPerformance;
+
extern pstatus_t general_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3],
int srcStep, BYTE *pDst, int dstStep, const prim_size_t *roi);
extern pstatus_t sse2_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3],
size_array, 1, YCBCR_TRIAL_ITERATIONS, TEST_TIME);
return SUCCESS;
}
+
+int TestPrimitivesColors(int argc, char* argv[])
+{
+ int status;
+
+ status = test_RGBToRGB_16s8u_P3AC4R_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_RGBToRGB_16s8u_P3AC4R_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ status = test_yCbCrToRGB_16s16s_P3P3_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_yCbCrToRGB_16s16s_P3P3_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ return 0;
+}
extern pstatus_t sse3_copy_8u(const BYTE *pSrc, BYTE *pDst, int len);
#endif
+extern BOOL g_TestPrimitivesPerformance;
+
/* ------------------------------------------------------------------------- */
int test_copy8u_func(void)
{
test_sizes, NUM_TEST_SIZES, MEMCPY_PRETEST_ITERATIONS, TEST_TIME);
return SUCCESS;
}
+
+int TestPrimitivesCopy(int argc, char* argv[])
+{
+ int status;
+
+ status = test_copy8u_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_copy8u_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ return 0;
+}
static const int MEMSET32_PRETEST_ITERATIONS = 40000000;
static const float TEST_TIME = 1.0;
+extern BOOL g_TestPrimitivesPerformance;
+
extern pstatus_t general_set_8u(BYTE val, BYTE *pDst, int len);
extern pstatus_t sse2_set_8u(BYTE val, BYTE *pDst, int len);
extern pstatus_t general_set_32s(INT32 val, INT32 *pDst, int len);
}
/* ------------------------------------------------------------------------- */
-static inline void memset32u_naive(
+static INLINE void memset32u_naive(
UINT32 val,
UINT32 *dst,
size_t count)
}
/* ------------------------------------------------------------------------- */
-static inline void memset32s_naive(
+static INLINE void memset32s_naive(
INT32 val,
INT32 *dst,
size_t count)
#endif
return SUCCESS;
}
+
+int TestPrimitivesSet(int argc, char* argv[])
+{
+ int status;
+
+ status = test_set8u_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_set8u_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ status = test_set32s_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_set32s_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ status = test_set32u_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_set32u_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ return 0;
+}
static const int SHIFT_PRETEST_ITERATIONS = 50000;
static const float TEST_TIME = 1.0;
+extern BOOL g_TestPrimitivesPerformance;
+
extern pstatus_t general_lShiftC_16s(
const INT16 *pSrc, int val, INT16 *pDst, int len);
extern pstatus_t general_rShiftC_16s(
test_sizes, NUM_TEST_SIZES, SHIFT_PRETEST_ITERATIONS, TEST_TIME);
return SUCCESS;
}
+
+int TestPrimitivesShift(int argc, char* argv[])
+{
+ int status;
+
+ status = test_lShift_16s_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_lShift_16s_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ status = test_lShift_16u_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_lShift_16u_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ status = test_rShift_16s_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_rShift_16s_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ status = test_rShift_16u_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_rShift_16u_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ return 0;
+}
static const int SIGN_PRETEST_ITERATIONS = 100000;
static const float TEST_TIME = 1.0;
+extern BOOL g_TestPrimitivesPerformance;
+
extern pstatus_t general_sign_16s(const INT16 *pSrc, INT16 *pDst, int len);
#ifdef WITH_SSE2
extern pstatus_t ssse3_sign_16s(const INT16 *pSrc, INT16 *pDst, int len);
test_sizes, NUM_TEST_SIZES, SIGN_PRETEST_ITERATIONS, TEST_TIME);
return SUCCESS;
}
+
+int TestPrimitivesSign(int argc, char* argv[])
+{
+ int status;
+
+ status = test_sign16s_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_sign16s_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ return 0;
+}
--- /dev/null
+
+#include "prim_test.h"
+
+#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,
+ -32, -24, -16, -8, +0, -24, -48, -72,
+ -96, -90, -84, -78, -72, -98, -124, -150,
+ -176, -192, -208, -224, -240, -256, -272, -288,
+ -304, -304, -304, -304, -304, -336, -368, -400,
+ -432, -450, -468, -486, -504, -522, -540, -558,
+ -576, -598, -620, -642, -664, -686, -708, -730,
+ -752, -768, -784, -800, -816, -816, -816, -816,
+ +68, +120, +172, +240, +53, +55, +57, +43,
+ +30, +32, +34, +36, +38, +20, +2, -16,
+ -34, -36, -38, -40, -42, -68, -94, -120,
+ -146, -148, -151, -186, -220, -227, -233, -240,
+ -247, -254, -261, -268, -275, -302, -329, -356,
+ -384, -403, -423, -443, -463, -484, -506, -528,
+ -550, -572, -594, -616, -639, -673, -707, -709,
+ -712, -733, -754, -775, -796, -796, -796, -796,
+ +168, +224, +281, +209, +138, +126, +115, +103,
+ +92, +88, +84, +80, +76, +64, +52, +40,
+ +28, +18, +8, -2, -12, -38, -64, -90,
+ -116, -105, -95, -148, -201, -198, -195, -192,
+ -190, -204, -218, -232, -247, -269, -291, -313,
+ -336, -357, -379, -400, -422, -447, -473, -498,
+ -524, -546, -569, -591, -614, -660, -707, -689,
+ -672, -698, -724, -750, -776, -776, -776, -776,
+ +268, +312, +357, +273, +191, +181, +172, +162,
+ +154, +144, +134, +124, +114, +108, +102, +80,
+ +58, +56, +54, +52, +50, +24, -2, -44,
+ -86, -61, -38, -93, -149, -137, -124, -144,
+ -165, -170, -175, -196, -218, -235, -252, -269,
+ -288, -310, -334, -357, -381, -409, -439, -468,
+ -498, -520, -543, -565, -589, -647, -706, -668,
+ -632, -663, -694, -725, -756, -756, -756, -756,
+ +368, +401, +434, +339, +244, +237, +230, +223,
+ +216, +200, +184, +168, +152, +152, +152, +120,
+ +88, +94, +100, +106, +112, +86, +60, +2,
+ -56, -18, +19, -39, -98, -76, -55, -97,
+ -140, -136, -133, -161, -190, -202, -215, -227,
+ -240, -265, -290, -315, -340, -373, -406, -439,
+ -472, -495, -518, -541, -564, -635, -706, -649,
+ -592, -628, -664, -700, -736, -736, -736, -736,
+ +404, +556, +454, +383, +313, +531, +239, +282,
+ +326, +304, +282, +260, +238, +246, +254, +118,
+ +238, +196, +154, +32, -90, -88, -86, +76,
+ +238, +243, +247, +29, -191, -232, -272, -121,
+ +29, -62, -153, -149, -145, -162, -180, -197,
+ -216, -240, -265, -289, -315, -345, -376, -406,
+ -438, -446, -456, -497, -539, -595, -653, -502,
+ -608, -625, -642, -675, -708, -708, -708, -708,
+ +440, +713, +475, +428, +382, +827, +249, +342,
+ +436, +408, +380, +352, +324, +340, +356, -140,
+ -124, +42, +208, +214, +220, +250, +280, +406,
+ +532, +504, +476, +352, +229, +125, +22, -146,
+ -314, -244, -175, -138, -101, -123, -146, -169,
+ -192, -216, -241, -265, -290, -318, -347, -375,
+ -404, -399, -395, -454, -514, -557, -601, -356,
+ -624, -622, -620, -650, -680, -680, -680, -680,
+ +604, +677, +495, +457, +419, +770, +354, +386,
+ +418, +416, +414, +380, +346, +258, -342, -302,
+ -6, +288, +582, +604, +626, +588, +550, +688,
+ +826, +829, +833, +724, +616, +481, +348, +181,
+ +15, -139, -292, -175, -56, -83, -112, -139,
+ -168, -192, -216, -240, -265, -291, -317, -343,
+ -370, -351, -333, -411, -489, -486, -484, -402,
+ -576, -587, -598, -625, -652, -652, -652, -652,
+ +1280, +1154, +1028, +998, +968, +970, +460, +430,
+ +400, +424, +448, +408, +368, +432, -528, -208,
+ +112, +534, +956, +994, +1032, +926, +820, +970,
+ +1120, +1155, +1190, +1097, +1004, +839, +674, +509,
+ +344, +223, +102, +45, -12, -45, -78, -111,
+ -144, -168, -192, -216, -240, -264, -288, -312,
+ -336, -304, -272, -368, -464, -416, -368, -448,
+ -528, -552, -576, -600, -624, -624, -624, -624,
+ +770, +671, +573, +554, +536, +629, +467, +464,
+ +462, +492, +523, +490, +457, +281, -405, -101,
+ +204, +599, +995, +1310, +1370, +1297, +1225, +1296,
+ +1368, +1432, +1498, +1402, +1308, +1184, +1062, +874,
+ +688, +586, +485, +303, +123, -82, -32, -76,
+ -122, -174, -226, -199, -171, -193, -216, -238,
+ -261, -314, -368, -325, -283, -360, -438, -451,
+ -465, -515, -565, -583, -601, -617, -633, -633,
+ +772, +701, +630, +623, +616, +545, +474, +499,
+ +524, +561, +599, +572, +546, +131, -283, +6,
+ +296, +665, +1034, +1627, +1708, +1669, +1630, +1623,
+ +1616, +1711, +1806, +1709, +1612, +1531, +1450, +1241,
+ +1032, +950, +869, +563, +258, -120, +15, -42,
+ -100, -180, -261, -182, -103, -123, -144, -165,
+ -186, -325, -464, -283, -102, -305, -508, -455,
+ -402, -478, -554, -566, -578, -610, -642, -642,
+ +774, +730, +687, +675, +664, +620, +577, +581,
+ +586, +597, +610, +590, +571, -147, -96, +209,
+ +516, +794, +1073, +1575, +1822, +1976, +1875, +1869,
+ +1864, +1988, +2114, +2014, +1916, +1876, +1838, +1606,
+ +1376, +1266, +1156, +902, +137, -61, -3, -120,
+ -238, -122, -7, -69, -130, -164, -200, -219,
+ -239, -271, -304, -128, -209, -297, -386, -426,
+ -467, -937, -895, -549, -459, -667, -619, -619,
+ +776, +760, +744, +728, +712, +696, +680, +664,
+ +648, +635, +622, +609, +596, -425, +90, +413,
+ +736, +924, +1112, +1524, +1936, +2284, +2120, +2116,
+ +2112, +2267, +2422, +2321, +2220, +2223, +2226, +1973,
+ +1720, +1582, +1444, +1242, +16, -2, -20, +58,
+ +136, -65, -267, -212, -158, -207, -257, -274,
+ -292, -218, -144, +26, -316, -290, -264, -142,
+ -20, +2956, +2860, -788, -852, -980, -596, -596,
+ +826, +807, +789, +770, +752, +749, +747, +744,
+ +742, +677, +613, +516, +421, -285, +288, +573,
+ +860, +1081, +1303, +1668, +2034, +2313, +2337, +2344,
+ +2352, +2452, +2554, +2574, +2596, +2506, +2418, +2248,
+ +2080, +1961, +1843, +925, +7, +40, +74, +748,
+ +654, +453, +251, +48, -154, -107, -61, -111,
+ -161, -28, +104, +45, -271, -274, -278, -842,
+ +1411, +3007, +3323, +327, -1389, -1197, -493, -493,
+ +876, +855, +834, +813, +792, +803, +814, +825,
+ +836, +720, +605, +681, +758, +110, +487, +735,
+ +984, +1239, +1494, +1813, +2132, +2343, +2554, +2573,
+ +2592, +2639, +2686, +2829, +2972, +2791, +2610, +2525,
+ +2440, +2341, +2243, +608, -2, +83, +169, +1438,
+ +1172, +970, +768, +565, +363, +249, +135, +52,
+ -30, -95, -160, -193, -226, -259, -292, +763,
+ -742, +2290, +1738, -1118, -902, -902, -390, -390,
+ +926, +902, +879, +855, +832, +824, +817, +809,
+ +802, +763, +724, +397, +2375, +970, +589, +848,
+ +1108, +1396, +1685, +1941, +2198, +2468, +2739, +2785,
+ +2832, +2888, +2946, +3178, +2900, +3058, +2962, +2848,
+ +2736, +2896, +2546, -364, +309, +205, +871, +1760,
+ +1626, +1471, +1317, +1145, +975, +844, +714, +599,
+ +485, +351, +216, +146, +75, -355, +750, +2687,
+ +529, -1067, -615, -835, -799, -847, -383, -383,
+ +976, +950, +924, +898, +872, +846, +820, +794,
+ +768, +806, +844, +882, +1432, +2598, +692, +962,
+ +1232, +1554, +1876, +2070, +2264, +2594, +2924, +2998,
+ +3072, +3139, +3206, +3273, +2316, +3071, +3314, +3173,
+ +3032, +2941, +1826, -57, +108, +73, +1574, +2083,
+ +2080, +1973, +1866, +1727, +1588, +1441, +1294, +1147,
+ +1000, +796, +592, +484, +376, +828, +256, +772,
+ -248, -72, -408, +984, -184, -536, -376, -376,
+ +1026, +997, +969, +941, +913, +888, +864, +840,
+ +816, +762, +709, +768, +1339, +2269, +2176, +1411,
+ +1414, +1677, +1941, +2188, +2436, +2730, +3023, +3157,
+ +3291, +3349, +3409, +3420, +2152, +3000, +3594, +3403,
+ +3213, +3233, +951, +12, +97, -303, +2883, +2755,
+ +2373, +2312, +2252, +2143, +2036, +1861, +1687, +1544,
+ +1403, +1254, +1106, +974, +842, +1229, +1105, +21,
+ +217, +46, -381, +1912, +3181, +2765, +301, -723,
+ +1076, +1045, +1015, +984, +954, +931, +909, +886,
+ +864, +719, +575, +654, +1246, +1685, +3149, +1604,
+ +1596, +1801, +2006, +2307, +2609, +2866, +3123, +3316,
+ +3510, +3561, +3613, +3568, +1988, +2931, +3875, +3634,
+ +3394, +3527, +76, +81, +86, +859, +3168, +2917,
+ +2666, +2652, +2639, +2561, +2484, +2282, +2081, +1943,
+ +1806, +1713, +1621, +1464, +1308, +1119, +931, +550,
+ +170, -92, -354, +1560, +3986, +1970, -558, -558,
+ +1126, +1092, +1060, +1027, +995, +973, +953, +932,
+ +912, +899, +888, -340, +1249, +1756, +2521, +2421,
+ +1810, +2036, +2263, +2521, +2781, +3066, +3350, +3443,
+ +3537, +3612, +3688, +3476, +2496, +3021, +3803, +3833,
+ +3863, +2843, +33, +133, -21, +2099, +3197, +3061,
+ +2927, +2944, +2961, +2882, +2804, +2607, +2410, +2309,
+ +2209, +2139, +2071, +1842, +1614, +1328, +1044, +663,
+ +283, +10, -263, -488, -201, -201, -457, -457,
+ +1176, +1141, +1106, +1071, +1036, +1017, +998, +979,
+ +960, +825, +690, +203, +740, +1573, +1894, +3239,
+ +2024, +2272, +2521, +2737, +2954, +3010, +3067, +3315,
+ +3564, +3664, +3764, +3384, +3004, +3112, +3732, +3776,
+ +3820, +1905, -10, +187, -128, +3341, +3226, +3207,
+ +3188, +3236, +3284, +3204, +3124, +2932, +2740, +2676,
+ +2612, +2567, +2522, +2221, +1920, +1539, +1158, +777,
+ +396, +112, -172, -488, -292, -324, -356, -356,
+ +1194, +1162, +1131, +1099, +1069, +1047, +1026, +972,
+ +920, +969, +507, +380, +767, +1428, +1834, +2799,
+ +2486, +2347, +2721, +2919, +3118, +3290, +3462, +3266,
+ +3071, +3157, +3243, +3521, +3800, +3674, +3548, +3710,
+ +3873, +874, +179, +91, +517, +3439, +3291, +3333,
+ +3377, +3403, +3430, +3361, +3292, +3174, +3057, +3004,
+ +2951, +2761, +2572, +2222, +1874, +1554, +1235, +883,
+ +533, +220, -93, -470, -335, -319, -303, -303,
+ +1212, +1184, +1157, +1129, +1102, +1078, +1055, +967,
+ +880, +1114, +325, +559, +794, +1284, +1775, +2361,
+ +2948, +2423, +2923, +3103, +3283, +3314, +3346, +3474,
+ +3602, +3674, +3747, +3659, +3572, +3980, +3877, +3901,
+ +3926, -157, +368, +253, +1674, +3795, +3356, +3461,
+ +3566, +3571, +3577, +3518, +3460, +3417, +3375, +3332,
+ +3290, +2956, +2623, +2225, +1828, +1570, +1313, +991,
+ +670, +328, -14, -452, -378, -314, -250, -250,
+ +1230, +1206, +1182, +1158, +1135, +1109, +1083, +1025,
+ +968, +779, +78, +481, +885, +1284, +1939, +2466,
+ +3250, +2626, +2772, +3157, +3543, +3514, +3486, +3729,
+ +3717, +3775, +3834, +3780, +3728, +3934, +3885, +3915,
+ +2667, +92, +333, +173, +2831, +3701, +3549, +3587,
+ +3627, +3642, +3659, +3643, +3628, +3675, +3724, +3436,
+ +3149, +2847, +2545, +2275, +2006, +1730, +1454, +1114,
+ +775, +388, +1, -402, -293, -309, -325, -325,
+ +1248, +1228, +1208, +1188, +1168, +1140, +1112, +1084,
+ +1056, +700, +344, +660, +976, +1284, +2104, +2316,
+ +3040, +2319, +2110, +2189, +2268, +2691, +3114, +3729,
+ +3832, +3877, +3922, +3903, +3884, +3889, +3894, +3931,
+ +1408, +341, +298, +95, +3988, +3609, +3742, +3715,
+ +3688, +3715, +3742, +3769, +3796, +3679, +3562, +3285,
+ +3008, +2738, +2468, +2326, +2184, +1890, +1596, +1238,
+ +880, +448, +16, -352, -208, -304, -400, -400,
+ +1296, +1284, +1272, +1260, +1249, +1165, +1081, +1093,
+ +1106, +232, +382, +677, +971, +973, +1232, +834,
+ +693, +537, +639, +564, +490, +563, +637, -106,
+ +944, +2358, +3773, +3795, +4074, +3964, +3855, +4337,
+ +212, +204, +197, +1341, +4023, +3813, +3860, +3810,
+ +3762, +3766, +3771, +3776, +3781, +3603, +3427, +3201,
+ +2977, +2838, +2699, +2400, +2101, +1982, +1607, +1280,
+ +954, +545, -120, -321, -266, -314, -362, -362,
+ +1344, +1340, +1337, +1333, +1330, +1190, +1051, +1103,
+ +1156, +20, +933, +950, +967, +919, +872, +889,
+ +906, +805, +705, +733, +761, +740, +720, +668,
+ +616, +328, +40, +1640, +3752, +3784, +3816, +3208,
+ +40, +581, +97, +2589, +4058, +4018, +3979, +3907,
+ +3836, +3818, +3801, +3784, +3767, +3529, +3292, +3375,
+ +3458, +3706, +3954, +3754, +3555, +2843, +1619, +1067,
+ +516, +386, -256, -290, -324, -324, -324, -324,
+ +1392, +1364, +1337, +1309, +1283, +1247, +1212, +968,
+ +982, +1424, +1099, +1079, +1058, +1072, +1088, +815,
+ +799, +1056, +802, +772, +743, +645, +547, +769,
+ +736, +649, +563, +332, +102, +1939, +4033, +1982,
+ +444, +332, -36, +4076, +4093, +4047, +4001, +3955,
+ +3910, +3870, +3830, +3791, +3752, +3806, +3861, +3835,
+ +3811, +3678, +3545, +3380, +3216, +3639, +3806, +2341,
+ +1134, +1091, +24, -387, -286, -286, -286, -286,
+ +1440, +1389, +1338, +1287, +1236, +1305, +1374, +1091,
+ +1320, +1037, +1267, +1208, +1150, +715, +281, +486,
+ +1204, +1564, +901, +1325, +1750, +1830, +1911, +1383,
+ +344, +459, +574, +817, +548, +351, +666, +757,
+ +336, +340, +856, +4028, +4128, +4076, +4024, +4004,
+ +3984, +3922, +3861, +3799, +3738, +3828, +3919, +3785,
+ +3652, +3394, +3137, +3007, +2878, +2900, +2923, +3105,
+ +3800, +1284, +1328, +28, -248, -248, -248, -248,
+ +1456, +1406, +1358, +1309, +1261, +1209, +1159, +1444,
+ +1218, +1265, +33, -654, -1342, -977, -356, +394,
+ +1401, +1753, +1338, +1738, +2140, +2575, +3009, +3524,
+ +3784, +2536, +1033, +265, +522, +440, +615, +629,
+ +388, +403, +2211, +4051, +4099, +4078, +4058, +3990,
+ +3922, +3910, +3898, +3886, +3875, +3805, +3735, +3553,
+ +3373, +3126, +2879, +2585, +2291, +2026, +1762, +2649,
+ +3026, +2303, +2092, +665, -250, -250, -250, -250,
+ +1472, +1425, +1379, +1332, +1286, +1371, +1457, +1030,
+ -932, -1834, -1712, -1237, -763, -621, +33, +815,
+ +1598, +1943, +1776, +2153, +2531, +2808, +3085, +3362,
+ +3640, +4102, +4052, +3042, +496, +530, +564, +502,
+ +440, +211, +3055, +3818, +4070, +4081, +4093, +3976,
+ +3860, +3898, +3936, +3974, +4013, +3783, +3553, +3323,
+ +3094, +2858, +2623, +2420, +2217, +1921, +1626, +915,
+ +2764, +250, +296, +22, -252, -252, -252, -252,
+ +1488, +1443, +1399, +1371, +1343, +1308, +1530, -408,
+ -1834, -1589, -1089, -811, -535, -281, +485, +1171,
+ +1859, +2132, +2150, +2503, +2857, +3105, +3352, +3536,
+ +3720, +3875, +3775, +4298, +4054, +2123, +449, +502,
+ +556, +546, +26, +2113, +3945, +4115, +4031, +3946,
+ +3862, +3838, +3814, +3982, +3894, +3488, +3338, +3140,
+ +2943, +2622, +2302, +2030, +1758, +1495, +1234, +1259,
+ +774, -347, -188, -189, -190, -222, -254, -254,
+ +1504, +1462, +1420, +1410, +1400, +1246, +1604, -1334,
+ -1712, -1089, -978, -643, -308, +59, +938, +1529,
+ +2120, +2322, +2524, +2854, +3184, +3402, +3620, +3710,
+ +3800, +3905, +4010, +4019, +4028, +3973, +334, +503,
+ +672, +627, +582, +409, +236, +2359, +3970, +3917,
+ +3864, +3778, +3692, +3990, +3776, +3194, +3124, +2958,
+ +2792, +2387, +1982, +1641, +1300, +1071, +842, +69,
+ -192, -176, -160, -144, -128, -192, -256, -256,
+ +1546, +1496, +1447, +1430, +1413, +1627, +1330, -2102,
+ -1184, -819, -712, -395, -80, +405, +1148, +1713,
+ +2280, +2486, +2692, +2995, +3297, +3467, +3638, +3712,
+ +3787, +3915, +4045, +3917, +4047, +3097, +357, +655,
+ +699, +198, +466, +381, +297, +376, +200, +1815,
+ +3431, +3568, +3961, +4114, +3755, +3310, +3121, +2804,
+ +2487, +2208, +1931, +1189, +447, +37, -116, -254,
+ -136, -111, -86, -109, -132, -196, -260, -260,
+ +1588, +1531, +1475, +1450, +1426, +1497, +33, -1591,
+ -1168, -807, -446, -149, +148, +753, +1358, +1899,
+ +2440, +2650, +2861, +3136, +3411, +3533, +3656, +3715,
+ +3774, +3927, +4080, +3817, +4066, +2223, +380, +553,
+ +214, +3610, +350, +354, +358, +442, +526, +226,
+ -74, +286, +1158, +1678, +1686, +1634, +1582, +1114,
+ +646, +239, -168, -31, +107, -228, -51, -65,
+ -80, -46, -12, -74, -136, -200, -264, -264,
+ +1630, +1565, +1502, +1470, +1439, +1590, -817, -1399,
+ -960, -633, -308, -14, +280, +875, +1472, +1971,
+ +2472, +2718, +2965, +3229, +3492, +3582, +3674, +3701,
+ +3729, +3793, +3859, +4147, +4181, +707, +563, +417,
+ +1297, +3917, +4234, +2198, +163, +267, +372, +348,
+ +325, +108, +147, +186, -31, +38, +107, +96,
+ +85, +61, +38, -162, -106, -126, +111, +876,
+ -152, -93, -34, -87, -140, -204, -268, -268,
+ +1672, +1601, +1530, +1491, +1452, +1685, -1666, -1209,
+ -752, -461, -170, +121, +412, +999, +1586, +2045,
+ +2504, +2787, +3071, +3322, +3574, +3633, +3693, +3688,
+ +3684, +3661, +3638, +3711, +2760, +473, +746, +283,
+ +2380, +4225, +4022, +4043, +4064, +2141, +218, +215,
+ +212, +186, +160, +230, +300, +234, +168, +102,
+ +36, -117, -269, +218, +1218, +2025, +2833, +1048,
+ -224, -140, -56, -100, -144, -208, -272, -272,
+ +1626, +1607, +1589, +1458, +1585, +692, -1479, -1107,
+ -736, -451, -168, +115, +400, +805, +1468, +1937,
+ +2408, +2703, +2999, +3327, +3655, +3568, +3482, +3620,
+ +3759, +3439, +3121, +1601, +851, +819, +533, +437,
+ +3415, +4252, +4066, +4055, +4045, +4084, +4124, +2995,
+ +1867, +1068, +269, +62, -145, -38, +69, +704,
+ +1339, +2183, +3028, +2816, +2861, +2953, +2790, -349,
+ +96, -19, -134, -137, -140, -204, -268, -268,
+ +1580, +1614, +1649, +1427, +1718, -300, -1293, -1006,
+ -720, -443, -166, +111, +388, +613, +1350, +1831,
+ +2312, +2620, +2928, +3076, +3225, +3249, +3273, +3297,
+ +3322, +3475, +3628, +3333, +1502, +655, +832, +593,
+ +3938, +4024, +4110, +4068, +4026, +3980, +3934, +3984,
+ +4034, +3998, +3962, +3990, +4018, +3786, +3554, +3610,
+ +3666, +3459, +3253, +3111, +2969, +2858, +2236, -210,
+ -96, -154, -212, -174, -136, -200, -264, -264,
+ +1662, +1653, +1644, +1619, +1851, -988, -1266, -985,
+ -704, -401, -100, +9, +120, +403, +944, +1579,
+ +2216, +2504, +2793, +2873, +2954, +2976, +2999, +3085,
+ +3173, +3237, +3303, +3575, +521, +553, +587, +1771,
+ +3981, +4019, +4058, +4032, +4007, +3971, +3936, +3948,
+ +3961, +3920, +3879, +3806, +3989, +3866, +3743, +3636,
+ +3529, +3375, +3222, +3069, +2916, +2907, +1362, -119,
+ -64, -113, -162, -147, -132, -196, -260, -260,
+ +1744, +1692, +1640, +1556, +1472, -1932, -1240, -964,
+ -688, -361, -34, +165, +364, +707, +1050, +1585,
+ +2120, +2389, +2658, +2671, +2684, +2705, +2726, +2875,
+ +3024, +3001, +2978, +2283, +564, +965, +342, +2951,
+ +4024, +4015, +4006, +3997, +3988, +3963, +3938, +3913,
+ +3888, +3842, +3796, +3622, +3960, +3946, +3932, +3662,
+ +3392, +3292, +3192, +3028, +2864, +2956, +488, -28,
+ -32, -72, -112, -120, -128, -192, -256, -256,
+ +1834, +1635, +1692, +1718, +208, -1663, -1229, -924,
+ -619, -283, +50, +256, +719, +705, +948, +1126,
+ +1562, +1845, +2129, +2236, +2344, +2447, +2551, +2654,
+ +2759, +2738, +2719, +1562, +663, +623, +327, +4207,
+ +3992, +4012, +4034, +3990, +3948, +3922, +3898, +3872,
+ +3848, +3774, +3701, +3484, +3523, +3726, +3929, +3812,
+ +3695, +3604, +3513, +3407, +3300, +3350, -440, -231,
+ -22, -48, -74, -100, -126, -174, -222, -222,
+ +1924, +1578, +1745, +1880, -1057, -1394, -1219, -884,
+ -550, -207, +135, +93, +563, +449, +847, +669,
+ +1004, +1302, +1600, +1802, +2005, +2191, +2377, +2435,
+ +2494, +2477, +2460, +843, +763, +794, +1337, +3928,
+ +3960, +4011, +4062, +3985, +3908, +3883, +3858, +3833,
+ +3808, +3707, +3607, +3603, +3599, +3506, +3414, +3706,
+ +3998, +3916, +3835, +3786, +3737, +2208, -345, +78,
+ -12, -24, -36, -80, -124, -156, -188, -188,
+ +1598, +1585, +1829, +2154, -1873, -1413, -1208, -556,
+ -417, -514, -102, +440, +214, +191, +681, +435,
+ +702, +870, +1039, +1224, +1409, +1709, +2010, +2039,
+ +2069, +2086, +1849, +795, +766, +596, +2474, +3953,
+ +3896, +3928, +3962, +3914, +3868, +3842, +3818, +3792,
+ +3768, +3687, +3608, +3577, +3546, +3462, +3379, +3312,
+ +3245, +3364, +3484, +3189, +2893, +858, -154, +35,
+ -34, -48, -62, -108, -154, -154, -154, -154,
+ +1784, +1849, +1915, +892, -1666, -1176, -1711, -741,
+ -796, -822, +175, -748, +378, +191, +517, +202,
+ +400, +439, +479, +646, +814, +1229, +1645, +1644,
+ +1644, +1697, +1239, +748, +770, +399, +3613, +3978,
+ +3832, +3847, +3862, +3845, +3828, +3803, +3778, +3753,
+ +3728, +3669, +3611, +3552, +3494, +3419, +3345, +3174,
+ +3004, +2813, +2623, +2592, +2562, -237, +37, -9,
+ -56, -72, -88, -136, -184, -152, -120, -120,
+ +1802, +1900, +2255, -286, -1290, -1129, -712, -391,
+ -327, -385, -445, +201, -178, +436, +27, -45,
+ -118, +204, +270, +384, +498, +685, +874, +998,
+ +1123, +1252, +1127, +794, +717, +1161, +3654, +3843,
+ +3776, +3788, +3802, +3782, +3764, +3616, +3726, +3690,
+ +3656, +3595, +3536, +3476, +3417, +3341, +3265, +3078,
+ +2891, +2687, +2484, +2617, +1982, -28, +8, +14,
+ +18, -18, -54, +6, +66, -30, -126, -126,
+ +1820, +1696, +2084, -2232, -1939, -570, -1762, -1834,
+ -1394, -461, -552, -387, -223, -1110, -462, -37,
+ -124, -31, -451, -134, +183, +143, +104, +353,
+ +602, +809, +1017, +841, +665, +1924, +3696, +3708,
+ +3720, +3731, +3742, +3721, +3700, +3431, +3674, +3629,
+ +3584, +3523, +3462, +3401, +3341, +3264, +3187, +2982,
+ +2778, +2562, +2346, +2386, +891, -77, -20, +36,
+ +92, +36, -20, -108, -196, -164, -132, -132,
+ +1710, +1955, +1177, -2833, -955, -2075, -2172, -364,
+ -1885, -1352, -820, -1599, -843, -1249, -887, -652,
+ -674, -554, -435, -636, -325, -304, -282, -101,
+ -175, +493, +906, +871, +580, +2767, +3674, +3653,
+ +3632, +3656, +3682, +3626, +3572, +3436, +3558, +3534,
+ +3512, +3449, +3388, +3325, +3264, +3186, +3108, +2902,
+ +2697, +2500, +2304, +2219, +343, +179, +271, +154,
+ +38, -6, -50, -110, -170, -154, -138, -138,
+ +1600, +1959, -242, -2667, -2020, -2557, -2582, -1455,
+ +696, +316, +960, +2052, +2120, +1940, +1760, +1292,
+ +824, -310, -932, -1394, -832, -750, -668, -298,
+ -440, +434, +796, +902, +496, +3610, +3652, +3598,
+ +3544, +3583, +3622, +3533, +3444, +3443, +3442, +3441,
+ +3440, +3377, +3314, +3251, +3188, +3109, +3030, +2823,
+ +2616, +2439, +2262, +2053, -204, +179, +50, +17,
+ -16, -48, -80, -112, -144, -144, -144, -144,
+ +1956, +1852, -2091, -3025, -1145, +322, +2045, +1672,
+ +1555, +1328, +1614, +1916, +1706, +1622, +1282, +1502,
+ +1466, +1301, +1393, +940, -792, -1548, -768, -820,
+ -617, +926, +934, +909, +1397, +3323, +3456, +3446,
+ +3436, +3393, +3351, +3388, +3426, +3373, +3321, +3444,
+ +3313, +3264, +3217, +3153, +3090, +2997, +2906, +2686,
+ +2467, +2290, +2115, +1282, -61, +136, +79, +36,
+ -5, -37, -69, -101, -133, -133, -133, -133,
+ +1800, +1746, +669, +1992, +1779, +1665, +1552, +1727,
+ +1390, +1317, +1245, +1269, +1293, +1560, +1316, +1456,
+ +1084, +1121, +1158, +971, +1297, +726, -869, -1343,
+ -794, +1419, +1072, +917, +2299, +3036, +3261, +3294,
+ +3328, +3204, +3080, +3244, +3409, +3305, +3201, +3449,
+ +3186, +3153, +3121, +3056, +2992, +2887, +2783, +2550,
+ +2318, +2143, +1968, +513, +82, +95, +108, +57,
+ +6, -26, -58, -90, -122, -122, -122, -122,
+ +1516, +1832, +1636, +1905, +1406, +1344, +1283, +1589,
+ +1641, +1465, +1291, +1277, +1263, +1386, +1254, +1314,
+ +1118, +1116, +1115, +905, +953, +1160, +1111, +118,
+ -363, +807, +698, +700, +2240, +3325, +2361, +2934,
+ +3252, +2998, +2745, +2924, +3103, +3155, +2952, +3277,
+ +3091, +3057, +3024, +2959, +2894, +2776, +2659, +2414,
+ +2169, +2074, +1981, +255, +65, +68, +73, +44,
+ +17, -15, -47, -79, -111, -111, -111, -111,
+ +1744, +1662, +1581, +1563, +1546, +1536, +1527, +1453,
+ +1380, +1359, +1339, +1286, +1234, +1213, +1193, +1172,
+ +1152, +1112, +1073, +1097, +1122, +826, +1043, +1067,
+ +1092, +964, +837, +741, +2182, +2078, +2487, +2831,
+ +2664, +2793, +2923, +2860, +2798, +3007, +2705, +3106,
+ +2996, +2962, +2928, +2862, +2796, +2666, +2536, +2278,
+ +2020, +1751, +1482, -259, +48, +43, +38, +33,
+ +28, -4, -36, -68, -100, -100, -100, -100,
+ +1684, +1640, +1596, +1584, +1573, +1543, +1513, +1451,
+ +1391, +1359, +1329, +1282, +1236, +1213, +1190, +1168,
+ +1146, +1107, +1069, +1063, +1058, +920, +1038, +996,
+ +955, +924, +894, +880, +1635, +1679, +2235, +2439,
+ +2132, +2451, +2771, +2580, +2644, +2713, +2528, +2742,
+ +2701, +2828, +2699, +2570, +2442, +2383, +2324, +2105,
+ +1887, +1732, +811, -79, +55, +62, +71, +46,
+ +23, -7, -37, -67, -97, -113, -129, -129,
+ +1624, +1618, +1612, +1606, +1601, +1551, +1501, +1451,
+ +1402, +1361, +1320, +1279, +1239, +1214, +1189, +1164,
+ +1140, +1103, +1067, +1031, +995, +1014, +1034, +926,
+ +818, +885, +953, +1021, +1089, +1024, +1472, +2048,
+ +2112, +2110, +2109, +2044, +2491, +2421, +2352, +2379,
+ +2406, +2694, +2471, +2279, +2088, +2100, +2113, +1933,
+ +1754, +1715, +140, +101, +62, +83, +104, +61,
+ +18, -10, -38, -66, -94, -126, -158, -158,
+ +1724, +1788, +1852, +1692, +1532, +1494, +1456, +1418,
+ +1381, +1345, +1311, +1275, +1241, +1214, +1187, +1160,
+ +1134, +1098, +1064, +1029, +995, +996, +998, +935,
+ +873, +877, +883, +792, +702, +657, +1125, +1832,
+ +2284, +1193, +1638, +1796, +2209, +2320, +2176, +2239,
+ +2047, +2560, +2562, +1891, +1734, +1673, +1613, +1744,
+ +1621, +1152, -83, -8, +69, +70, +73, +42,
+ +13, -13, -39, -65, -91, -139, -187, -187,
+ +1824, +1702, +1580, +1522, +1464, +1438, +1412, +1386,
+ +1360, +1331, +1302, +1273, +1244, +1215, +1186, +1157,
+ +1128, +1095, +1062, +1029, +996, +979, +962, +945,
+ +928, +871, +814, +821, +828, +803, +1290, +1617,
+ +1944, +2068, +1168, +1292, +1416, +1708, +1488, +1844,
+ +1688, +2171, +2142, +1249, +1380, +1503, +1626, +1045,
+ -48, +79, +206, +141, +76, +59, +42, +25,
+ +8, -16, -40, -64, -88, -152, -216, -216,
+ +1688, +1615, +1542, +1501, +1460, +1429, +1398, +1367,
+ +1336, +1309, +1284, +1257, +1232, +1205, +1180, +1153,
+ +1128, +1092, +1058, +1022, +988, +968, +950, +930,
+ +912, +861, +812, +793, +776, +595, +672, +971,
+ +1272, +330, +924, +1038, +1152, +1298, +1444, +1910,
+ +1608, +1531, +1200, +515, +344, +259, +176, +251,
+ +72, +122, +174, +128, +84, +64, +46, +26,
+ +8, -18, -44, -70, -96, -144, -192, -192,
+ +1552, +1528, +1504, +1480, +1456, +1420, +1384, +1348,
+ +1312, +1289, +1266, +1243, +1220, +1197, +1174, +1151,
+ +1128, +1091, +1054, +1017, +980, +959, +938, +917,
+ +896, +853, +810, +767, +724, +645, +566, +583,
+ +600, +640, +680, +528, +376, +376, +888, +1464,
+ +1016, +637, +258, +295, +332, +297, +262, +227,
+ +192, +167, +142, +117, +92, +71, +50, +29,
+ +8, -20, -48, -76, -104, -136, -168, -168,
+ +1544, +1521, +1498, +1475, +1452, +1411, +1370, +1329,
+ +1288, +1267, +1248, +1227, +1208, +1187, +1168, +1147,
+ +1128, +1088, +1050, +1010, +972, +948, +926, +902,
+ +880, +843, +808, +771, +736, +677, +620, +609,
+ +600, +614, +628, +546, +464, +238, +2060, +1690,
+ +1576, +1709, +308, +313, +320, +285, +252, +217,
+ +184, +162, +142, +120, +100, +76, +54, +30,
+ +8, -22, -52, -82, -112, -128, -144, -144,
+ +1536, +1514, +1492, +1470, +1448, +1402, +1356, +1310,
+ +1264, +1247, +1230, +1213, +1196, +1179, +1162, +1145,
+ +1128, +1087, +1046, +1005, +964, +939, +914, +889,
+ +864, +835, +806, +777, +748, +711, +674, +637,
+ +600, +588, +576, +564, +552, +612, +160, +1916,
+ +1112, +223, +358, +333, +308, +275, +242, +209,
+ +176, +159, +142, +125, +108, +83, +58, +33,
+ +8, -24, -56, -88, -120, -120, -120, -120,
+ +1536, +1514, +1492, +1470, +1448, +1402, +1356, +1310,
+ +1264, +1246, +1230, +1212, +1196, +1178, +1162, +1144,
+ +1128, +1086, +1046, +1004, +964, +938, +914, +888,
+ +864, +834, +806, +776, +748, +710, +674, +636,
+ +600, +588, +576, +564, +552, +644, +480, +108,
+ +504, +158, +326, +316, +308, +274, +242, +208,
+ +176, +158, +142, +124, +108, +82, +58, +32,
+ +8, -24, -56, -88, -120, -120, -120, -120,
+ +1536, +1514, +1492, +1470, +1448, +1402, +1356, +1310,
+ +1264, +1247, +1230, +1213, +1196, +1179, +1162, +1145,
+ +1128, +1087, +1046, +1005, +964, +939, +914, +889,
+ +864, +835, +806, +777, +748, +711, +674, +637,
+ +600, +588, +576, +564, +552, +420, +288, +348,
+ +408, +351, +294, +301, +308, +275, +242, +209,
+ +176, +159, +142, +125, +108, +83, +58, +33,
+ +8, -24, -56, -88, -120, -120, -120, -120,
+ +1536, +1514, +1492, +1470, +1448, +1402, +1356, +1310,
+ +1264, +1246, +1230, +1212, +1196, +1178, +1162, +1144,
+ +1128, +1086, +1046, +1004, +964, +938, +914, +888,
+ +864, +834, +806, +776, +748, +710, +674, +636,
+ +600, +588, +576, +564, +552, +420, +288, +348,
+ +408, +350, +294, +300, +308, +274, +242, +208,
+ +176, +158, +142, +124, +108, +82, +58, +32,
+ +8, -24, -56, -88, -120, -120, -120, -120
+};
+
+static INT16 TEST_CB_COMPONENT[4096] =
+{
+ +1728, +1730, +1732, +1734, +1736, +1738, +1740, +1742,
+ +1744, +1740, +1736, +1732, +1728, +1796, +1864, +1804,
+ +1744, +1754, +1764, +1774, +1784, +1794, +1804, +1814,
+ +1824, +1774, +1724, +1802, +1880, +1814, +1748, +1810,
+ +1872, +1878, +1884, +1890, +1896, +1910, +1924, +1938,
+ +1952, +1938, +1924, +1910, +1896, +1914, +1932, +1950,
+ +1968, +1974, +1980, +1986, +1992, +1998, +2004, +2010,
+ +2016, +2016, +2016, +2016, +2016, +2016, +2016, +2016,
+ +1710, +1697, +1684, +1704, +1723, +1726, +1730, +1733,
+ +1737, +1738, +1740, +1741, +1743, +1758, +1774, +1757,
+ +1741, +1762, +1783, +1788, +1793, +1774, +1755, +1784,
+ +1813, +1817, +1821, +1825, +1829, +1857, +1885, +1881,
+ +1877, +1849, +1821, +1857, +1894, +1904, +1914, +1924,
+ +1935, +1928, +1922, +1915, +1909, +1922, +1936, +1949,
+ +1963, +1974, +1985, +1997, +2008, +2009, +2011, +2012,
+ +2014, +2017, +2020, +2023, +2026, +2026, +2026, +2026,
+ +1692, +1664, +1637, +1674, +1711, +1715, +1720, +1725,
+ +1730, +1737, +1744, +1751, +1758, +1721, +1684, +1711,
+ +1738, +1770, +1802, +1802, +1802, +1754, +1706, +1754,
+ +1802, +1860, +1918, +1848, +1778, +1900, +2022, +1952,
+ +1882, +1820, +1759, +1825, +1892, +1898, +1905, +1911,
+ +1918, +1919, +1920, +1921, +1922, +1931, +1940, +1949,
+ +1958, +1974, +1991, +2008, +2025, +2021, +2018, +2015,
+ +2012, +2018, +2024, +2030, +2036, +2036, +2036, +2036,
+ +1674, +1631, +1589, +1644, +1698, +1703, +1710, +1716,
+ +1723, +1735, +1748, +1760, +1773, +1763, +1754, +1760,
+ +1767, +1794, +1821, +1800, +1779, +1830, +1881, +1900,
+ +1919, +2047, +2175, +2015, +1855, +1879, +1903, +1927,
+ +1951, +1759, +1824, +1856, +1890, +1892, +1895, +1897,
+ +1901, +1909, +1918, +1926, +1935, +1939, +1944, +1948,
+ +1953, +1974, +1996, +2019, +2041, +2032, +2025, +2017,
+ +2010, +2019, +2028, +2037, +2046, +2046, +2046, +2046,
+ +1656, +1599, +1543, +1614, +1686, +1693, +1701, +1708,
+ +1716, +1734, +1752, +1770, +1788, +1806, +1824, +1810,
+ +1796, +1818, +1840, +2054, +2268, +1650, +1032, +510,
+ -12, -70, -128, +390, +908, +1602, +2296, +2158,
+ +2020, +1699, +1890, +1889, +1888, +1887, +1886, +1885,
+ +1884, +1900, +1916, +1932, +1948, +1948, +1948, +1948,
+ +1948, +1975, +2003, +2030, +2058, +2045, +2033, +2020,
+ +2008, +2020, +2032, +2044, +2056, +2056, +2056, +2056,
+ +1590, +1570, +1551, +1612, +1673, +1579, +1742, +1713,
+ +1685, +1672, +1660, +1711, +1763, +1694, +1626, +1941,
+ +2001, +2060, +583, -654, -1891, -2046, -2201, -2084,
+ -1967, -2049, -2131, -2053, -1975, -1751, -1527, +41,
+ +1609, +2374, +1859, +2000, +1886, +1898, +1912, +1909,
+ +1907, +1900, +1894, +1919, +1945, +1944, +1944, +1943,
+ +1943, +1967, +1992, +2017, +2042, +2032, +2023, +2014,
+ +2006, +2017, +2028, +2039, +2050, +2050, +2050, +2050,
+ +1524, +1542, +1560, +1610, +1661, +1467, +1785, +1719,
+ +1654, +1611, +1568, +1653, +1738, +1839, +1940, +793,
+ -866, -2050, -2210, -2082, -1954, -1902, -1850, -1862,
+ -1874, -1980, -2086, -1936, -1786, -1776, -1766, -1820,
+ -1874, -534, +1829, +2112, +1884, +1911, +1939, +1934,
+ +1930, +1901, +1872, +1907, +1942, +1941, +1940, +1939,
+ +1938, +1960, +1982, +2004, +2027, +2021, +2015, +2009,
+ +2004, +2014, +2024, +2034, +2044, +2044, +2044, +2044,
+ +1586, +1641, +1697, +1704, +1712, +1577, +1699, +1660,
+ +1623, +1613, +1604, +1642, +1681, +1791, -402, -2036,
+ -1877, -2144, -1899, -1942, -1985, -1918, -1851, -1880,
+ -1909, -1959, -2009, -1931, -1853, -1801, -1749, -1617,
+ -1485, -1939, -1882, +96, +2074, +1971, +1869, +1895,
+ +1921, +1885, +1850, +1894, +1939, +1937, +1936, +1934,
+ +1933, +1952, +1972, +1991, +2011, +2008, +2006, +2003,
+ +2002, +2011, +2020, +2029, +2038, +2038, +2038, +2038,
+ +1136, +1229, +1322, +1287, +1252, +1433, +1614, +1603,
+ +1592, +1616, +1640, +1632, +1624, +2256, -1720, -1792,
+ -1864, -1982, -2100, -2058, -2016, -1934, -1852, -1898,
+ -1944, -1938, -1932, -1926, -1920, -1826, -1732, -1670,
+ -1608, -1552, -1496, -1664, -1320, +2288, +1800, +1856,
+ +1912, +1870, +1828, +1882, +1936, +1934, +1932, +1930,
+ +1928, +1945, +1962, +1979, +1996, +1997, +1998, +1999,
+ +2000, +2008, +2016, +2024, +2032, +2032, +2032, +2032,
+ +1552, +1624, +1698, +1674, +1652, +1644, +1638, +1614,
+ +1592, +1611, +1630, +1681, +1733, +1146, -2000, -1787,
+ -1830, -1924, -2019, -2049, -2080, -1986, -1893, -1895,
+ -1898, -1896, -1894, -1860, -1827, -1779, -1731, -1667,
+ -1604, -1615, -1626, -1878, -594, +2063, +1903, +2016,
+ +1873, +2132, +1880, +1884, +1888, +1921, +1955, +1941,
+ +1927, +1925, +1925, +1955, +1987, +2005, +2025, +2043,
+ +2063, +1995, +1927, +2099, +2015, +2095, +2175, +2175,
+ +1456, +1509, +1562, +1551, +1540, +1601, +1662, +1627,
+ +1592, +1606, +1621, +1731, +1842, +37, -2281, -1782,
+ -1796, -1867, -1938, -2041, -2144, -2039, -1934, -1893,
+ -1852, -1854, -1857, -1795, -1734, -1732, -1731, -1665,
+ -1600, -1678, -1757, -1836, +645, +2094, +2007, +1920,
+ +1322, +2139, +1933, +1886, +1840, +1909, +1979, +1952,
+ +1926, +1907, +1888, +1933, +1978, +2015, +2052, +2089,
+ +2126, +1982, +1838, +2174, +1998, +2158, +2318, +2318,
+ +1488, +1520, +1554, +1554, +1556, +1588, +1622, +1606,
+ +1592, +1569, +1547, +1700, +1855, -993, -2049, -1825,
+ -1858, -1905, -1953, -2016, -2080, -1995, -1911, -1858,
+ -1806, -1812, -1819, -1729, -1641, -1685, -1730, -1678,
+ -1628, -1677, -1727, -2194, +1947, +2125, +2046, +945,
+ -2205, +114, +2177, +2144, +1856, +1912, +1970, +1963,
+ +1957, +1935, +1915, +1925, +1937, +1991, +2047, +2181,
+ +2061, +2337, +2613, +1817, +2301, +2157, +2269, +2397,
+ +1520, +1533, +1546, +1559, +1572, +1577, +1582, +1587,
+ +1592, +1533, +1474, +1671, +1868, -2023, -1818, -1869,
+ -1920, -1944, -1968, -1992, -2016, -1952, -1888, -1824,
+ -1760, -1771, -1782, -1665, -1548, -1639, -1730, -1693,
+ -1656, -1677, -1699, -1017, +2226, +1644, +2087, -286,
+ -2148, -2167, -1674, +611, +2384, +2173, +1962, +1975,
+ +1988, +1965, +1942, +1919, +1896, +1969, +2042, +2019,
+ +1484, -1916, -1220, +2484, +1068, -916, +1708, +1964,
+ +1504, +1514, +1526, +1536, +1548, +1550, +1554, +1556,
+ +1560, +1581, +1604, +1786, +689, -2138, -1894, -1905,
+ -1918, -1926, -1935, -1943, -1952, -1878, -1805, -1731,
+ -1658, -1626, -1596, -1549, -1503, -1507, -1513, -1518,
+ -1524, -1526, -1785, +148, +2080, +1995, +2422, -2094,
+ -2003, -2033, -1809, -1665, -1776, -189, +1398, +2536,
+ +2139, +2122, +2105, +2327, +2295, +2204, +2113, +2870,
+ -213, -1669, -1077, -1237, -1653, -1589, +2059, +1931,
+ +1488, +1497, +1506, +1515, +1524, +1525, +1526, +1527,
+ +1528, +1631, +1735, +1902, -490, -2254, -1971, -1943,
+ -1916, -1909, -1902, -1895, -1888, -1805, -1722, -1639,
+ -1556, -1483, -1411, -1434, -1458, -1377, -1297, -1344,
+ -1392, -1376, -1872, +1312, +1935, +1834, +1734, -2622,
+ -2370, -2157, -1945, -1892, -1840, -2039, -2239, -2022,
+ -782, -281, +220, +433, +134, -377, -888, -1655,
+ -1398, -1166, -934, -1374, -1302, -726, +2410, +1898,
+ +1472, +1478, +1486, +1492, +1500, +1498, +1498, +1496,
+ +1496, +1600, +1705, +1666, -933, -1474, -2015, -1964,
+ -1914, -1891, -1869, -1846, -1824, -1731, -1639, -1546,
+ -1454, -1387, -1321, -1191, -1317, -1150, -1240, -1250,
+ -1260, -1545, -1575, +2459, +1885, +2057, +182, -2429,
+ -2225, -2088, -1952, -1928, -1904, -1905, -1907, -2149,
+ -1879, -1835, -1793, -1670, -1803, -1645, -1489, -1491,
+ -1239, -1335, -1431, -1335, -1495, +681, +2345, +2089,
+ +1456, +1461, +1466, +1471, +1476, +1473, +1470, +1467,
+ +1464, +1570, +1676, +1174, -1888, -950, -2060, -1986,
+ -1912, -1874, -1836, -1798, -1760, -1658, -1556, -1454,
+ -1352, -1292, -1232, -1204, -1688, -1180, -1184, -1156,
+ -1128, -1203, -254, +2071, +1836, +2281, -1370, -2237,
+ -2080, -2020, -1960, -1964, -1968, -2028, -2088, -2020,
+ -1952, -1855, -1758, -1725, -1692, -1635, -1578, -1329,
+ -1592, -1504, -1416, -1040, -1688, +2088, +2280, +2280,
+ +1428, +1438, +1450, +1460, +1472, +1463, +1454, +1493,
+ +1533, +1512, +1748, -160, -2068, -1346, -1137, -1775,
+ -1902, -1848, -1794, -1708, -1622, -1544, -1466, -1356,
+ -1247, -1198, -1149, -1196, -1755, -1246, -993, -1012,
+ -1032, -1202, +930, +2023, +1837, +2238, -2480, -2286,
+ -1838, -1799, -1761, -1835, -1909, -1954, -2000, -1982,
+ -1964, -1908, -1853, -1829, -1807, -1749, -1692, -1538,
+ -1642, -1526, -1410, -638, -122, +774, +1926, +1926,
+ +1400, +1417, +1434, +1451, +1469, +1454, +1439, +1520,
+ +1602, +1455, +1820, -1239, -1737, -1743, -726, -1821,
+ -1892, -1822, -1752, -1618, -1485, -1431, -1377, -1259,
+ -1142, -1104, -1066, -1188, -1823, -1313, -803, -869,
+ -936, -1203, +2115, +1976, +1838, +916, -2055, -1569,
+ -1596, -1579, -1563, -1706, -1850, -1881, -1913, -1944,
+ -1976, -1962, -1949, -1935, -1922, -1864, -1807, -1749,
+ -1692, -1548, -1404, -1004, -92, +996, +2084, +2084,
+ +1372, +1394, +1418, +1441, +1465, +1444, +1423, +1483,
+ +1543, +1765, +1732, -2204, -1533, -1611, -1179, -1274,
+ -1882, -1764, -1646, -1560, -1475, -1301, -1127, -1113,
+ -1101, -994, -887, -1052, -1730, -1395, -804, -709,
+ -872, -306, +2051, +1929, +2063, -151, -1597, -1347,
+ -1354, -1326, -1300, -1417, -1535, -1599, -1665, -1730,
+ -1796, -1824, -1852, -1880, -1909, -1883, -1857, -1767,
+ -1678, -1570, -1462, -1434, +1154, +2402, +1858, +1858,
+ +1344, +1373, +1403, +1432, +1462, +1435, +1409, +1446,
+ +1484, +1564, +621, -1890, -1842, -1737, -1633, -728,
+ -1872, -1706, -1541, -1503, -1466, -1428, -1391, -1225,
+ -1060, -884, -709, -917, -1638, -1478, -807, -551,
+ -808, +590, +1988, +1882, +2288, -1218, -1140, -1126,
+ -1112, -1075, -1038, -1129, -1220, -1319, -1418, -1517,
+ -1616, -1686, -1756, -1826, -1896, -1902, -1908, -1786,
+ -1664, -1592, -1520, -1864, +2400, +2016, +2144, +2144,
+ +1348, +1372, +1398, +1424, +1450, +1463, +1477, +1491,
+ +1505, +1729, -607, -1838, -1790, -1735, -1681, -1003,
+ -1350, -1710, -1558, -1519, -1480, -1382, -1285, -1379,
+ -1475, -1208, -941, -611, -793, -796, -800, -611,
+ -680, +1364, +1872, +1932, +1481, -1150, -966, -926,
+ -886, -868, -851, -929, -1009, -1061, -1114, -1230,
+ -1348, -1521, -1695, -1805, -1915, -1900, -1886, -1792,
+ -1698, -1604, -1766, -744, +2326, +2134, +2198, +2198,
+ +1352, +1373, +1395, +1417, +1439, +1492, +1546, +1536,
+ +1526, +1894, -1835, -1787, -1739, -1735, -1731, -1279,
+ -828, -1714, -1577, -1536, -1495, -1337, -1180, -1023,
+ -866, -764, -663, -562, -973, -371, -282, -417,
+ -552, +2138, +1757, +1983, +674, -1083, -793, -726,
+ -660, -662, -665, -731, -798, -804, -811, -945,
+ -1080, -1357, -1635, -1784, -1934, -1899, -1865, -1798,
+ -1732, -1616, -2012, +376, +2252, +2252, +2252, +2252,
+ +1356, +1373, +1391, +1409, +1427, +1425, +1423, +1501,
+ +1579, +907, -1814, -1702, -1847, -1909, -1716, -1634,
+ -786, -1686, -1819, -1712, -1605, -1371, -1139, -921,
+ -705, -656, -608, -384, -416, -233, -308, -477,
+ +376, +1968, +1769, +2033, -5, -839, -651, -606,
+ -562, -584, -606, -660, -715, -739, -763, -963,
+ -1164, -1432, -1702, -1843, -1985, -1977, -1971, -1884,
+ -1798, -2012, -2226, +2152, +2178, +2194, +2210, +2210,
+ +1360, +1374, +1388, +1402, +1416, +1358, +1300, +1466,
+ +1632, -81, -1794, -1619, -1956, -2085, -1702, -1991,
+ -744, -891, -526, -353, -180, -383, -586, -821,
+ -1056, -805, -554, -463, -372, -353, -334, -539,
+ +1304, +1799, +1782, +2085, -684, -597, -510, -487,
+ -464, -506, -548, -590, -632, -674, -716, -982,
+ -1248, -1509, -1770, -1903, -2036, -2057, -2078, -1971,
+ -1864, -1896, -1416, +2392, +2104, +2136, +2168, +2168,
+ +1346, +1358, +1371, +1383, +1396, +1395, +1393, +1552,
+ +1711, -1177, -1762, -2203, -1364, -465, +690, +1942,
+ +1913, +1747, +1837, +1816, +1794, +1889, +1983, +1774,
+ +1564, +548, -468, -299, -386, -391, -398, -147,
+ +1895, +1920, +1946, +1284, -401, -397, -393, -421,
+ -450, -478, -507, -568, -629, -722, -815, -1068,
+ -1321, -1697, -2074, -2082, -2091, -2129, -2168, -2030,
+ -1894, -2028, +142, +2280, +2114, +2082, +2050, +2050,
+ +1332, +1343, +1354, +1365, +1377, +1432, +1487, +1382,
+ +1278, -1763, -195, +1308, +1788, +1667, +1547, +1522,
+ +1498, +1569, +1641, +1681, +1721, +1600, +1480, +1552,
+ +1624, +1901, +2179, +1145, -401, -431, -462, -12,
+ +1974, +1786, +2111, +484, -119, -198, -277, -356,
+ -436, -451, -467, -547, -627, -770, -914, -898,
+ -882, -606, -330, -470, -611, -1435, -2259, -2091,
+ -1924, -2160, +1700, +2168, +2124, +2028, +1932, +1932,
+ +1318, +1327, +1337, +1346, +1357, +1405, +1452, +1420,
+ +1389, +1381, +1629, +1748, +1356, +1495, +1635, +1631,
+ +1627, +1551, +1732, +1689, +1647, +1728, +1809, +1730,
+ +1652, +1686, +1721, +1948, +1921, +874, -430, +363,
+ +1925, +1764, +1859, +148, -28, -95, -160, -291,
+ -422, -423, -426, -557, -688, -370, -309, -280,
+ -251, -570, -890, -858, -826, -563, -301, -1079,
+ -1858, -1636, +2170, +2296, +2166, +2118, +2070, +2070,
+ +1304, +1312, +1321, +1329, +1338, +1378, +1419, +1459,
+ +1500, +1452, +1404, +1420, +1436, +1580, +1724, +1484,
+ +1244, +1022, +1313, +1187, +1062, +1088, +1115, +1397,
+ +1680, +1728, +1777, +1729, +1682, +1922, +1651, +1763,
+ +1876, +1742, +1609, -189, +62, +8, -45, -226,
+ -408, -397, -387, -568, -750, -227, -217, -430,
+ -644, -1047, -1451, -1502, -1554, -1229, -905, -580,
+ -256, -856, +1616, +1912, +2208, +2208, +2208, +2208,
+ +1290, +1304, +1319, +1334, +1350, +1377, +1404, +1271,
+ +1395, +1525, +1655, +1769, +1884, +1802, +1720, +1430,
+ +1141, +1026, +1168, +1037, +908, +700, +491, +331,
+ +172, +873, +1575, +1524, +1731, +1991, +1738, +1774,
+ +1811, +1914, +993, -119, +48, -74, -196, -271,
+ -346, -407, -470, -324, -179, -213, -503, -810,
+ -1117, -1273, -1430, -1636, -1841, -1823, -1551, -1246,
+ -686, +1194, +1026, +1610, +2194, +2194, +2194, +2194,
+ +1276, +1297, +1319, +1341, +1363, +1376, +1390, +1340,
+ +1802, +1854, +1907, +1863, +1820, +1768, +1717, +1377,
+ +1038, +1031, +1024, +889, +755, +568, +381, +290,
+ +200, +19, -162, +553, +1781, +2060, +1827, +1786,
+ +1746, +2086, +378, -50, +35, -156, -348, -316,
+ -284, -419, -554, -337, -121, -456, -791, -934,
+ -1078, -1244, -1411, -1514, -1617, -1907, -1686, -1657,
+ -1116, +1964, +1972, +2076, +2180, +2180, +2180, +2180,
+ +1262, +1289, +1318, +1346, +1375, +1359, +1344, +1632,
+ +1921, +1927, +1934, +1876, +1820, +1702, +1585, +1259,
+ +935, +907, +880, +724, +569, +436, +302, +217,
+ +132, +44, -43, -99, +102, +801, +2011, +1878,
+ +1745, +1426, +2131, +916, -43, -191, -340, -393,
+ -446, -461, -478, -237, -254, -522, -790, -962,
+ -1135, -1519, -1647, -1760, -1872, -1446, -2045, -1827,
+ -1354, +2254, +2278, +2222, +2166, +2166, +2166, +2166,
+ +1248, +1283, +1318, +1353, +1388, +1343, +1298, +1925,
+ +2040, +2001, +1962, +1891, +1820, +1637, +1454, +1143,
+ +832, +784, +736, +560, +384, +304, +224, +144,
+ +64, +70, +76, +18, -40, +54, +1684, +1714,
+ +1744, +1790, +1836, +1882, +1928, +798, -332, -470,
+ -608, -505, -402, -139, -388, -589, -790, -991,
+ -1192, -1794, -1884, -2006, -2128, -2266, -868, +818,
+ +2504, +2288, +2072, +2112, +2152, +2152, +2152, +2152,
+ +1238, +1263, +1290, +1332, +1375, +1301, +1484, +2002,
+ +2009, +1973, +1939, +1871, +1805, +1608, +1411, +1118,
+ +826, +751, +676, +505, +334, +273, +212, +151,
+ +91, +69, +48, +11, -26, +482, +1758, +1771,
+ +1784, +2033, +1771, +1860, +1950, +1989, +2029, +884,
+ -260, -1156, -261, -309, -614, -922, -975, -1411,
+ -1848, -2062, -2019, -697, +626, +2060, +2471, +2273,
+ +2076, +2051, +2026, +2081, +2136, +2136, +2136, +2136,
+ +1228, +1245, +1263, +1313, +1363, +1260, +1670, +2080,
+ +1978, +1947, +1916, +1853, +1791, +1580, +1369, +1094,
+ +820, +718, +616, +450, +285, +243, +201, +159,
+ +118, +69, +20, +4, -13, +910, +1833, +1828,
+ +1824, +229, +1706, +1839, +1972, +1901, +1830, +1983,
+ +2136, +2032, +1416, +1056, +696, +280, +376, +728,
+ +1080, +1767, +2454, +2405, +2356, +2035, +2226, +2193,
+ +2160, +2070, +1980, +2050, +2120, +2120, +2120, +2120,
+ +1218, +1226, +1235, +1292, +1350, +1235, +1888, +2061,
+ +1979, +1935, +1893, +1834, +1776, +1551, +1326, +1070,
+ +814, +685, +556, +395, +235, +212, +189, +166,
+ +145, +116, +88, -68, +33, +1306, +1811, +1949,
+ +1576, -200, -183, +905, +1994, +1956, +1919, +1881,
+ +1844, +2004, +1909, +2005, +2102, +2042, +2239, +2195,
+ +2152, +2043, +1935, +2370, +2038, +2697, +1821, +368,
+ +2244, +2121, +1998, +2051, +2104, +2104, +2104, +2104,
+ +1208, +1208, +1209, +1273, +1338, +1210, +2107, +2043,
+ +1980, +1925, +1871, +1816, +1762, +1523, +1285, +1046,
+ +808, +652, +497, +341, +186, +182, +179, +175,
+ +172, +164, +157, +117, +590, +1958, +1791, +1815,
+ +816, +140, -24, -28, -32, +988, +2008, +2036,
+ +2064, +1977, +1890, +1931, +1972, +2013, +2054, +2127,
+ +2200, +2320, +2440, +2080, +184, -1760, -3192, +336,
+ +2328, +2172, +2016, +2052, +2088, +2088, +2088, +2088,
+ +1222, +1215, +1209, +1266, +1325, +1459, +2104, +2046,
+ +1989, +1945, +1903, +1861, +1819, +1612, +1406, +1136,
+ +866, +715, +564, +446, +328, +295, +263, +230,
+ +199, +481, +764, +711, +1427, +2086, +1721, +1692,
+ +128, -37, +55, -14, -82, -108, -135, +335,
+ +804, +1293, +1783, +2272, +2250, +2197, +1889, +1356,
+ +568, -763, -2095, -3010, -2646, -2931, -2705, +2305,
+ +2196, +2159, +2122, +2117, +2112, +2112, +2112, +2112,
+ +1236, +1223, +1210, +1261, +1313, +1708, +2103, +2050,
+ +1998, +1967, +1937, +1907, +1877, +1702, +1528, +1226,
+ +924, +778, +633, +552, +471, +409, +348, +287,
+ +226, +287, +349, +283, +1241, +1702, +1652, +1826,
+ -48, +43, +134, +1, -132, -181, -230, -343,
+ -456, -670, -884, -202, -544, -946, -1860, -1718,
+ -2088, -2311, -2534, -2469, -2404, -2311, -1706, +2483,
+ +2064, +2146, +2228, +2182, +2136, +2136, +2136, +2136,
+ +1250, +1230, +1211, +1255, +1300, +1957, +2101, +2054,
+ +2007, +1956, +1906, +1856, +1806, +1696, +1586, +1284,
+ +982, +841, +701, +657, +613, +554, +497, +438,
+ +381, +412, +445, +717, +1758, +1782, +1807, +1095,
+ -128, -70, -11, -97, -182, -253, -325, -428,
+ -532, -761, -991, -580, -170, -1033, -873, -1976,
+ -1800, -2018, -2237, -2343, -2450, -2650, -35, +2308,
+ +2092, +2117, +2142, +2151, +2160, +2160, +2160, +2160,
+ +1264, +1238, +1212, +1250, +1288, +2206, +2100, +2058,
+ +2016, +1946, +1876, +1806, +1736, +1690, +1644, +1342,
+ +1040, +905, +770, +763, +756, +701, +646, +591,
+ +536, +539, +542, +897, +1764, +1607, +1962, +365,
+ -208, -182, -156, -194, -232, -326, -420, -514,
+ -608, -853, -1098, -1471, -820, -97, -910, -955,
+ -2024, -2238, -2452, -2474, -2496, -2990, +1636, +2134,
+ +2120, +2088, +2056, +2120, +2184, +2184, +2184, +2184,
+ +1198, +1191, +1185, +1227, +1525, +2065, +2093, +2009,
+ +1925, +1887, +1850, +1781, +1712, +1682, +1653, +1464,
+ +1275, +1130, +986, +937, +889, +840, +792, +743,
+ +696, +684, +674, +1335, +1741, +1839, +1939, +54,
+ -294, -295, -297, -298, -300, -414, -527, -641,
+ -755, -947, -1140, -1732, -1813, -733, -166, -1038,
+ -887, -1234, -1581, -1609, -1636, -1158, +2392, +2279,
+ +2166, +2119, +2072, +2121, +2170, +2170, +2170, +2170,
+ +1132, +1145, +1159, +1205, +1763, +1924, +2086, +1960,
+ +1834, +1829, +1825, +1756, +1688, +1675, +1663, +1586,
+ +1510, +1356, +1202, +1112, +1023, +981, +939, +897,
+ +856, +831, +807, +1774, +1718, +1817, +1405, -512,
+ -380, -409, -438, -403, -369, -502, -635, -768,
+ -902, -1042, -1182, -1482, -1782, -2138, -1982, -610,
+ -262, -486, -711, -744, -777, +162, +2125, +1912,
+ +2212, +2150, +2088, +2122, +2156, +2156, +2156, +2156,
+ +1194, +1146, +1100, +1182, +1776, +1927, +2079, +1863,
+ +1903, +1978, +1799, +1843, +1632, +1619, +1608, +1612,
+ +1617, +1517, +1418, +1351, +1284, +1216, +1149, +1098,
+ +1048, +945, +1099, +1781, +1695, +1954, +422, -566,
+ -530, -554, -579, -571, -565, -686, -806, -927,
+ -1049, -1232, -1416, -1679, -1943, -2342, -2486, -2501,
+ -2773, -2074, -1376, -1671, -2221, +458, +2369, +2137,
+ +2162, +2133, +2104, +2123, +2142, +2142, +2142, +2142,
+ +1256, +1149, +1043, +1160, +1790, +1931, +2073, +1766,
+ +1972, +2129, +1774, +1931, +1576, +1565, +1554, +1639,
+ +1724, +1679, +1635, +1590, +1546, +1453, +1361, +1300,
+ +1240, +1060, +1392, +1788, +1672, +2092, -560, -620,
+ -680, -700, -721, -741, -762, -870, -979, -1087,
+ -1196, -1423, -1650, -1877, -2104, -2291, -2478, -2857,
+ -2724, -2895, -3067, -3110, -3666, +2547, +2103, +2107,
+ +2112, +2116, +2120, +2124, +2128, +2128, +2128, +2128,
+ +1214, +1170, +1128, +1453, +1779, +1692, +1861, +1807,
+ +1753, +1732, +1712, +1803, +1640, +1759, +1623, +1710,
+ +1799, +1666, +1790, +1755, +1719, +1628, +1539, +1497,
+ +1456, +1352, +1504, +1752, +1745, +1445, -902, -898,
+ -894, -907, -921, -935, -950, -1070, -1190, -1310,
+ -1431, -1641, -1852, -2062, -2273, -2431, -2590, -2812,
+ -2779, -2929, -3080, -3279, -2198, +2298, +2187, +2124,
+ +2062, +2081, +2100, +2119, +2138, +2138, +2138, +2138,
+ +1172, +1193, +1214, +1747, +1769, +1710, +2163, +2360,
+ +2046, +1592, +1651, +1677, +1704, +1954, +1693, +1783,
+ +1874, +1654, +1947, +1920, +1893, +1805, +1718, +1695,
+ +1672, +1644, +1617, +1717, +1818, +798, -1245, -1176,
+ -1108, -1115, -1123, -1131, -1139, -1270, -1402, -1534,
+ -1666, -1860, -2054, -2248, -2442, -2572, -2702, -2768,
+ -2834, -2964, -3094, -3192, -219, +2306, +2272, +2142,
+ +2012, +2046, +2080, +2114, +2148, +2148, +2148, +2148,
+ +1194, +1150, +1364, +1784, +1694, +1983, +2272, +1441,
+ +2147, +1980, +1813, +1838, +1864, +1909, +1698, +1823,
+ +1949, +1818, +1943, +1989, +2034, +1933, +1833, +1812,
+ +1792, +1712, +1633, +1649, +1923, -536, -1459, -1390,
+ -1322, -1354, -1388, -1421, -1455, -1566, -1678, -1789,
+ -1901, -2078, -2256, -2433, -2611, -2744, -2878, -2915,
+ -2953, -2998, -3044, -3777, +1633, +2298, +1941, +2015,
+ +2090, +2107, +2124, +2141, +2158, +2158, +2158, +2158,
+ +1216, +1109, +1514, +1823, +1620, +2001, +1870, +1803,
+ +1224, +1600, +1464, +1232, +1000, +1096, +1192, +1352,
+ +1512, +1726, +1940, +2058, +2176, +2062, +1948, +1930,
+ +1912, +1781, +1650, +1583, +2028, -1871, -1674, -1605,
+ -1536, -1595, -1654, -1713, -1772, -1863, -1954, -2045,
+ -2136, -2297, -2458, -2619, -2780, -2917, -3054, -3063,
+ -3072, -3033, -2994, -2827, +2460, +2035, +2122, +2145,
+ +2168, +2168, +2168, +2168, +2168, +2168, +2168, +2168,
+ +1190, +1271, +1610, +1756, +1647, +1523, +1144, +1324,
+ +1249, +1364, +1224, +1211, +1199, +1255, +1566, +1430,
+ +1294, +1404, +1514, +1800, +2087, +2075, +2063, +2003,
+ +1944, +1654, +1621, +1811, +979, -1997, -1903, -1888,
+ -1874, -1927, -1982, -2036, -2091, -2163, -2236, -2308,
+ -2381, -2513, -2646, -2778, -2911, -3005, -3100, -3114,
+ -3129, -3039, -3206, -1084, +2317, +2104, +2148, +2159,
+ +2171, +2175, +2179, +2183, +2187, +2187, +2187, +2187,
+ +1164, +1179, +1195, +1179, +1163, +1302, +1442, +1358,
+ +1274, +1385, +1496, +1447, +1399, +1158, +1429, +1508,
+ +1588, +1594, +1601, +1543, +1486, +1832, +2179, +2077,
+ +1976, +1528, +1593, +1785, -582, -2381, -2133, -2172,
+ -2212, -2261, -2311, -2361, -2411, -2464, -2518, -2572,
+ -2626, -2730, -2834, -2938, -3042, -3094, -3146, -3166,
+ -3186, -3046, -3418, +658, +2174, +2174, +2174, +2174,
+ +2174, +2182, +2190, +2198, +2206, +2206, +2206, +2206,
+ +1202, +1230, +1259, +1272, +1286, +1321, +1356, +1343,
+ +1331, +1405, +1480, +1474, +1470, +1349, +1483, +1522,
+ +1562, +1576, +1591, +1573, +1557, +1589, +1622, +1718,
+ +1816, +1690, +1820, +1694, -2015, -2556, -2330, -2376,
+ -2422, -2610, -2799, -2700, -2602, -2669, -2736, -2803,
+ -2871, -2946, -3022, -3097, -3173, -3182, -3192, -3153,
+ -3115, -3324, -3278, +2256, +2159, +2147, +2136, +2156,
+ +2177, +2189, +2201, +2213, +2225, +2225, +2225, +2225,
+ +1240, +1282, +1325, +1367, +1410, +1340, +1271, +1329,
+ +1388, +1426, +1465, +1503, +1542, +1540, +1539, +1537,
+ +1536, +1559, +1582, +1605, +1628, +1603, +1578, +1617,
+ +1656, +1596, +1536, +1604, -2936, -2476, -2528, -2580,
+ -2632, -2704, -2777, -2785, -2794, -2874, -2955, -3035,
+ -3116, -3163, -3210, -3257, -3304, -3271, -3238, -3141,
+ -3044, -3091, -2114, +2319, +2144, +2121, +2098, +2139,
+ +2180, +2196, +2212, +2228, +2244, +2244, +2244, +2244,
+ +1230, +1255, +1281, +1306, +1333, +1303, +1272, +1338,
+ +1405, +1436, +1468, +1500, +1533, +1535, +1537, +1539,
+ +1542, +1562, +1584, +1605, +1627, +1601, +1577, +1616,
+ +1656, +1807, +1959, -417, -2793, -2797, -2545, -2581,
+ -2618, -2687, -2757, -2794, -2833, -2901, -2968, -3036,
+ -3105, -3145, -3186, -3178, -3171, -3149, -3128, -3058,
+ -2989, -3221, -126, +2281, +2129, +2084, +2040, +2107,
+ +2175, +2189, +2203, +2217, +2231, +2231, +2231, +2231,
+ +1220, +1229, +1238, +1247, +1257, +1266, +1275, +1348,
+ +1422, +1447, +1473, +1499, +1525, +1530, +1536, +1542,
+ +1548, +1567, +1587, +1606, +1626, +1601, +1577, +1616,
+ +1656, +1763, +1871, +1658, -2138, -2862, -2563, -2583,
+ -2604, -2671, -2738, -2805, -2873, -2928, -2983, -3038,
+ -3094, -3128, -3162, -3100, -3038, -3028, -3018, -2976,
+ -2934, -3352, +1862, +2244, +2114, +2048, +1982, +2076,
+ +2170, +2182, +2194, +2206, +2218, +2218, +2218, +2218,
+ +1210, +1234, +1259, +1283, +1308, +1325, +1341, +1390,
+ +1439, +1457, +1477, +1496, +1516, +1525, +1535, +1544,
+ +1554, +1571, +1589, +1607, +1625, +1616, +1608, +1632,
+ +1656, +1718, +1782, +1685, +1845, +528, -2836, -2728,
+ -2622, -2654, -2687, -2719, -2752, -2763, -2773, -2992,
+ -2955, -3030, -3106, -2813, -2777, -3226, -2908, -3134,
+ -3359, -971, +2186, +2270, +2099, +2075, +2052, +2108,
+ +2165, +2175, +2185, +2195, +2205, +2205, +2205, +2205,
+ +1200, +1240, +1280, +1320, +1360, +1384, +1408, +1432,
+ +1456, +1469, +1482, +1495, +1508, +1521, +1534, +1547,
+ +1560, +1576, +1592, +1608, +1624, +1632, +1640, +1648,
+ +1656, +1675, +1694, +1713, +1732, +1871, +986, -827,
+ -2640, -2638, -2636, -2634, -2632, -2598, -2564, -2946,
+ -2816, -2933, -3050, -2783, -3028, -3169, -1774, +293,
+ +2360, +2179, +1998, +2041, +2084, +2103, +2122, +2141,
+ +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192,
+ +1232, +1266, +1300, +1334, +1368, +1390, +1412, +1434,
+ +1456, +1468, +1482, +1494, +1508, +1520, +1534, +1546,
+ +1560, +1578, +1596, +1614, +1632, +1640, +1648, +1656,
+ +1664, +1645, +1628, +1705, +1784, +2101, +1908, +1298,
+ +688, +1071, -594, -1587, -2580, -2891, -3202, -2281,
+ -2640, -2058, -1476, -94, +1032, +2278, +2244, +2209,
+ +2176, +2131, +2088, +2091, +2096, +2111, +2128, +2143,
+ +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192,
+ +1264, +1292, +1320, +1348, +1376, +1396, +1416, +1436,
+ +1456, +1469, +1482, +1495, +1508, +1521, +1534, +1547,
+ +1560, +1580, +1600, +1620, +1640, +1648, +1656, +1664,
+ +1672, +1617, +1562, +1699, +1836, +1821, +1806, +1887,
+ +1968, +1964, +1960, +2020, +2080, +1936, +1792, +1200,
+ +1632, +1889, +2146, +2083, +2020, +2093, +2166, +2079,
+ +1992, +2085, +2178, +2143, +2108, +2121, +2134, +2147,
+ +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192,
+ +1296, +1318, +1340, +1362, +1384, +1402, +1420, +1438,
+ +1456, +1468, +1482, +1494, +1508, +1520, +1534, +1546,
+ +1560, +1582, +1604, +1626, +1648, +1656, +1664, +1672,
+ +1680, +1667, +1656, +1739, +1824, +1811, +1800, +1835,
+ +1872, +1881, +1890, +1819, +1748, +1995, +450, +937,
+ +912, +715, +2056, +2019, +1984, +2035, +2088, +2059,
+ +2032, +2085, +2140, +2129, +2120, +2129, +2140, +2149,
+ +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192,
+ +1328, +1344, +1360, +1376, +1392, +1408, +1424, +1440,
+ +1456, +1469, +1482, +1495, +1508, +1521, +1534, +1547,
+ +1560, +1584, +1608, +1632, +1656, +1664, +1672, +1680,
+ +1688, +1719, +1750, +1781, +1812, +1803, +1794, +1785,
+ +1776, +1798, +1820, +1874, +1928, +1798, +2180, +674,
+ +1216, +2103, +1966, +1957, +1948, +1979, +2010, +2041,
+ +2072, +2087, +2102, +2117, +2132, +2139, +2146, +2153,
+ +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192,
+ +1328, +1344, +1360, +1376, +1392, +1408, +1424, +1440,
+ +1456, +1468, +1482, +1494, +1508, +1520, +1534, +1546,
+ +1560, +1584, +1608, +1632, +1656, +1664, +1672, +1680,
+ +1688, +1718, +1750, +1780, +1812, +1802, +1794, +1784,
+ +1776, +1798, +1820, +1858, +1896, +1750, +1860, +2338,
+ +1792, +2134, +1966, +1956, +1948, +1978, +2010, +2040,
+ +2072, +2086, +2102, +2116, +2132, +2138, +2146, +2152,
+ +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192,
+ +1328, +1344, +1360, +1376, +1392, +1408, +1424, +1440,
+ +1456, +1469, +1482, +1495, +1508, +1521, +1534, +1547,
+ +1560, +1584, +1608, +1632, +1656, +1664, +1672, +1680,
+ +1688, +1719, +1750, +1781, +1812, +1803, +1794, +1785,
+ +1776, +1798, +1820, +1842, +1864, +1958, +2052, +1954,
+ +1856, +1911, +1966, +1957, +1948, +1979, +2010, +2041,
+ +2072, +2087, +2102, +2117, +2132, +2139, +2146, +2153,
+ +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192,
+ +1328, +1344, +1360, +1376, +1392, +1408, +1424, +1440,
+ +1456, +1468, +1482, +1494, +1508, +1520, +1534, +1546,
+ +1560, +1584, +1608, +1632, +1656, +1664, +1672, +1680,
+ +1688, +1718, +1750, +1780, +1812, +1802, +1794, +1784,
+ +1776, +1798, +1820, +1842, +1864, +1958, +2052, +1954,
+ +1856, +1910, +1966, +1956, +1948, +1978, +2010, +2040,
+ +2072, +2086, +2102, +2116, +2132, +2138, +2146, +2152,
+ +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192
+};
+
+static INT16 TEST_CR_COMPONENT[4096] =
+{
+ -2112, -2114, -2116, -2118, -2120, -2122, -2124, -2126,
+ -2128, -2118, -2108, -2098, -2088, -2150, -2212, -2146,
+ -2080, -2100, -2120, -2140, -2160, -2164, -2168, -2172,
+ -2176, -2092, -2008, -2052, -2096, -2132, -2168, -2076,
+ -1984, -2088, -2192, -2168, -2144, -2136, -2128, -2120,
+ -2112, -2126, -2140, -2154, -2168, -2150, -2132, -2114,
+ -2096, -2096, -2096, -2096, -2096, -2096, -2096, -2096,
+ -2096, -2080, -2064, -2048, -2032, -2032, -2032, -2032,
+ -2128, -2113, -2098, -2115, -2132, -2133, -2134, -2135,
+ -2137, -2127, -2117, -2107, -2097, -2117, -2137, -2125,
+ -2114, -2134, -2154, -2159, -2163, -2135, -2108, -2128,
+ -2149, -2132, -2116, -2116, -2115, -2115, -2114, -2098,
+ -2082, -2112, -2142, -2141, -2139, -2133, -2128, -2122,
+ -2117, -2127, -2137, -2147, -2158, -2146, -2134, -2122,
+ -2111, -2108, -2106, -2104, -2102, -2101, -2101, -2101,
+ -2101, -2087, -2073, -2059, -2045, -2045, -2045, -2045,
+ -2144, -2112, -2080, -2112, -2145, -2145, -2145, -2145,
+ -2146, -2136, -2126, -2116, -2107, -2085, -2063, -2105,
+ -2148, -2168, -2189, -2178, -2167, -2107, -2048, -2085,
+ -2122, -2173, -2225, -2180, -2135, -2098, -2061, -2120,
+ -2180, -2136, -2093, -2114, -2135, -2131, -2128, -2125,
+ -2122, -2128, -2135, -2141, -2148, -2142, -2137, -2131,
+ -2126, -2121, -2117, -2112, -2108, -2107, -2107, -2106,
+ -2106, -2094, -2082, -2070, -2058, -2058, -2058, -2058,
+ -2160, -2111, -2062, -2109, -2157, -2156, -2155, -2154,
+ -2155, -2145, -2135, -2125, -2116, -2132, -2148, -2132,
+ -2118, -2154, -2191, -2181, -2170, -2494, -2308, -2393,
+ -2479, -2470, -2461, -2243, -2282, -2353, -2167, -2174,
+ -2182, -2160, -2139, -2135, -2130, -2128, -2128, -2127,
+ -2127, -2129, -2132, -2134, -2138, -2138, -2139, -2139,
+ -2141, -2133, -2127, -2120, -2114, -2112, -2112, -2111,
+ -2111, -2101, -2091, -2081, -2071, -2071, -2071, -2071,
+ -2176, -2110, -2045, -2107, -2170, -2168, -2167, -2165,
+ -2164, -2154, -2145, -2135, -2126, -2180, -2235, -2161,
+ -2088, -2141, -2195, -2440, -2686, -2371, -1033, -398,
+ +236, +305, +375, -3, -894, -2096, -2787, -2485,
+ -2184, -2185, -2187, -2156, -2126, -2127, -2129, -2130,
+ -2132, -2131, -2130, -2129, -2128, -2135, -2142, -2149,
+ -2156, -2147, -2138, -2129, -2120, -2119, -2118, -2117,
+ -2116, -2108, -2100, -2092, -2084, -2084, -2084, -2084,
+ -2112, -2085, -2058, -2112, -2166, -2067, -2225, -2190,
+ -2157, -2107, -2057, -2104, -2151, -2119, -2088, -2632,
+ -2666, -2263, -837, +844, +2526, +3327, +2847, +2847,
+ +2847, +2726, +2606, +2967, +3070, +2968, +2867, +397,
+ -2074, -2745, -2137, -2281, -2169, -2202, -2236, -2190,
+ -2145, -2145, -2147, -2148, -2150, -2152, -2156, -2159,
+ -2163, -2159, -2156, -2152, -2150, -2130, -2111, -2123,
+ -2137, -2127, -2117, -2107, -2097, -2097, -2097, -2097,
+ -2048, -2060, -2073, -2118, -2163, -1967, -2284, -2217,
+ -2150, -2060, -1971, -2074, -2177, -2315, -2454, -1057,
+ +1364, +2990, +2568, +2593, +2619, +2369, +2631, +2508,
+ +2386, +2332, +2278, +2352, +2427, +2913, +2888, +3022,
+ +3156, +1302, -2088, -2406, -2213, -2279, -2345, -2251,
+ -2158, -2161, -2165, -2168, -2172, -2171, -2171, -2170,
+ -2170, -2172, -2175, -2177, -2180, -2142, -2105, -2131,
+ -2158, -2146, -2134, -2122, -2110, -2110, -2110, -2110,
+ -2112, -2163, -2215, -2235, -2255, -1994, -2247, -2194,
+ -2143, -2109, -2076, -2123, -2170, -2270, +700, +3527,
+ +2770, +2035, +2325, +2293, +2263, +2178, +2350, +2265,
+ +2181, +2129, +2078, +2154, +2231, +2521, +2557, +2559,
+ +2562, +3221, +3113, +140, -2832, -2034, -2261, -2199,
+ -2139, -2160, -2182, -2188, -2194, -2189, -2185, -2181,
+ -2177, -2185, -2193, -2201, -2210, -2154, -2098, -2138,
+ -2179, -2165, -2151, -2137, -2123, -2123, -2123, -2123,
+ -1664, -1755, -1846, -1841, -1836, -1767, -2210, -2173,
+ -2136, -2159, -2182, -2173, -2164, -2739, +2830, +2735,
+ +2640, +2361, +2082, +1995, +1908, +1989, +2070, +2023,
+ +1976, +1927, +1878, +1957, +2036, +2131, +2226, +2353,
+ +2480, +2581, +2682, +2943, +2692, -2815, -2178, -2149,
+ -2120, -2160, -2200, -2208, -2216, -2208, -2200, -2192,
+ -2184, -2198, -2212, -2226, -2240, -2166, -2092, -2146,
+ -2200, -2184, -2168, -2152, -2136, -2136, -2136, -2136,
+ -2096, -2166, -2238, -2228, -2220, -2087, -2210, -2173,
+ -2137, -2189, -2243, -2152, -2318, -2031, +3375, +2861,
+ +2605, +2305, +2007, +1851, +1697, +1756, +1815, +1810,
+ +1806, +1756, +1707, +1754, +1801, +1911, +2023, +2149,
+ +2277, +2299, +2323, +2729, +1345, -2439, -2129, -2217,
+ -2307, -2349, -2136, -2179, -2222, -2223, -2224, -2193,
+ -2162, -2171, -2180, -2190, -2199, -2198, -2198, -2213,
+ -2229, -2172, -2115, -2170, -2225, -2113, -2257, -2257,
+ -2016, -2067, -2118, -2105, -2093, -2152, -2211, -2174,
+ -2138, -2221, -2305, -2132, -2472, +212, +2897, +2477,
+ +2570, +2251, +1932, +1709, +1487, +1524, +1561, +1598,
+ +1636, +1586, +1537, +1552, +1567, +1693, +1820, +1947,
+ +2074, +2019, +1964, +2261, -514, -2321, -2080, -2031,
+ -1982, -2283, -2073, -2151, -2229, -2238, -2248, -2194,
+ -2140, -2144, -2149, -2154, -2159, -2231, -2304, -2281,
+ -2258, -2160, -2062, -2188, -2314, -2090, -2378, -2378,
+ -2064, -2094, -2126, -2125, -2125, -2152, -2179, -2159,
+ -2139, -2204, -2270, -2144, -2530, +1688, +2834, +2460,
+ +2343, +2147, +1953, +1678, +1404, +1387, +1370, +1418,
+ +1466, +1416, +1366, +1349, +1332, +1442, +1553, +1663,
+ +1775, +1817, +1861, +2415, -2405, -2457, -1999, -2035,
+ -281, -1464, -2393, -2378, -2363, -2301, -2240, -2195,
+ -2150, -2165, -2181, -2182, -2182, -2199, -2218, -2188,
+ -2159, -2756, -2329, -1934, -2307, -2627, -2179, -2307,
+ -2112, -2123, -2135, -2146, -2158, -2153, -2149, -2144,
+ -2140, -2188, -2236, -2156, -2588, +3164, +2772, +2444,
+ +2116, +2045, +1975, +1648, +1322, +1251, +1181, +1238,
+ +1296, +1246, +1197, +1147, +1098, +1192, +1287, +1381,
+ +1476, +1617, +1758, +1291, -2760, -2083, -2430, -1273,
+ -628, -647, -667, -1582, -2498, -2365, -2233, -2196,
+ -2160, -2187, -2215, -2210, -2206, -2169, -2133, -2096,
+ -2060, -280, -548, -2448, -1788, -860, -1980, -2236,
+ -2112, -2120, -2130, -2140, -2150, -2145, -2141, -2137,
+ -2133, -2147, -2161, -2079, -718, +3207, +2525, +2291,
+ +2057, +1941, +1827, +1553, +1279, +1174, +1070, +1094,
+ +1118, +1044, +970, +976, +983, +1001, +1019, +1165,
+ +1313, +1305, +1555, -212, -2491, -2189, -2401, -867,
+ -615, -642, -671, -603, -536, -1354, -2172, -2271,
+ -2370, -2340, -2311, -2330, -2349, -2315, -2282, -2697,
+ -1321, -420, -543, -394, -757, -741, -2261, -2261,
+ -2112, -2119, -2127, -2135, -2143, -2138, -2134, -2130,
+ -2126, -2106, -2087, -2259, +640, +2995, +2279, +2138,
+ +1998, +1839, +1681, +1459, +1237, +1098, +960, +950,
+ +940, +842, +744, +806, +869, +811, +753, +951,
+ +1150, +995, +1352, -1715, -2222, -2297, -2372, -463,
+ -602, -639, -676, -649, -623, -600, -577, -810,
+ -1044, -1214, -1384, -1426, -1469, -1183, -897, -483,
+ -582, -560, -538, -900, -750, -1134, -2542, -2286,
+ -2112, -2117, -2123, -2129, -2135, -2131, -2127, -2123,
+ -2119, -2017, -1916, -2886, +1262, +2014, +2256, +2097,
+ +1939, +1736, +1534, +1364, +1194, +1022, +850, +806,
+ +762, +736, +710, +508, +818, +604, +646, +752,
+ +859, +1131, +1149, -2865, -2273, -2339, -1639, -425,
+ -493, -522, -553, -566, -581, -677, -773, -661,
+ -550, -567, -585, -586, -588, -657, -727, -572,
+ -675, -668, -661, -798, -679, -1799, -2407, -2151,
+ -2112, -2116, -2120, -2124, -2128, -2124, -2120, -2116,
+ -2112, -2185, -2258, -1723, +1884, +1035, +2234, +2057,
+ +1880, +1634, +1388, +1270, +1152, +946, +740, +662,
+ +584, +630, +676, +466, +1280, +654, +540, +554,
+ +568, +757, -78, -2481, -2324, -2383, -906, -389,
+ -384, -407, -430, -485, -540, -499, -458, -513,
+ -568, -689, -810, -771, -732, -645, -558, -663,
+ -768, -776, -784, -696, -608, -2464, -2272, -2016,
+ -2104, -2110, -2116, -2122, -2129, -2105, -2081, -2105,
+ -2130, -2204, -2536, -84, +1856, +1148, +1209, +1701,
+ +1683, +1507, +1332, +1188, +1045, +837, +630, +518,
+ +407, +489, +572, +398, +1249, +662, +330, +383,
+ +436, +589, -1304, -2350, -2117, -2615, +213, -12,
+ -239, -265, -293, -320, -348, -377, -407, -484,
+ -562, -626, -691, -675, -661, -625, -590, -682,
+ -776, -804, -832, -540, -248, -664, -1848, -2616,
+ -2096, -2104, -2113, -2121, -2130, -2086, -2043, -2095,
+ -2148, -2225, -2815, +1555, +1829, +1519, +697, +1603,
+ +1486, +1381, +1276, +1107, +938, +729, +520, +375,
+ +230, +349, +468, +331, +1219, +670, +121, +212,
+ +304, +423, -2531, -2477, -2423, -1569, +309, -149,
+ -94, -125, -157, -157, -157, -256, -356, -456,
+ -556, -564, -573, -581, -590, -606, -623, -703,
+ -784, -832, -880, -384, +112, -1424, -2448, -2192,
+ -2088, -2098, -2109, -2119, -2131, -2099, -2068, -2100,
+ -2134, -2485, -2325, +2921, +2025, +1536, +1048, +1088,
+ +1385, +1270, +1156, +993, +831, +700, +570, +407,
+ +245, +256, +268, +343, +932, +662, +135, +185,
+ +236, -337, -2445, -2346, -2504, -793, +149, -75,
+ -45, -64, -84, -88, -93, -183, -273, -363,
+ -454, -454, -454, -518, -583, -619, -655, -723,
+ -792, -796, -800, -868, -1960, -2296, -2376, -2248,
+ -2080, -2093, -2106, -2119, -2132, -2113, -2094, -2107,
+ -2120, -2234, -813, +2752, +2222, +1555, +1401, +574,
+ +1284, +1160, +1036, +880, +724, +672, +620, +440,
+ +260, +164, +69, +357, +646, +654, +151, +159,
+ +168, -1096, -2361, -2217, -2586, -18, -11, -3,
+ +4, -4, -13, -21, -30, -110, -191, -271,
+ -352, -344, -336, -456, -576, -632, -688, -744,
+ -800, -760, -720, -584, -2496, -2400, -2304, -2304,
+ -2072, -2086, -2102, -2117, -2133, -2171, -2211, -2170,
+ -2130, -2462, +1045, +2615, +2138, +1656, +1432, +807,
+ +951, +1193, +924, +734, +545, +397, +250, +486,
+ +723, +569, +416, +311, +207, +384, +305, +242,
+ +180, -1825, -2295, -2348, -1891, +69, -19, -10,
+ -3, -7, -12, -16, -22, -65, -107, -182,
+ -258, -309, -361, -477, -593, -640, -688, -736,
+ -784, -752, -720, -1200, -2448, -2384, -2320, -2320,
+ -2064, -2081, -2099, -2116, -2134, -2231, -2329, -2234,
+ -2140, -2691, +2902, +2478, +2055, +1759, +1464, +1041,
+ +618, +1227, +812, +589, +366, +379, +392, +277,
+ +162, +207, +253, +267, +281, +114, -52, +70,
+ +192, -2555, -2230, -2481, -1197, +156, -28, -19,
+ -10, -11, -12, -13, -15, -20, -25, -94,
+ -164, -275, -387, -498, -610, -649, -689, -728,
+ -768, -744, -720, -1816, -2400, -2368, -2336, -2336,
+ -2056, -2075, -2095, -2115, -2135, -2178, -2222, -2138,
+ -2310, -1319, +2743, +2293, +2099, +1893, +1432, +1242,
+ +541, +1036, +1020, +699, +379, +376, +374, +275,
+ +177, +196, +217, +189, +162, +100, +39, +153,
+ -756, -2420, -2293, -2549, -502, +131, -4, -10,
+ -17, -14, -12, -9, -7, -7, -6, -102,
+ -198, -320, -444, -519, -595, -641, -689, -720,
+ -752, -768, -784, -2192, -2320, -2336, -2352, -2352,
+ -2048, -2070, -2092, -2114, -2136, -2126, -2116, -2042,
+ -2480, +52, +2584, +2108, +2144, +2028, +1400, +1444,
+ +464, +78, -308, -470, -632, -394, -156, +18,
+ +192, +187, +182, +113, +44, +87, +130, +237,
+ -1704, -2286, -2356, -2618, +192, +106, +20, -2,
+ -24, -18, -12, -6, +0, +6, +12, -110,
+ -232, -367, -502, -541, -580, -635, -690, -713,
+ -736, -792, -848, -2568, -2240, -2304, -2368, -2368,
+ -2046, -2068, -2091, -2113, -2136, -2121, -2105, -2186,
+ -2523, +1999, +2681, +2740, +1518, +117, -1541, -2639,
+ -2457, -2465, -2474, -2466, -2459, -2498, -2536, -2303,
+ -2070, -995, +81, -76, +24, +35, +47, -150,
+ -2394, -2422, -2450, -1806, +117, +85, +53, +21,
+ -11, -11, -11, -11, -11, -11, -11, -107,
+ -203, -404, -606, -615, -625, -610, -596, -693,
+ -791, -757, -1491, -2401, -2287, -2303, -2319, -2319,
+ -2044, -2067, -2090, -2113, -2137, -2116, -2095, -2074,
+ -2054, +2923, +219, -1748, -2692, -2563, -2435, -2114,
+ -2306, -2193, -2080, -2159, -2239, -2298, -2357, -2320,
+ -2284, -2432, -2580, -1544, +4, -16, -36, -280,
+ -2572, -2302, -2544, -994, +43, +64, +86, +44,
+ +2, -4, -10, -16, -22, -28, -34, -104,
+ -174, -186, -198, -178, -158, -330, -502, -674,
+ -846, -722, -2134, -2234, -2334, -2302, -2270, -2270,
+ -2042, -2065, -2089, -2112, -2137, -2159, -2180, -2154,
+ -2129, -2458, -2532, -2604, -2166, -2218, -2272, -2293,
+ -2315, -2000, -2198, -2219, -2242, -2322, -2401, -2385,
+ -2370, -2285, -2201, -2452, -2704, -1411, +137, -1402,
+ -2174, -2502, -2830, +250, +0, +28, +55, +35,
+ +15, +3, -9, -21, -33, -45, -57, -101,
+ -145, -175, -206, -220, -235, -177, -120, -414,
+ -709, -191, -2489, -2547, -2349, -2349, -2349, -2349,
+ -2040, -2064, -2089, -2113, -2138, -2202, -2267, -2235,
+ -2204, -2207, -2210, -2181, -2152, -2131, -2110, -2217,
+ -1812, -1552, -2317, -2025, -1734, -1578, -1423, -1939,
+ -2456, -2395, -2334, -2081, -2340, -2551, -2250, -2013,
+ -2288, -2446, -2093, -43, -42, -8, +25, +26,
+ +28, +10, -8, -26, -44, -62, -80, -98,
+ -116, -165, -214, -263, -312, -281, -250, -155,
+ -60, -940, -1820, -2348, -2364, -2396, -2428, -2428,
+ -2038, -2058, -2079, -2100, -2122, -2123, -2124, -2285,
+ -2191, -2065, -1940, -1910, -1882, -2232, -2327, -2149,
+ -1717, -1485, -2022, -1759, -1497, -1242, -987, -716,
+ -446, -1226, -2007, -2723, -2160, -2330, -2245, -2175,
+ -2362, -2338, -1034, +109, -28, -19, -10, +15,
+ +41, +19, -3, -25, -47, -89, -131, -141,
+ -151, -208, -266, -355, -445, -458, -472, -405,
+ -83, -1135, -1163, -1895, -2371, -2387, -2403, -2403,
+ -2036, -2053, -2071, -2089, -2107, -2044, -1982, -2080,
+ -1666, -1668, -1671, -1897, -2124, -2590, -2545, -2083,
+ -1622, -1419, -1729, -1495, -1261, -1162, -1064, -774,
+ -484, -314, -144, -806, -2492, -2366, -2240, -2338,
+ -2436, -2486, -489, +4, -15, -30, -45, +4,
+ +54, +28, +2, -24, -50, -116, -182, -184,
+ -186, -252, -318, -448, -578, -636, -694, -656,
+ -106, -2098, -2042, -2210, -2378, -2378, -2378, -2378,
+ -2034, -2047, -2062, -2076, -2091, -2093, -2096, -1650,
+ -1461, -1687, -1913, -2155, -2398, -2676, -2442, -2016,
+ -1591, -1448, -1563, -1341, -1120, -986, -853, -623,
+ -394, -265, -137, +200, +24, -1554, -2363, -2324,
+ -2286, -2122, -2727, -1220, +31, +136, -15, +25,
+ +67, +37, +7, -7, -21, -111, -201, -211,
+ -221, -295, -370, -460, -551, -509, -468, -634,
+ -545, -2805, -2249, -2301, -2353, -2353, -2353, -2353,
+ -2032, -2043, -2054, -2065, -2076, -2143, -2210, -1477,
+ -1768, -1962, -2156, -2414, -2672, -2762, -2340, -1950,
+ -1560, -1479, -1398, -1189, -980, -811, -642, -473,
+ -304, -217, -130, -75, -20, +27, -2486, -2311,
+ -2136, -2527, -2406, -2445, -2484, -979, +14, +47,
+ +80, +46, +12, +10, +8, -106, -220, -238,
+ -256, -339, -422, -473, -524, -639, -754, -1637,
+ -2520, -2232, -2456, -2392, -2328, -2328, -2328, -2328,
+ -2012, -2030, -2049, -2052, -2055, -2191, -2073, -1585,
+ -1867, -2081, -2296, -2526, -2757, -2653, -2294, -1886,
+ -1479, -1380, -1282, -1087, -893, -748, -604, -491,
+ -379, -243, -109, -181, +1, -606, -2493, -2283,
+ -2331, -2481, -2376, -2413, -2452, -2308, -2421, -1350,
+ -278, -124, +30, +88, +145, +127, +109, +27,
+ -56, -278, -501, -1107, -1714, -2162, -2612, -2532,
+ -2453, -2297, -2397, -2369, -2341, -2341, -2341, -2341,
+ -1992, -2018, -2045, -2040, -2035, -2241, -1936, -1695,
+ -1966, -2201, -2436, -2639, -2842, -2545, -2248, -1823,
+ -1398, -1282, -1166, -986, -806, -686, -566, -510,
+ -454, -271, -88, -289, +22, -1239, -2500, -2257,
+ -2526, -388, -2346, -2383, -2421, -2358, -2296, -2490,
+ -2684, -2342, -2001, -1627, -1254, -1176, -1099, -1501,
+ -1904, -2266, -2628, -2510, -2393, -2407, -2422, -2404,
+ -2386, -2362, -2338, -2346, -2354, -2354, -2354, -2354,
+ -1972, -2006, -2040, -2043, -2046, -2194, -1831, -1835,
+ -2097, -2336, -2576, -2735, -2895, -2564, -2234, -1839,
+ -1445, -1279, -1114, -916, -719, -623, -528, -528,
+ -529, -425, -323, -59, -53, -2527, -2443, -2517,
+ -2081, +170, -140, -1312, -2485, -2440, -2395, -2382,
+ -2370, -2400, -2431, -2509, -2589, -2559, -2530, -2500,
+ -2472, -2429, -2387, -2489, -2335, -2939, -2008, -1331,
+ -2447, -2395, -2343, -2355, -2367, -2367, -2367, -2367,
+ -1952, -1994, -2037, -2047, -2058, -2148, -1727, -1977,
+ -2228, -2472, -2716, -2832, -2948, -2584, -2220, -1856,
+ -1492, -1277, -1062, -847, -632, -561, -490, -547,
+ -604, -581, -558, -343, -1152, -2281, -2386, -2523,
+ -1124, -40, +19, +15, +10, -1242, -2495, -2531,
+ -2568, -2459, -2350, -2369, -2388, -2407, -2426, -2477,
+ -2528, -2593, -2659, -2212, -1254, +369, +967, -1026,
+ -2508, -2428, -2348, -2364, -2380, -2380, -2380, -2380,
+ -1948, -1996, -2044, -2060, -2077, -1957, -1837, -2069,
+ -2303, -2545, -2788, -2918, -3049, -2873, -2442, -2026,
+ -1611, -1374, -1138, -965, -793, -732, -672, -707,
+ -743, -847, -953, -2017, -2059, -2441, -2313, -2327,
+ -295, +99, -19, +23, +65, +26, -13, -629,
+ -1246, -1795, -2345, -2509, -2675, -2540, -2406, -1887,
+ -1368, -467, +434, +439, +699, +1162, +856, -2695,
+ -2409, -2413, -2417, -2389, -2361, -2361, -2361, -2361,
+ -1944, -1998, -2052, -2074, -2097, -1767, -1949, -2163,
+ -2378, -2619, -2860, -3005, -3150, -3163, -2664, -2197,
+ -1730, -1472, -1214, -1084, -954, -904, -854, -868,
+ -882, -859, -836, -877, -1942, -2091, -2240, -2389,
+ +22, -18, -57, +32, +121, +14, -93, -9,
+ +76, +149, +221, +166, +110, +143, +175, +239,
+ +304, +379, +455, +530, +605, +676, +235, -2573,
+ -2310, -2398, -2486, -2414, -2342, -2342, -2342, -2342,
+ -1940, -2000, -2060, -2072, -2084, -1640, -1964, -2144,
+ -2325, -2532, -2740, -2899, -3059, -3052, -2790, -2319,
+ -1849, -1569, -1290, -1202, -1115, -1075, -1036, -1028,
+ -1021, -1077, -1135, -503, -2689, -2395, -2359, -1553,
+ +19, -6, -30, +25, +80, +34, -12, +37,
+ +86, +124, +162, +137, +111, +137, +163, +237,
+ +312, +393, +475, +525, +574, +654, -803, -2466,
+ -2339, -2383, -2427, -2375, -2323, -2323, -2323, -2323,
+ -1936, -2002, -2068, -2070, -2072, -1514, -1980, -2126,
+ -2272, -2446, -2620, -2794, -2968, -2942, -2916, -2442,
+ -1968, -1667, -1366, -1321, -1276, -1247, -1218, -1189,
+ -1160, -1041, -922, -1411, -2412, -2189, -2478, -719,
+ +16, +6, -4, +18, +40, +54, +68, +82,
+ +96, +100, +104, +108, +112, +132, +152, +236,
+ +320, +408, +496, +520, +544, +632, -1840, -2360,
+ -2368, -2368, -2368, -2336, -2304, -2304, -2304, -2304,
+ -1898, -1921, -1944, -2111, -1766, -1551, -1848, -1985,
+ -2122, -2318, -2515, -2664, -2813, -3074, -3079, -2828,
+ -2321, -2024, -1729, -1608, -1489, -1457, -1425, -1393,
+ -1362, -1246, -1131, -1879, -2372, -2532, -2693, +331,
+ +25, +40, +55, +54, +54, +71, +88, +105,
+ +123, +151, +180, +208, +237, +83, -70, +48,
+ +167, +248, +329, +346, +363, +733, -2738, -2577,
+ -2416, -2395, -2374, -2353, -2332, -2332, -2332, -2332,
+ -1860, -1840, -1820, -2152, -1460, -1588, -1716, -1844,
+ -1972, -2191, -2411, -2535, -2659, -2950, -2730, -2958,
+ -2674, -2383, -2092, -1897, -1703, -1668, -1633, -1598,
+ -1564, -1452, -1340, -2348, -2333, -2365, -1885, -157,
+ +34, +74, +115, +91, +68, +88, +109, +129,
+ +150, +203, +256, +309, +362, +291, +220, +117,
+ +14, +88, +162, +172, +183, -702, -2612, -2282,
+ -2464, -2422, -2380, -2370, -2360, -2360, -2360, -2360,
+ -2110, -1967, -1824, -1953, -1314, -1513, -1712, -1815,
+ -1918, -2207, -2242, -2453, -2408, -2602, -2541, -2752,
+ -2707, -2692, -2679, -2409, -2140, -2054, -1968, -1867,
+ -1766, -1721, -1677, -2369, -2293, -2516, -948, -53,
+ +75, +92, +110, +95, +82, +105, +129, +152,
+ +177, +222, +268, +313, +359, +354, +350, +441,
+ +533, +472, +411, +414, +674, -1689, -2518, -2339,
+ -2416, -2401, -2386, -2387, -2388, -2388, -2388, -2388,
+ -1848, -1838, -1828, -1754, -1168, -1438, -1708, -1786,
+ -1864, -2225, -2075, -2372, -2158, -2255, -2353, -2546,
+ -2740, -2747, -2755, -2666, -2578, -2441, -2305, -2136,
+ -1968, -1991, -2015, -2390, -2254, -2669, -13, +51,
+ +116, +111, +106, +101, +96, +123, +150, +177,
+ +204, +242, +280, +318, +356, +418, +480, +510,
+ +540, +600, +661, +657, +1166, -2677, -2425, -2396,
+ -2368, -2380, -2392, -2404, -2416, -2416, -2416, -2416,
+ -1882, -1711, -1796, -1369, -1198, -1419, -1640, -1749,
+ -1858, -1977, -1842, -2058, -2019, -2113, -2207, -2366,
+ -2525, -2478, -2689, -2836, -2983, -2759, -2536, -2393,
+ -2250, -2194, -2139, -2357, -2318, -2018, +72, +113,
+ +157, +150, +145, +139, +134, +159, +186, +212,
+ +239, +273, +308, +342, +377, +439, +502, +548,
+ +595, +632, +669, +931, +170, -2666, -2430, -2403,
+ -2376, -2385, -2394, -2403, -2412, -2412, -2412, -2412,
+ -1916, -1840, -2276, -1240, -1228, -1400, -1572, -1712,
+ -1852, -1731, -1610, -1745, -1881, -1972, -2063, -2186,
+ -2310, -2211, -2625, -2751, -2877, -2822, -2768, -2650,
+ -2532, -2398, -2265, -2324, -2383, -1369, +156, +177,
+ +198, +191, +185, +178, +172, +197, +223, +248,
+ +274, +305, +336, +367, +398, +461, +524, +587,
+ +650, +664, +679, +1206, -827, -2656, -2437, -2410,
+ -2384, -2390, -2396, -2402, -2408, -2408, -2408, -2408,
+ -1950, -1953, -1956, -1063, -1194, -1317, -1440, -1435,
+ -1430, -1499, -1314, -1431, -1550, -1638, -1726, -1798,
+ -1871, -1927, -2240, -2409, -2578, -2597, -2616, -2731,
+ -2846, -2554, -2262, -2259, -2511, -527, +176, +207,
+ +239, +231, +224, +217, +210, +234, +259, +284,
+ +309, +336, +364, +391, +419, +482, +546, +609,
+ +673, +744, +816, +936, -2015, -2485, -2187, -2289,
+ -2392, -2395, -2398, -2401, -2404, -2404, -2404, -2404,
+ -1984, -2066, -1636, -886, -1160, -1234, -1308, -1414,
+ -1520, -2037, -2042, -1887, -1732, -1817, -1902, -1923,
+ -1944, -1900, -1856, -2068, -2280, -2372, -2464, -2556,
+ -2648, -2454, -2260, -2194, -2640, +314, +196, +238,
+ +280, +272, +264, +256, +248, +272, +296, +320,
+ +344, +368, +392, +416, +440, +504, +568, +632,
+ +696, +825, +954, +923, -2692, -2315, -2450, -2425,
+ -2400, -2400, -2400, -2400, -2400, -2400, -2400, -2400,
+ -2252, -1953, -1142, -1035, -1441, -1826, -2211, -2244,
+ -2278, -2220, -1908, -1914, -1922, -2001, -2336, -2095,
+ -2111, -2171, -2231, -2131, -2031, -2143, -2255, -2303,
+ -2352, -2306, -2260, -2359, -1689, +442, +269, +305,
+ +341, +333, +325, +317, +309, +329, +349, +369,
+ +389, +415, +441, +468, +494, +536, +579, +669,
+ +760, +797, +1091, -248, -2610, -2406, -2459, -2431,
+ -2404, -2400, -2396, -2392, -2388, -2388, -2388, -2388,
+ -2008, -2096, -1673, -1953, -2234, -2162, -2091, -2051,
+ -2012, -2149, -2286, -2199, -2113, -1930, -2259, -2012,
+ -2278, -2186, -2094, -2194, -2295, -2171, -2047, -2051,
+ -2056, -2158, -2261, -2524, -739, +570, +343, +372,
+ +402, +394, +386, +378, +370, +386, +402, +418,
+ +434, +462, +491, +520, +549, +569, +590, +707,
+ +824, +770, +1228, -1418, -2528, -2498, -2468, -2438,
+ -2408, -2400, -2392, -2384, -2376, -2376, -2376, -2376,
+ -1988, -2191, -2139, -2150, -2163, -2130, -2098, -2081,
+ -2066, -2140, -2216, -2179, -2143, -2066, -2245, -2137,
+ -2285, -2233, -2181, -2225, -2270, -2326, -2382, -2166,
+ -1952, -2250, -2549, -2465, +180, +394, +352, +407,
+ +463, +455, +447, +423, +399, +523, +391, +547,
+ +447, +493, +540, +572, +603, +633, +665, +792,
+ +920, +1094, +1269, -2764, -2446, -2429, -2413, -2412,
+ -2412, -2400, -2388, -2376, -2364, -2364, -2364, -2364,
+ -1968, -2031, -2094, -2093, -2092, -2099, -2106, -2113,
+ -2120, -2133, -2147, -2160, -2174, -2203, -2233, -2262,
+ -2292, -2280, -2269, -2257, -2246, -2226, -2207, -2283,
+ -2360, -2343, -2327, -2406, +586, -38, +363, +443,
+ +524, +516, +508, +468, +428, +660, +380, +676,
+ +460, +525, +591, +624, +658, +699, +741, +878,
+ +1016, +907, +286, -2575, -2364, -2361, -2358, -2387,
+ -2416, -2400, -2384, -2368, -2352, -2352, -2352, -2352,
+ -2020, -2071, -2124, -2080, -2037, -2062, -2089, -2115,
+ -2142, -2152, -2164, -2176, -2188, -2211, -2235, -2259,
+ -2283, -2275, -2267, -2260, -2253, -2249, -2246, -2290,
+ -2336, -2337, -2339, -1205, -71, -16, +296, +496,
+ +441, +469, +497, +381, +521, +635, +493, +735,
+ +465, +544, +624, +640, +656, +747, +839, +899,
+ +960, +1115, -1033, -2493, -2418, -2378, -2339, -2379,
+ -2420, -2408, -2396, -2384, -2372, -2372, -2372, -2372,
+ -2072, -2113, -2155, -2068, -1982, -2027, -2073, -2118,
+ -2164, -2173, -2183, -2193, -2203, -2220, -2238, -2256,
+ -2274, -2270, -2267, -2264, -2261, -2273, -2286, -2299,
+ -2312, -2332, -2352, -2052, -729, +7, +230, +550,
+ +358, +422, +486, +294, +614, +610, +606, +794,
+ +470, +564, +658, +656, +655, +797, +939, +921,
+ +904, +1324, -2352, -2412, -2472, -2396, -2320, -2372,
+ -2424, -2416, -2408, -2400, -2392, -2392, -2392, -2392,
+ -1996, -1930, -1865, -1960, -2055, -2087, -2120, -2153,
+ -2186, -2193, -2201, -2209, -2217, -2229, -2241, -2253,
+ -2265, -2265, -2266, -2267, -2268, -2280, -2294, -2306,
+ -2320, -2342, -2365, -2707, -2538, -1491, -188, +172,
+ +275, +327, +379, +287, +451, +505, +559, +773,
+ +475, +551, +628, +512, +653, +909, +654, +1007,
+ +1104, -739, -2583, -2506, -2430, -2397, -2365, -2396,
+ -2428, -2424, -2420, -2416, -2412, -2412, -2412, -2412,
+ -1920, -2004, -2088, -2108, -2128, -2148, -2168, -2188,
+ -2208, -2214, -2220, -2226, -2232, -2238, -2244, -2250,
+ -2256, -2261, -2266, -2271, -2276, -2289, -2302, -2315,
+ -2328, -2353, -2378, -2339, -2300, -2477, -1630, -719,
+ +192, +232, +272, +280, +288, +400, +512, +752,
+ +480, +539, +598, +369, +652, +767, -142, -1211,
+ -2792, -2547, -2302, -2345, -2388, -2399, -2410, -2421,
+ -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432,
+ -2024, -2070, -2116, -2130, -2144, -2164, -2184, -2204,
+ -2224, -2228, -2232, -2236, -2240, -2244, -2248, -2252,
+ -2256, -2262, -2270, -2276, -2284, -2296, -2310, -2322,
+ -2336, -2319, -2304, -2287, -2272, -2559, -2336, -1855,
+ -1376, -2264, -1104, -520, +64, +384, +704, +704,
+ +192, -44, -280, -1236, -1936, -3018, -2564, -2349,
+ -2392, -2390, -2390, -2388, -2388, -2398, -2410, -2420,
+ -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432,
+ -2128, -2136, -2144, -2152, -2160, -2180, -2200, -2220,
+ -2240, -2242, -2244, -2246, -2248, -2250, -2252, -2254,
+ -2256, -2265, -2274, -2283, -2292, -2305, -2318, -2331,
+ -2344, -2287, -2230, -2237, -2244, -2387, -2530, -2481,
+ -2432, -2456, -2480, -2600, -2720, -2448, -2176, -1904,
+ -2144, -2419, -2694, -2585, -2476, -2451, -2426, -2465,
+ -2504, -2491, -2478, -2433, -2388, -2399, -2410, -2421,
+ -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432,
+ -2104, -2122, -2140, -2158, -2176, -2196, -2216, -2236,
+ -2256, -2256, -2256, -2256, -2256, -2256, -2256, -2256,
+ -2256, -2266, -2278, -2288, -2300, -2312, -2326, -2338,
+ -2352, -2317, -2284, -2281, -2280, -2357, -2436, -2417,
+ -2400, -2408, -2416, -2360, -2304, -2480, -864, -1648,
+ -1408, -1225, -2580, -2509, -2440, -2427, -2416, -2435,
+ -2456, -2446, -2438, -2412, -2388, -2398, -2410, -2420,
+ -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432,
+ -2080, -2108, -2136, -2164, -2192, -2212, -2232, -2252,
+ -2272, -2270, -2268, -2266, -2264, -2262, -2260, -2258,
+ -2256, -2269, -2282, -2295, -2308, -2321, -2334, -2347,
+ -2360, -2349, -2338, -2327, -2316, -2329, -2342, -2355,
+ -2368, -2360, -2352, -2376, -2400, -2256, -2624, -1392,
+ -1696, -2593, -2466, -2435, -2404, -2405, -2406, -2407,
+ -2408, -2403, -2398, -2393, -2388, -2399, -2410, -2421,
+ -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432,
+ -2080, -2108, -2136, -2164, -2192, -2212, -2232, -2252,
+ -2272, -2270, -2268, -2266, -2264, -2262, -2260, -2258,
+ -2256, -2268, -2282, -2294, -2308, -2320, -2334, -2346,
+ -2360, -2348, -2338, -2326, -2316, -2328, -2342, -2354,
+ -2368, -2360, -2352, -2360, -2368, -2352, -2592, -2192,
+ -2560, -2768, -2466, -2434, -2404, -2404, -2406, -2406,
+ -2408, -2402, -2398, -2392, -2388, -2398, -2410, -2420,
+ -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432,
+ -2080, -2108, -2136, -2164, -2192, -2212, -2232, -2252,
+ -2272, -2270, -2268, -2266, -2264, -2262, -2260, -2258,
+ -2256, -2269, -2282, -2295, -2308, -2321, -2334, -2347,
+ -2360, -2349, -2338, -2327, -2316, -2329, -2342, -2355,
+ -2368, -2360, -2352, -2344, -2336, -2448, -2560, -2480,
+ -2400, -2433, -2466, -2435, -2404, -2405, -2406, -2407,
+ -2408, -2403, -2398, -2393, -2388, -2399, -2410, -2421,
+ -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432,
+ -2080, -2108, -2136, -2164, -2192, -2212, -2232, -2252,
+ -2272, -2270, -2268, -2266, -2264, -2262, -2260, -2258,
+ -2256, -2268, -2282, -2294, -2308, -2320, -2334, -2346,
+ -2360, -2348, -2338, -2326, -2316, -2328, -2342, -2354,
+ -2368, -2360, -2352, -2344, -2336, -2448, -2560, -2480,
+ -2400, -2432, -2466, -2434, -2404, -2404, -2406, -2406,
+ -2408, -2402, -2398, -2392, -2388, -2398, -2410, -2420,
+ -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432
+};
+
+/**
+ * 64x64 XRGB Image
+ */
+
+static UINT32 TEST_XRGB_IMAGE[4096] =
+{
+ 0xFF229cdf, 0xFF249de0, 0xFF259fe2, 0xFF2ca5e8, 0xFF229cdf, 0xFF229ce0, 0xFF239de0, 0xFF229ce0,
+ 0xFF229cdf, 0xFF229cdf, 0xFF239ce0, 0xFF249ce0, 0xFF249ce0, 0xFF219ce3, 0xFF1e9ce6, 0xFF209ae2,
+ 0xFF2299dd, 0xFF2199de, 0xFF209adf, 0xFF209ae0, 0xFF1f9be0, 0xFF1e9ae0, 0xFF1d99e0, 0xFF1c98e0,
+ 0xFF1b97df, 0xFF1e96dc, 0xFF2194d9, 0xFF1f93dd, 0xFF1d93e0, 0xFF1b94dc, 0xFF1895d8, 0xFF1c92db,
+ 0xFF208fde, 0xFF1b91de, 0xFF1693df, 0xFF1793df, 0xFF1992df, 0xFF1891df, 0xFF178fdf, 0xFF178edf,
+ 0xFF168dde, 0xFF158cdd, 0xFF148cdc, 0xFF128cda, 0xFF118cd9, 0xFF118bd9, 0xFF128ada, 0xFF1289da,
+ 0xFF1288db, 0xFF1187da, 0xFF1186da, 0xFF1085da, 0xFF0f85d9, 0xFF0f84d9, 0xFF0e83d9, 0xFF0d82d8,
+ 0xFF0d82d8, 0xFF0d81d8, 0xFF0d80d7, 0xFF0d7fd7, 0xFF0d7ed6, 0xFF0d7ed6, 0xFF0d7ed6, 0xFF0d7ed6,
+ 0xFF259fe1, 0xFF27a1e2, 0xFF29a2e3, 0xFF2ba4e6, 0xFF249fe1, 0xFF249fe1, 0xFF249fe1, 0xFF249ee1,
+ 0xFF239ee1, 0xFF249ee1, 0xFF249ee1, 0xFF259de1, 0xFF259de2, 0xFF249de2, 0xFF229de2, 0xFF229ce1,
+ 0xFF229bdf, 0xFF219ce0, 0xFF209ce1, 0xFF209ce2, 0xFF209ce2, 0xFF209ae0, 0xFF2199de, 0xFF1f99df,
+ 0xFF1d98e0, 0xFF1e97e0, 0xFF1f97e0, 0xFF1d96df, 0xFF1c95de, 0xFF1c94e0, 0xFF1c94e1, 0xFF1d93e1,
+ 0xFF1d92e0, 0xFF1b93de, 0xFF1a94dc, 0xFF1a93de, 0xFF1a93e0, 0xFF1992e0, 0xFF1891df, 0xFF188fdf,
+ 0xFF178edf, 0xFF168ede, 0xFF158edd, 0xFF148ddc, 0xFF138ddb, 0xFF138cdb, 0xFF138bdb, 0xFF128adb,
+ 0xFF1289db, 0xFF1288db, 0xFF1187db, 0xFF1186db, 0xFF1085db, 0xFF0f84da, 0xFF0e83d9, 0xFF0e83d9,
+ 0xFF0e83d9, 0xFF0e82d9, 0xFF0e81d8, 0xFF0e80d8, 0xFF0d7fd7, 0xFF0d7fd7, 0xFF0d7fd7, 0xFF0d7fd7,
+ 0xFF27a3e3, 0xFF2aa4e3, 0xFF2ea6e3, 0xFF2aa4e3, 0xFF26a2e3, 0xFF26a1e3, 0xFF25a1e3, 0xFF25a0e3,
+ 0xFF25a0e3, 0xFF25a0e3, 0xFF259fe3, 0xFF269fe3, 0xFF269ee4, 0xFF279ee1, 0xFF279edf, 0xFF259ee0,
+ 0xFF239ee1, 0xFF219ee2, 0xFF209ee4, 0xFF209de4, 0xFF219de3, 0xFF229be0, 0xFF2499dc, 0xFF2299de,
+ 0xFF1f98e0, 0xFF1d99e4, 0xFF1b9ae7, 0xFF1c98e2, 0xFF1c96dc, 0xFF1e94e3, 0xFF2092ea, 0xFF1d94e6,
+ 0xFF1a96e2, 0xFF1c96de, 0xFF1d95da, 0xFF1c94de, 0xFF1b94e1, 0xFF1a93e0, 0xFF1a92e0, 0xFF1991e0,
+ 0xFF1890e0, 0xFF1790df, 0xFF178fde, 0xFF168fde, 0xFF158edd, 0xFF148ddd, 0xFF138cdc, 0xFF138bdc,
+ 0xFF128adc, 0xFF1289dc, 0xFF1188dc, 0xFF1187dd, 0xFF1086dd, 0xFF0f85db, 0xFF0e83d9, 0xFF0e84da,
+ 0xFF0f84da, 0xFF0e83da, 0xFF0e82d9, 0xFF0e81d9, 0xFF0e80d8, 0xFF0e80d8, 0xFF0e80d8, 0xFF0e80d8,
+ 0xFF2aa7e5, 0xFF2da7e4, 0xFF31a8e3, 0xFF2ca6e3, 0xFF27a4e4, 0xFF27a3e4, 0xFF27a3e4, 0xFF27a3e4,
+ 0xFF26a2e4, 0xFF26a2e4, 0xFF27a1e5, 0xFF27a0e5, 0xFF27a0e6, 0xFF26a0e5, 0xFF25a0e4, 0xFF259fe4,
+ 0xFF259ee3, 0xFF239ee5, 0xFF229fe6, 0xFF229fe5, 0xFF229fe4, 0xFF13a5e6, 0xFF1b9fe8, 0xFF16a0e8,
+ 0xFF11a0e7, 0xFF129fef, 0xFF139ef7, 0xFF1b99ec, 0xFF179ae2, 0xFF149ce4, 0xFF1d98e5, 0xFF1c97e6,
+ 0xFF1b96e7, 0xFF1c98dc, 0xFF1d97df, 0xFF1c96e1, 0xFF1c94e2, 0xFF1b94e1, 0xFF1b93e1, 0xFF1a93e0,
+ 0xFF1a92e0, 0xFF1991e0, 0xFF1890e0, 0xFF1790df, 0xFF168fdf, 0xFF158ede, 0xFF158dde, 0xFF148cdd,
+ 0xFF138bdc, 0xFF128add, 0xFF1289dd, 0xFF1188de, 0xFF1187de, 0xFF0f85dc, 0xFF0d83da, 0xFF0f85db,
+ 0xFF1086db, 0xFF0f84db, 0xFF0f83da, 0xFF0e82da, 0xFF0e81da, 0xFF0e81da, 0xFF0e81da, 0xFF0e81da,
+ 0xFF2caae7, 0xFF30aae5, 0xFF34abe3, 0xFF2ea8e4, 0xFF29a6e5, 0xFF28a6e5, 0xFF28a5e5, 0xFF28a5e5,
+ 0xFF28a5e6, 0xFF28a4e6, 0xFF28a3e7, 0xFF28a2e7, 0xFF28a1e8, 0xFF25a2e9, 0xFF23a3ea, 0xFF25a0e8,
+ 0xFF279ee6, 0xFF259fe7, 0xFF23a0e9, 0xFF18a4f5, 0xFF0ea7ff, 0xFF1ba6de, 0xFF558ebb, 0xFF6f839c,
+ 0xFF89797e, 0xFF8d797c, 0xFF917979, 0xFF7f7b94, 0xFF5687af, 0xFF229bd6, 0xFF04a4fd, 0xFF109df4,
+ 0xFF1c97eb, 0xFF1c9ada, 0xFF1c98e4, 0xFF1c97e3, 0xFF1d95e2, 0xFF1c95e2, 0xFF1c94e2, 0xFF1c94e1,
+ 0xFF1b94e1, 0xFF1a93e1, 0xFF1a92e1, 0xFF1991e1, 0xFF1890e1, 0xFF178fe0, 0xFF158edf, 0xFF148dde,
+ 0xFF138cdd, 0xFF128bde, 0xFF128adf, 0xFF1289df, 0xFF1188e0, 0xFF0f85dd, 0xFF0d83da, 0xFF0f85db,
+ 0xFF1187dd, 0xFF1086dc, 0xFF0f84dc, 0xFF0e83db, 0xFF0e81db, 0xFF0e81db, 0xFF0e81db, 0xFF0e81db,
+ 0xFF30abe5, 0xFF36afe8, 0xFF34abe4, 0xFF2faae5, 0xFF2ba8e6, 0xFF36aee8, 0xFF26a6e8, 0xFF29a7e7,
+ 0xFF2ca8e7, 0xFF2da7e6, 0xFF2fa5e5, 0xFF2ca5e7, 0xFF29a4e9, 0xFF2ba5e5, 0xFF2ca5e2, 0xFF10aaef,
+ 0xFF13adf6, 0xFF23a3f8, 0xFF6091a5, 0xFFa6755d, 0xFFec5915, 0xFFff490c, 0xFFfa5504, 0xFFff590f,
+ 0xFFff5d1b, 0xFFff6116, 0xFFfa6412, 0xFFff550f, 0xFFff4b0d, 0xFFfb4918, 0xFFf54823, 0xFF8e737e,
+ 0xFF269eda, 0xFF06a2ff, 0xFF1d97e2, 0xFF1799ea, 0xFF1c97e4, 0xFF1a98e4, 0xFF1898e4, 0xFF1a96e3,
+ 0xFF1b95e3, 0xFF1a94e2, 0xFF1a93e0, 0xFF1992e1, 0xFF1891e2, 0xFF1790e1, 0xFF168fe0, 0xFF158fdf,
+ 0xFF138ede, 0xFF138ddf, 0xFF138ce0, 0xFF128be0, 0xFF1189e0, 0xFF1087de, 0xFF0f85db, 0xFF138ae0,
+ 0xFF0f87dc, 0xFF0f86dc, 0xFF0f85dc, 0xFF0f84dc, 0xFF0e83db, 0xFF0e83db, 0xFF0e83db, 0xFF0e83db,
+ 0xFF34abe2, 0xFF3cb4ec, 0xFF34ace5, 0xFF31abe6, 0xFF2daae8, 0xFF44b6eb, 0xFF24a7ea, 0xFF29aaea,
+ 0xFF2face9, 0xFF32a9e6, 0xFF35a7e3, 0xFF30a7e6, 0xFF2ba8ea, 0xFF25aaf0, 0xFF20adf6, 0xFF4d8ba7,
+ 0xFFb8674c, 0xFFff5510, 0xFFf7650c, 0xFFf86313, 0xFFfa611b, 0xFFf0671f, 0xFFfc6222, 0xFFfb6926,
+ 0xFFf96f29, 0xFFf67122, 0xFFf3721b, 0xFFf26b20, 0xFFf16424, 0xFFff5622, 0xFFff531f, 0xFFff4b17,
+ 0xFFff440e, 0xFFb1615b, 0xFF1f95e0, 0xFF129bf0, 0xFF1c9ae5, 0xFF189ae6, 0xFF159be7, 0xFF1898e6,
+ 0xFF1b95e5, 0xFF1b95e2, 0xFF1995e0, 0xFF1994e1, 0xFF1892e2, 0xFF1792e1, 0xFF1691e0, 0xFF1590df,
+ 0xFF148fdf, 0xFF148fe0, 0xFF148fe1, 0xFF128de1, 0xFF108be0, 0xFF1189de, 0xFF1186dd, 0xFF178fe4,
+ 0xFF0e87db, 0xFF0e87dc, 0xFF0f87dd, 0xFF0f85dc, 0xFF0e84dc, 0xFF0e84dc, 0xFF0e84dc, 0xFF0e84dc,
+ 0xFF36b1eb, 0xFF36b4f0, 0xFF2eafed, 0xFF2caeec, 0xFF2aadec, 0xFF41b4ef, 0xFF29abe9, 0xFF2cabe8,
+ 0xFF2fabe7, 0xFF31abe6, 0xFF32aae6, 0xFF2faae7, 0xFF2ca9e8, 0xFF25a7eb, 0xFF946a5f, 0xFFff3e06,
+ 0xFFf95618, 0xFFe27312, 0xFFf87329, 0xFFf77427, 0xFFf77626, 0xFFf27628, 0xFFf8712b, 0xFFf9772e,
+ 0xFFf97e30, 0xFFf77f2e, 0xFFf5812b, 0xFFf57b2c, 0xFFf5752d, 0xFFfd6a2b, 0xFFfb652a, 0xFFf65e2c,
+ 0xFFf1572e, 0xFFff4810, 0xFFff460f, 0xFF817680, 0xFF02a7f1, 0xFF2496ea, 0xFF199be4, 0xFF1b98e4,
+ 0xFF1d96e5, 0xFF1b96e2, 0xFF1a96e0, 0xFF1995e1, 0xFF1794e3, 0xFF1793e2, 0xFF1692e1, 0xFF1691e0,
+ 0xFF1590df, 0xFF1591e1, 0xFF1591e3, 0xFF138fe1, 0xFF108ce0, 0xFF128be0, 0xFF158ae0, 0xFF168de2,
+ 0xFF0f89dd, 0xFF0f88dd, 0xFF0f88dd, 0xFF0f86dd, 0xFF0f85dc, 0xFF0f85dc, 0xFF0f85dc, 0xFF0f85dc,
+ 0xFF5fc1e7, 0xFF57bee8, 0xFF4fbbe9, 0xFF4ebae6, 0xFF4ebae3, 0xFF51b6ee, 0xFF2eaee8, 0xFF2eade6,
+ 0xFF2fabe5, 0xFF2face7, 0xFF2eade9, 0xFF2eace7, 0xFF2daae5, 0xFF15b2ff, 0xFFec4310, 0xFFf15016,
+ 0xFFf75d1c, 0xFFf87123, 0xFFf9862a, 0xFFf6882d, 0xFFf48b31, 0xFFf48532, 0xFFf47f33, 0xFFf78535,
+ 0xFFfa8c37, 0xFFf88e39, 0xFFf7903a, 0xFFf88b38, 0xFFf98635, 0xFFf87e35, 0xFFf77635, 0xFFf76d34,
+ 0xFFf76532, 0xFFf85e31, 0xFFf95730, 0xFFff5125, 0xFFf65237, 0xFF03a5fd, 0xFF1e9be1, 0xFF1e98e3,
+ 0xFF1f96e5, 0xFF1c97e2, 0xFF1a97df, 0xFF1896e1, 0xFF1795e4, 0xFF1794e3, 0xFF1793e2, 0xFF1692e1,
+ 0xFF1692e0, 0xFF1693e2, 0xFF1794e4, 0xFF1391e2, 0xFF0f8ee0, 0xFF148ee1, 0xFF198ee3, 0xFF148ce1,
+ 0xFF0f8bde, 0xFF0f8ade, 0xFF0f89de, 0xFF0f88dd, 0xFF0f86dd, 0xFF0f86dd, 0xFF0f86dd, 0xFF0f86dd,
+ 0xFF3cb6ee, 0xFF36b4ef, 0xFF30b2f0, 0xFF30b1ee, 0xFF2fb1ec, 0xFF38b0ef, 0xFF2eaee9, 0xFF2faee8,
+ 0xFF31ade6, 0xFF2fafe8, 0xFF2eb1ea, 0xFF31adec, 0xFF29afee, 0xFF30aac8, 0xFFff3d05, 0xFFfa501a,
+ 0xFFf96021, 0xFFf87428, 0xFFf7882f, 0xFFfa9638, 0xFFf59b38, 0xFFf5973b, 0xFFf6923e, 0xFFf89440,
+ 0xFFfa9742, 0xFFfa9a44, 0xFFfa9d46, 0xFFf99845, 0xFFf89444, 0xFFf98d43, 0xFFfa8641, 0xFFf97d3f,
+ 0xFFf9743d, 0xFFf77039, 0xFFf56d35, 0xFFff6122, 0xFFbf6c63, 0xFF129eef, 0xFF229ae8, 0xFF1c99ed,
+ 0xFF179ce4, 0xFF1498f0, 0xFF1b94e1, 0xFF1a96e2, 0xFF1998e3, 0xFF1897e4, 0xFF1896e5, 0xFF1895e4,
+ 0xFF1993e2, 0xFF1792e1, 0xFF1590df, 0xFF1692e2, 0xFF1793e5, 0xFF1490e4, 0xFF128ee2, 0xFF118de3,
+ 0xFF108de3, 0xFF118bde, 0xFF1289d9, 0xFF0f88e2, 0xFF0c89dd, 0xFF1085e0, 0xFF0987e4, 0xFF0987e4,
+ 0xFF40b5e9, 0xFF3bb4e9, 0xFF37b2ea, 0xFF37b2e9, 0xFF38b1e8, 0xFF33b0ea, 0xFF2eaeeb, 0xFF30afe9,
+ 0xFF33afe8, 0xFF30b2ea, 0xFF2eb5ec, 0xFF34aff2, 0xFF25b4f7, 0xFF8d7f86, 0xFFf64f00, 0xFFed5c1e,
+ 0xFFfa6326, 0xFFf7762d, 0xFFf58a35, 0xFFfea242, 0xFFf7ab3f, 0xFFf7a843, 0xFFf7a548, 0xFFf9a34a,
+ 0xFFfaa24c, 0xFFfba64f, 0xFFfcaa52, 0xFFf9a652, 0xFFf7a252, 0xFFfa9c50, 0xFFfd974e, 0xFFfc8d4b,
+ 0xFFfb8348, 0xFFf68341, 0xFFf1823a, 0xFFf5732c, 0xFF718cac, 0xFF179af0, 0xFF2599ef, 0xFF2697e9,
+ 0xFF269bc6, 0xFF1696f1, 0xFF1d91e3, 0xFF1c96e3, 0xFF1b9be3, 0xFF1a99e6, 0xFF1998e9, 0xFF1b97e7,
+ 0xFF1c95e5, 0xFF1891df, 0xFF138dda, 0xFF1992e2, 0xFF1e98ea, 0xFF1592e6, 0xFF0b8de2, 0xFF0e8ee5,
+ 0xFF108fe9, 0xFF128cdf, 0xFF1489d4, 0xFF0e88e6, 0xFF088cdc, 0xFF1184e4, 0xFF0488ec, 0xFF0488ec,
+ 0xFF3eb6ea, 0xFF3bb5eb, 0xFF38b4eb, 0xFF38b4eb, 0xFF38b3eb, 0xFF35b2eb, 0xFF33b1ec, 0xFF34b1eb,
+ 0xFF35b1ea, 0xFF32b3e9, 0xFF30b5e9, 0xFF34b0f0, 0xFF23b6f8, 0xFFc56044, 0xFFf9540c, 0xFFf26322,
+ 0xFFf77029, 0xFFf77d2f, 0xFFf78b35, 0xFFfba142, 0xFFf6b046, 0xFFfbb44f, 0xFFf7b051, 0xFFf9af54,
+ 0xFFfbad56, 0xFFfcb25a, 0xFFfeb75d, 0xFFfab35f, 0xFFf6b061, 0xFFfaac5d, 0xFFfda95a, 0xFFfb9f55,
+ 0xFFf99551, 0xFFf7914b, 0xFFf68d45, 0xFFff7e23, 0xFF1ba5f0, 0xFF129ef4, 0xFF2896f1, 0xFF239fb1,
+ 0xFF6c9600, 0xFF3c9c82, 0xFF179ef8, 0xFF169cf4, 0xFF149de3, 0xFF169ae5, 0xFF1897e7, 0xFF1995e6,
+ 0xFF1a93e5, 0xFF1993e3, 0xFF1793e0, 0xFF1c98e6, 0xFF1a95e5, 0xFF1692e5, 0xFF138fe5, 0xFF138ceb,
+ 0xFF138be3, 0xFF0087e4, 0xFF007cf5, 0xFF1a86d3, 0xFF0d8cf1, 0xFF008fe2, 0xFF0d85ea, 0xFF0886f1,
+ 0xFF3cb7ec, 0xFF3bb7ed, 0xFF3ab6ed, 0xFF39b6ed, 0xFF38b5ed, 0xFF37b5ed, 0xFF37b4ed, 0xFF37b3ed,
+ 0xFF36b3ec, 0xFF34b4e9, 0xFF31b5e5, 0xFF35b1ef, 0xFF21b8fa, 0xFFfd4203, 0xFFfc581e, 0xFFf86a26,
+ 0xFFf47c2d, 0xFFf78431, 0xFFf98c36, 0xFFf8a041, 0xFFf6b54d, 0xFFfec05b, 0xFFf6bc5a, 0xFFf8ba5d,
+ 0xFFfbb861, 0xFFfdbe65, 0xFFffc469, 0xFFfbc16c, 0xFFf5bd70, 0xFFfabc6b, 0xFFfebb66, 0xFFfab160,
+ 0xFFf6a75a, 0xFFf89f55, 0xFFfa984f, 0xFFdf956f, 0xFF08a6fc, 0xFF259ddb, 0xFF159ff3, 0xFF4aa172,
+ 0xFF69a90d, 0xFF62a406, 0xFF5a981b, 0xFF34969b, 0xFF0e99ff, 0xFF1297f2, 0xFF1695e4, 0xFF1793e5,
+ 0xFF1892e5, 0xFF1995e6, 0xFF1a98e7, 0xFF209deb, 0xFF1593df, 0xFF1892e4, 0xFF1a91e9, 0xFF2095eb,
+ 0xFF259dd1, 0xFFd0f772, 0xFFc1f396, 0xFF0083f1, 0xFF1782a0, 0xFF3c7e2f, 0xFF1787cc, 0xFF0b8ada,
+ 0xFF3db9ed, 0xFF3cb8ed, 0xFF3bb8ed, 0xFF3ab7ed, 0xFF39b7ed, 0xFF39b7ed, 0xFF39b6ed, 0xFF3ab6ed,
+ 0xFF3ab6ed, 0xFF37b4ed, 0xFF34b2ec, 0xFF35abf3, 0xFF6e96b3, 0xFFff4601, 0xFFf86520, 0xFFf67329,
+ 0xFFf58131, 0xFFf78b37, 0xFFf9953e, 0xFFf8a649, 0xFFf8b854, 0xFFfcc260, 0xFFf8c465, 0xFFf9c36a,
+ 0xFFfac26e, 0xFFfac773, 0xFFfacb77, 0xFFfbcb7b, 0xFFfccb7e, 0xFFfac87b, 0xFFf8c578, 0xFFf9bc72,
+ 0xFFfbb46d, 0xFFf6b069, 0xFFfeaa57, 0xFF94a0a5, 0xFF13a1f3, 0xFF219df0, 0xFF199eff, 0xFF71c124,
+ 0xFF79b826, 0xFF72b21e, 0xFF6aaa24, 0xFF67a125, 0xFF649a19, 0xFF419d72, 0xFF1f9fcb, 0xFF1994ff,
+ 0xFF1399f1, 0xFF199cf4, 0xFF1ea0f8, 0xFF1b9cff, 0xFF1193f6, 0xFF1293f1, 0xFF1393ec, 0xFF0083ff,
+ 0xFF72cca0, 0xFFcbf982, 0xFFd0ffac, 0xFF79a046, 0xFF337700, 0xFF3a7c03, 0xFF0d8de2, 0xFF0d8edb,
+ 0xFF3fbbee, 0xFF3ebaed, 0xFF3db9ed, 0xFF3cb9ed, 0xFF3bb8ed, 0xFF3bb8ed, 0xFF3cb9ee, 0xFF3cb9ee,
+ 0xFF3db9ef, 0xFF3ab4f1, 0xFF37aff3, 0xFF32b3fe, 0xFFb48f7d, 0xFFff5907, 0xFFf37122, 0xFFf57c2b,
+ 0xFFf68735, 0xFFf7923d, 0xFFf89d45, 0xFFf9ac50, 0xFFf9bb5a, 0xFFf9c465, 0xFFfacd71, 0xFFfacd76,
+ 0xFFfacd7b, 0xFFf7cf80, 0xFFf4d286, 0xFFfcd689, 0xFFffd98c, 0xFFfbd48b, 0xFFf3cf8a, 0xFFf9c885,
+ 0xFFffc17f, 0xFFf5c27d, 0xFFffbc5e, 0xFF48abdc, 0xFF1e9deb, 0xFF1ea2e8, 0xFF1da8e5, 0xFF99d31c,
+ 0xFF8acb22, 0xFF82c427, 0xFF7abc2c, 0xFF75b429, 0xFF70ad25, 0xFF6dab17, 0xFF6ba908, 0xFF5ea912,
+ 0xFF519f54, 0xFF489b6d, 0xFF3e9887, 0xFF3b9592, 0xFF389880, 0xFF449663, 0xFF509446, 0xFF83b43c,
+ 0xFF4f851b, 0xFFafe187, 0xFF9fcc83, 0xFF368011, 0xFF43821c, 0xFF32853c, 0xFF0492f9, 0xFF1092dd,
+ 0xFF40bcee, 0xFF3fbcee, 0xFF3ebbee, 0xFF3dbaed, 0xFF3cbaed, 0xFF3cb9ed, 0xFF3cb9ec, 0xFF3cb9ec,
+ 0xFF3cb8ec, 0xFF3fb4f0, 0xFF43aff5, 0xFF0ebbe9, 0xFFffb897, 0xFFf7814d, 0xFFf57623, 0xFFf6812e,
+ 0xFFf88c39, 0xFFf89943, 0xFFf8a64d, 0xFFf8b257, 0xFFf9bd60, 0xFFfac96d, 0xFFfbd47b, 0xFFfad681,
+ 0xFFfad788, 0xFFfbd98e, 0xFFfbda93, 0xFFfae5a1, 0xFFfed692, 0xFFfadea0, 0xFFf9db98, 0xFFfad694,
+ 0xFFfbd090, 0xFFffd285, 0xFFffc778, 0xFF009afd, 0xFF26a8f2, 0xFF20a4f8, 0xFF53bea5, 0xFFa4da31,
+ 0xFF9dd638, 0xFF97d03a, 0xFF91ca3d, 0xFF8bc539, 0xFF85c035, 0xFF7dbe31, 0xFF74bc2d, 0xFF76b81c,
+ 0xFF77b027, 0xFF72ab25, 0xFF6da724, 0xFF6ba328, 0xFF68a31f, 0xFF58951a, 0xFF78b745, 0xFFbbf181,
+ 0xFF73ad4c, 0xFF417c15, 0xFF508b1e, 0xFF43861c, 0xFF498614, 0xFF17868b, 0xFF0b90f6, 0xFF168ee8,
+ 0xFF42beef, 0xFF41bdee, 0xFF40bcee, 0xFF3fbced, 0xFF3ebbed, 0xFF3dbaec, 0xFF3db9eb, 0xFF3cb8ea,
+ 0xFF3bb7e9, 0xFF39b9f0, 0xFF37bbf7, 0xFF50b5dc, 0xFFff9744, 0xFFfec49d, 0xFFf87a24, 0xFFf88530,
+ 0xFFf9913d, 0xFFf8a049, 0xFFf7af55, 0xFFf8b85d, 0xFFf9c065, 0xFFface75, 0xFFfcdb85, 0xFFfbde8d,
+ 0xFFfae195, 0xFFfee29b, 0xFFffe2a0, 0xFFfbe9a4, 0xFFffbe6b, 0xFFfdde9f, 0xFFffe8a6, 0xFFfbe3a3,
+ 0xFFf8dea0, 0xFFfdd899, 0xFFb6bdab, 0xFF119ff1, 0xFF1ea4e9, 0xFF1a9fff, 0xFF89d465, 0xFFb0e245,
+ 0xFFb0e04e, 0xFFacdc4e, 0xFFa7d94e, 0xFFa1d649, 0xFF9ad345, 0xFF97ce3d, 0xFF94c935, 0xFF8dc534,
+ 0xFF86c133, 0xFF7bbc32, 0xFF6fb731, 0xFF6db330, 0xFF6cae2e, 0xFF7eba3f, 0xFF70a531, 0xFF7bb54f,
+ 0xFF579a20, 0xFF5c9f2b, 0xFF519425, 0xFF80b965, 0xFF609a1d, 0xFF0390e3, 0xFF118ef2, 0xFF1c89f2,
+ 0xFF44c0ef, 0xFF43bfef, 0xFF42beee, 0xFF40bdee, 0xFF3fbcee, 0xFF3fbbed, 0xFF40baeb, 0xFF3eb9ed,
+ 0xFF3cb9ee, 0xFF37b9eb, 0xFF27bcf7, 0xFF949c8f, 0xFFfb9637, 0xFFf9bc7c, 0xFFf9b585, 0xFFf7994a,
+ 0xFFf69b43, 0xFFf6a64e, 0xFFf7b259, 0xFFf8bc66, 0xFFfac672, 0xFFfad380, 0xFFfae08d, 0xFFf9e698,
+ 0xFFf9eba2, 0xFFfeeaa6, 0xFFffeaab, 0xFFfcefa9, 0xFFfaba62, 0xFFfbdc99, 0xFFfff4b9, 0xFFfbecb2,
+ 0xFFf7e6ab, 0xFFffe5a3, 0xFF64b1d1, 0xFF199ff0, 0xFF269fe9, 0xFF0499f2, 0xFFe3f051, 0xFFd5ef58,
+ 0xFFc0e364, 0xFFbde165, 0xFFbae065, 0xFFb5de5d, 0xFFb0dc56, 0xFFaad74e, 0xFFa3d346, 0xFF9bd043,
+ 0xFF93cd3f, 0xFF8cc93e, 0xFF84c63c, 0xFF81c139, 0xFF7dbc36, 0xFF8bc746, 0xFF89c245, 0xFF63a02c,
+ 0xFF65aa2c, 0xFF5ea42d, 0xFF509626, 0xFFa4cf98, 0xFFd9eadd, 0xFFb9ddff, 0xFF389ef4, 0xFF008fd4,
+ 0xFF46c1ef, 0xFF44c0ef, 0xFF43bfef, 0xFF42beef, 0xFF40bdef, 0xFF42bced, 0xFF43baec, 0xFF40baf0,
+ 0xFF3dbaf4, 0xFF35b8e7, 0xFF17bdf7, 0xFFd97f50, 0xFFf79147, 0xFFf7a554, 0xFFffdbba, 0xFFf8a24d,
+ 0xFFf3a549, 0xFFf5ad53, 0xFFf7b55e, 0xFFf9c16f, 0xFFfbcc7f, 0xFFf9d88a, 0xFFf8e595, 0xFFf8eda2,
+ 0xFFf8f5ae, 0xFFfff3b2, 0xFFfff2b6, 0xFFfef5ae, 0xFFf4b659, 0xFFf9db93, 0xFFfeffcd, 0xFFfbf6c1,
+ 0xFFf7edb6, 0xFFfff2ac, 0xFF13a4f7, 0xFF16a5f0, 0xFF18a5e8, 0xFF56b4cd, 0xFFf1f271, 0xFFd5ef84,
+ 0xFFcfe67b, 0xFFcde77c, 0xFFcbe77c, 0xFFc9e672, 0xFFc7e567, 0xFFbce15f, 0xFFb1dd57, 0xFFa9dc51,
+ 0xFFa0da4b, 0xFF9dd749, 0xFF9ad447, 0xFF94cf43, 0xFF8fcb3f, 0xFF88c43c, 0xFF82be39, 0xFF72b430,
+ 0xFF63a928, 0xFF59a028, 0xFF4e9827, 0xFFa0c479, 0xFFfffbf7, 0xFF7fd3f5, 0xFF038fe2, 0xFF0e89e2,
+ 0xFF48c3ef, 0xFF46c2ef, 0xFF45c1f0, 0xFF43c0f0, 0xFF42bff0, 0xFF42beee, 0xFF43bdec, 0xFF41bcef,
+ 0xFF3fbcf2, 0xFF2fc0fe, 0xFF36bdfc, 0xFFf54c00, 0xFFff8a52, 0xFFfaa65e, 0xFFfdc48e, 0xFFfbc185,
+ 0xFFf5ae50, 0xFFf7b65e, 0xFFf9be6c, 0xFFfac978, 0xFFfbd485, 0xFFfede98, 0xFFffe8aa, 0xFFfdeeae,
+ 0xFFf9f5b2, 0xFFfcf6ba, 0xFFfff7c2, 0xFFfcf0b2, 0xFFf7cc6e, 0xFFfbde91, 0xFFfdfcca, 0xFFfffbd1,
+ 0xFFfffdc8, 0xFFcae4c8, 0xFF16a1f2, 0xFF1da4ef, 0xFF12a1f1, 0xFF9fd5b9, 0xFFeaf28c, 0xFFdcf095,
+ 0xFFd9eb90, 0xFFd9ec93, 0xFFd9ec95, 0xFFd6eb8c, 0xFFd4ea83, 0xFFc9e779, 0xFFbfe36f, 0xFFb8e368,
+ 0xFFb1e262, 0xFFafe05e, 0xFFaddf5a, 0xFFa3d952, 0xFF99d449, 0xFF8ecb41, 0xFF84c33a, 0xFF75b833,
+ 0xFF66ac2c, 0xFF5da329, 0xFF559927, 0xFF4b9421, 0xFF2499b9, 0xFF1593fe, 0xFF0993d8, 0xFF0f90d8,
+ 0xFF4ac5ef, 0xFF48c4f0, 0xFF46c2f0, 0xFF45c1f1, 0xFF43c0f1, 0xFF43bfef, 0xFF43bfed, 0xFF42beee,
+ 0xFF41bdf0, 0xFF38bbf0, 0xFF72a1b8, 0xFFff5d1e, 0xFFf97931, 0xFFf5a151, 0xFFf9ad61, 0xFFfee0bd,
+ 0xFFf8b758, 0xFFfabf69, 0xFFfcc87a, 0xFFfcd282, 0xFFfcdc8b, 0xFFfbde8f, 0xFFfbe193, 0xFFfbeba4,
+ 0xFFfbf5b5, 0xFFfaf8c2, 0xFFf9fcce, 0xFFf9ecb7, 0xFFfae183, 0xFFfee290, 0xFFfbfac8, 0xFFfdf8d8,
+ 0xFFfffccb, 0xFF8bcedc, 0xFF189fee, 0xFF25a3ee, 0xFF0b9dfb, 0xFFe8f6a5, 0xFFe4f1a6, 0xFFe4f0a6,
+ 0xFFe4efa6, 0xFFe5f1aa, 0xFFe6f2ad, 0xFFe3f1a6, 0xFFe0ef9e, 0xFFd7ec93, 0xFFcde987, 0xFFc8ea80,
+ 0xFFc2eb78, 0xFFc1ea73, 0xFFc0e96e, 0xFFb1e360, 0xFFa3dd53, 0xFF94d247, 0xFF86c83b, 0xFF78bc35,
+ 0xFF69b030, 0xFF62a52b, 0xFF5b9b27, 0xFF57920a, 0xFF0995fc, 0xFF0d96e5, 0xFF1091eb, 0xFF1091eb,
+ 0xFF4ac5f0, 0xFF49c4f0, 0xFF47c3f1, 0xFF45c2f1, 0xFF44c1f2, 0xFF41c1f2, 0xFF3fc1f2, 0xFF3fbff1,
+ 0xFF3fbcf0, 0xFF32c3fe, 0xFFbe7f6e, 0xFFfe6526, 0xFFf67b35, 0xFFf59a4d, 0xFFf8ab5c, 0xFFfbd0a0,
+ 0xFFf7c783, 0xFFfec16b, 0xFFfdd17f, 0xFFfbdb87, 0xFFf9e590, 0xFFf8ed9a, 0xFFf7f4a5, 0xFFfbea9a,
+ 0xFFffdf8e, 0xFFfce3a0, 0xFFf7e6b1, 0xFFfceecc, 0xFFfffbcb, 0xFFfff3c7, 0xFFfcf1c3, 0xFFfef5d2,
+ 0xFFfffcd3, 0xFF4bb5e7, 0xFF21a5ed, 0xFF1ca2ee, 0xFF3daae2, 0xFFeef6ac, 0xFFe6f2b1, 0xFFe8f2b5,
+ 0xFFe9f3b8, 0xFFeaf4ba, 0xFFebf5bc, 0xFFe8f3b6, 0xFFe6f2af, 0xFFe0f0a8, 0xFFdbeea2, 0xFFd6ef9a,
+ 0xFFd1f092, 0xFFc9ed82, 0xFFc1eb73, 0xFFb0e362, 0xFFa1dc51, 0xFF94d347, 0xFF88ca3e, 0xFF7bbf38,
+ 0xFF6eb433, 0xFF66a92e, 0xFF5da01b, 0xFF3d9448, 0xFF0a93f6, 0xFF0e94ec, 0xFF1193f0, 0xFF1193f0,
+ 0xFF4bc5f1, 0xFF4ac5f1, 0xFF48c4f1, 0xFF47c3f2, 0xFF45c3f2, 0xFF40c3f4, 0xFF3bc4f6, 0xFF3cbff3,
+ 0xFF3ebbf0, 0xFF2dcaff, 0xFFff5d25, 0xFFfe6d2f, 0xFFf37d39, 0xFFf59348, 0xFFf8a958, 0xFFf7c083,
+ 0xFFf7d7ae, 0xFFffc36d, 0xFFffda84, 0xFFfbe48c, 0xFFf7ee94, 0xFFf8ed9e, 0xFFfaeca7, 0xFFf9f1b4,
+ 0xFFf8f6c1, 0xFFfcf6c8, 0xFFfff6d0, 0xFFfef2d3, 0xFFfcf4ba, 0xFFfffee8, 0xFFf7fdea, 0xFFfdfde3,
+ 0xFFfffcdc, 0xFF0b9df1, 0xFF2aaaed, 0xFF1baaf6, 0xFF80c8da, 0xFFfdffbb, 0xFFe8f2bd, 0xFFebf4c4,
+ 0xFFeff7cb, 0xFFeff7cb, 0xFFeff7cb, 0xFFedf6c5, 0xFFebf5c0, 0xFFeaf4be, 0xFFe8f3bd, 0xFFe4f4b4,
+ 0xFFe0f6ab, 0xFFd0f191, 0xFFc1ec77, 0xFFb0e463, 0xFF9edb4e, 0xFF95d448, 0xFF8bcc42, 0xFF7fc23b,
+ 0xFF73b935, 0xFF6aac31, 0xFF60a510, 0xFF229687, 0xFF0b91f1, 0xFF0e93f3, 0xFF1294f5, 0xFF1294f5,
+ 0xFF4cc6f1, 0xFF4bc5f2, 0xFF49c5f2, 0xFF47c4f2, 0xFF46c4f2, 0xFF43c4f1, 0xFF40c4f0, 0xFF42c0f3,
+ 0xFF39c1f6, 0xFF5eacca, 0xFFfb591e, 0xFFf36e31, 0xFFf88135, 0xFFfb923f, 0xFFfbaf5e, 0xFFffc373,
+ 0xFFfde2ba, 0xFFffcd75, 0xFFffd372, 0xFFffe584, 0xFFfff796, 0xFFfef4a2, 0xFFfdf1ae, 0xFFfff8c2,
+ 0xFFfcf8cd, 0xFFfef8d2, 0xFFfff9d6, 0xFFfef6e1, 0xFFfcf5dd, 0xFFfffbee, 0xFFfbfce8, 0xFFfffce0,
+ 0xFFb2e0e8, 0xFF19a4f0, 0xFF26abec, 0xFF16a8f6, 0xFFc2e4d8, 0xFFf9fac5, 0xFFeff6cb, 0xFFf0f7ce,
+ 0xFFf1f8d2, 0xFFf1f8d1, 0xFFf2f9d1, 0xFFf1f9cd, 0xFFf1f9ca, 0xFFf2fbca, 0xFFf4fdca, 0xFFe7f8b6,
+ 0xFFdaf3a2, 0xFFcbef8a, 0xFFbcec71, 0xFFb0e661, 0xFFa5e151, 0xFF9ad949, 0xFF8fd240, 0xFF83c73b,
+ 0xFF77bc35, 0xFF6ab31d, 0xFF5ea905, 0xFF138dea, 0xFF1193ef, 0xFF1093f0, 0xFF0f93f0, 0xFF0f93f0,
+ 0xFF4dc6f2, 0xFF4cc6f2, 0xFF4ac5f3, 0xFF48c5f3, 0xFF47c5f3, 0xFF46c4ef, 0xFF46c4eb, 0xFF48c0f3,
+ 0xFF34c7fb, 0xFF989591, 0xFFfc6428, 0xFFf1773b, 0xFFfc8432, 0xFFff9135, 0xFFffb564, 0xFFffbe5a,
+ 0xFFf3ddb6, 0xFFccd097, 0xFFb4cea5, 0xFFb0d3b1, 0xFFabd7bd, 0xFFc3e1bf, 0xFFdaebc1, 0xFFf5fdc7,
+ 0xFFffffbd, 0xFFfffecd, 0xFFfffcdc, 0xFFfffce0, 0xFFfbfce5, 0xFFfdfbe6, 0xFFfffae7, 0xFFfffbdd,
+ 0xFF61c4f4, 0xFF26aaee, 0xFF22abec, 0xFF10a7f6, 0xFFffffd7, 0xFFf5f5d0, 0xFFf6fad9, 0xFFf4f9d9,
+ 0xFFf2f9da, 0xFFf3fad8, 0xFFf4fbd7, 0xFFf5fcd5, 0xFFf7fdd4, 0xFFf3face, 0xFFf0f7c8, 0xFFe2f4b0,
+ 0xFFd4f199, 0xFFc5ee82, 0xFFb7eb6b, 0xFFb1e95f, 0xFFabe754, 0xFF9fdf49, 0xFF94d83f, 0xFF87cc3a,
+ 0xFF7bc034, 0xFF6bb425, 0xFF5ba332, 0xFF0495f9, 0xFF1795ee, 0xFF1293ed, 0xFF0c91eb, 0xFF0c91eb,
+ 0xFF4fc8f3, 0xFF4dc8f3, 0xFF4cc8f4, 0xFF4bc8f4, 0xFF49c8f4, 0xFF47c5f2, 0xFF45c2ef, 0xFF42c2f8,
+ 0xFF34c8ff, 0xFFdf6746, 0xFFff632a, 0xFFff701b, 0xFFe18b53, 0xFFa4a185, 0xFF63c1cd, 0xFF26c0ff,
+ 0xFF2ab8ff, 0xFF25b5f1, 0xFF27b7f9, 0xFF26b5f6, 0xFF23b3f2, 0xFF24b5fa, 0xFF25b7ff, 0xFF189ddf,
+ 0xFF43bbf4, 0xFF9edae8, 0xFFf9f9dc, 0xFFf3fbe6, 0xFFffffea, 0xFFfdffe6, 0xFFfafce2, 0xFFffffff,
+ 0xFF1ea8ef, 0xFF1ca8f1, 0xFF1ba8f2, 0xFF5bc4f1, 0xFFffffe7, 0xFFfbf9e1, 0xFFfbfce3, 0xFFf8fbe0,
+ 0xFFf5fadd, 0xFFf5fbdb, 0xFFf5fbda, 0xFFf6fcd7, 0xFFf6fdd3, 0xFFf0f8c9, 0xFFebf4be, 0xFFdff2a9,
+ 0xFFd4f094, 0xFFc7f47b, 0xFFbaf862, 0xFFb0ef58, 0xFFa6e64e, 0xFFa3e248, 0xFF98d73a, 0xFF8acd38,
+ 0xFF7bc435, 0xFF70b821, 0xFF3b9c84, 0xFF0d93f4, 0xFF1394ed, 0xFF1193e9, 0xFF0f92e6, 0xFF0f92e6,
+ 0xFF50c9f4, 0xFF4fcaf4, 0xFF4ecaf5, 0xFF4dcaf5, 0xFF4ccaf6, 0xFF48c5f4, 0xFF45c0f3, 0xFF47c2ef,
+ 0xFF4ac4eb, 0xFFff521f, 0xFFa79a92, 0xFF51b7e6, 0xFF28c7ff, 0xFF2cc4f9, 0xFF31c1f1, 0xFF3fbbf0,
+ 0xFF37c0ef, 0xFF39b9f0, 0xFF3bb3f1, 0xFF38b5f4, 0xFF36b7f7, 0xFF32b9f0, 0xFF2fbbe8, 0xFF2fb8eb,
+ 0xFF2fb5ed, 0xFF20acf3, 0xFF10a3fa, 0xFF70c9f3, 0xFFf5f9df, 0xFFf6fbde, 0xFFf6fdde, 0xFFd8ebe4,
+ 0xFF11a5ee, 0xFF2db2f5, 0xFF14a5f8, 0xFFa5e2ec, 0xFFfffff8, 0xFFfffef3, 0xFFfffded, 0xFFfcfde6,
+ 0xFFf8fce0, 0xFFf7fcde, 0xFFf6fcdd, 0xFFf6fcd8, 0xFFf5fdd3, 0xFFedf7c4, 0xFFe5f1b4, 0xFFe5f5b8,
+ 0xFFe4f9bb, 0xFFecfed2, 0xFFf3ffe9, 0xFFedfedb, 0xFFe8f9cd, 0xFFcaef89, 0xFF9cd636, 0xFF84c72e,
+ 0xFF6bb826, 0xFF6cb315, 0xFF1a95d6, 0xFF1591ef, 0xFF1093eb, 0xFF1193e6, 0xFF1294e1, 0xFF1294e1,
+ 0xFF52cbf4, 0xFF50caf4, 0xFF4ecaf4, 0xFF4ccaf3, 0xFF4ac9f3, 0xFF48c8f5, 0xFF46c7f6, 0xFF40bfed,
+ 0xFF41bfeb, 0xFF41d4f9, 0xFF33c9fc, 0xFF2fc9ff, 0xFF42c3ec, 0xFF40c3f4, 0xFF3ec3fc, 0xFF35bbf4,
+ 0xFF33bbf3, 0xFF49bdf7, 0xFF39b7f9, 0xFF37b7f6, 0xFF35b7f2, 0xFF2eb5f4, 0xFF28b3f5, 0xFF2fbbf8,
+ 0xFF2fbaf2, 0xFF30b5f2, 0xFF31b0f1, 0xFF1facf6, 0xFF0dabed, 0xFF7fd2ed, 0xFFffffe6, 0xFF80d9d2,
+ 0xFF2faaf8, 0xFF1dafec, 0xFF03aae6, 0xFFfff8ff, 0xFFfffffe, 0xFFfffff9, 0xFFfffdf4, 0xFFfdfeeb,
+ 0xFFfbfee3, 0xFFf9fde1, 0xFFf7fce0, 0xFFf5fdd8, 0xFFf4fdcf, 0xFFf5fce2, 0xFFf6fde8, 0xFFf3fde8,
+ 0xFFf1fde9, 0xFFebfdd3, 0xFFe6fdbe, 0xFFe0f8ba, 0xFFdaf2b7, 0xFFeafcd2, 0xFFf2fde6, 0xFFb7de8d,
+ 0xFF84c73d, 0xFF9ab848, 0xFF14a1f9, 0xFF0494f3, 0xFF1094ef, 0xFF1095ec, 0xFF1095e9, 0xFF1095e9,
+ 0xFF54ccf5, 0xFF51cbf4, 0xFF4ecaf3, 0xFF4cc9f2, 0xFF49c8f1, 0xFF48cbf5, 0xFF48cef9, 0xFF40c4f3,
+ 0xFF49cafc, 0xFF40c2f1, 0xFF47caf5, 0xFF46c7f4, 0xFF46c4f3, 0xFF39b5ee, 0xFF2ca5e8, 0xFF2eb1e1,
+ 0xFF56c1ea, 0xFF6dc9e9, 0xFF37c2e5, 0xFF51caeb, 0xFF6bd2f1, 0xFF74d1f5, 0xFF7dcff9, 0xFF56c7f8,
+ 0xFF1fafe8, 0xFF25b1ee, 0xFF2cb3f4, 0xFF3eb5f9, 0xFF2bb3ee, 0xFF1baff5, 0xFF32b5f0, 0xFF3fb2f9,
+ 0xFF26a9f2, 0xFF1faeeb, 0xFF3fb8f4, 0xFFfcfff3, 0xFFffffff, 0xFFffffff, 0xFFfffefb, 0xFFfefff1,
+ 0xFFfeffe6, 0xFFfbffe5, 0xFFf8fde3, 0xFFf5fdd7, 0xFFf3fecb, 0xFFf5fbeb, 0xFFf7feee, 0xFFf2fdde,
+ 0xFFedfccf, 0xFFe3f9b0, 0xFFd9f692, 0xFFd2f48b, 0xFFccf184, 0xFFceee97, 0xFFd0eaa9, 0xFFdaebc1,
+ 0xFFf4fbe9, 0xFF7fc679, 0xFF5ac1ff, 0xFF1aa1eb, 0xFF1195f2, 0xFF0f96f2, 0xFF0e97f2, 0xFF0e97f2,
+ 0xFF54cdf5, 0xFF52ccf4, 0xFF4fcbf3, 0xFF4dc9f3, 0xFF4ac8f2, 0xFF49c6f2, 0xFF47c4f2, 0xFF49d2f3,
+ 0xFF46c8f3, 0xFF4dc5fc, 0xFF2c9add, 0xFF1883cd, 0xFF046cbe, 0xFF0080c5, 0xFF0f96d4, 0xFF2eaddb,
+ 0xFF60c6eb, 0xFF76cdef, 0xFF51caea, 0xFF69d2f0, 0xFF81daf5, 0xFF9ae4f7, 0xFFb3eff9, 0xFFcffaff,
+ 0xFFe3feff, 0xFF9ae1ff, 0xFF48bcf7, 0xFF11b5dd, 0xFF32aef0, 0xFF28acfc, 0xFF31b2f3, 0xFF34b1f6,
+ 0xFF25adf0, 0xFF26acf6, 0xFF98d1fc, 0xFFfffdf8, 0xFFffffff, 0xFFfffffb, 0xFFfefff4, 0xFFfdffee,
+ 0xFFfcfde7, 0xFFfbfee4, 0xFFfaffe0, 0xFFf8fde7, 0xFFf7fcef, 0xFFf3fbeb, 0xFFeffdd9, 0xFFe9fbc2,
+ 0xFFe3f9ac, 0xFFd9f49b, 0xFFceef8b, 0xFFc1ea76, 0xFFb4e562, 0xFFabdd5a, 0xFFa2d261, 0xFFc1e98e,
+ 0xFFdbe8b9, 0xFF96d4ff, 0xFF8ed0fa, 0xFF42aeee, 0xFF1095f1, 0xFF1096f1, 0xFF0f96f1, 0xFF0f96f1,
+ 0xFF55cef5, 0xFF53ccf4, 0xFF50cbf4, 0xFF4ecaf4, 0xFF4cc8f4, 0xFF51caf7, 0xFF57cbfa, 0xFF45c0ea,
+ 0xFF1a75c7, 0xFF0058ad, 0xFF015bb4, 0xFF066fc0, 0xFF0b84cd, 0xFF0093ce, 0xFF11a7e0, 0xFF3eb9e6,
+ 0xFF6bcbeb, 0xFF7ed1f6, 0xFF6cd3f0, 0xFF82dbf4, 0xFF98e3f9, 0xFFa5ecf7, 0xFFb2f4f5, 0xFFc7f7f9,
+ 0xFFddfafd, 0xFFf2ffff, 0xFFf8fff6, 0xFFbcebfe, 0xFF22b4f2, 0xFF29afff, 0xFF2fb0f7, 0xFF29b1f2,
+ 0xFF23b1ee, 0xFF1aa7fa, 0xFFcae6f4, 0xFFf7f8f4, 0xFFfeffff, 0xFFfefff7, 0xFFfeffed, 0xFFfcffeb,
+ 0xFFfbfae9, 0xFFfbfee3, 0xFFfbffdc, 0xFFfbffe9, 0xFFfbfff7, 0xFFf1fedd, 0xFFe7fbc3, 0xFFe0f6b4,
+ 0xFFd8f0a5, 0xFFceec94, 0xFFc4e884, 0xFFb8e678, 0xFFace36c, 0xFFa0df53, 0xFF94d455, 0xFF80bd41,
+ 0xFFd2e599, 0xFF2ca1f4, 0xFF30a2f6, 0xFF209cf3, 0xFF1096f1, 0xFF1096f1, 0xFF1096f1, 0xFF1096f1,
+ 0xFF55cef4, 0xFF53cdf4, 0xFF51cbf5, 0xFF50cbf5, 0xFF4ecaf6, 0xFF4dc9f4, 0xFF54d0fa, 0xFF2b86ce,
+ 0xFF0752b1, 0xFF045fb9, 0xFF0a74c9, 0xFF0882ce, 0xFF0691d4, 0xFF02a0d5, 0xFF24b5e7, 0xFF4cc4ea,
+ 0xFF74d3ee, 0xFF83d9f5, 0xFF7fddf4, 0xFF93e4f6, 0xFFa8ecf9, 0xFFb6f2f9, 0xFFc3f9f9, 0xFFd3fafb,
+ 0xFFe3fcfc, 0xFFedfefb, 0xFFf0f9f3, 0xFFffffff, 0xFFfffdff, 0xFF7edcef, 0xFF26adfd, 0xFF2aaff7,
+ 0xFF2db2f2, 0xFF34b1e0, 0xFF09a7f7, 0xFF8dd3f5, 0xFFfdfbf9, 0xFFfffff6, 0xFFfdffeb, 0xFFfcffe6,
+ 0xFFfcfce0, 0xFFf9fcde, 0xFFf7fcdd, 0xFFfcffef, 0xFFf9fdec, 0xFFe8f5d0, 0xFFdff5bd, 0xFFd9f1ad,
+ 0xFFd2ed9d, 0xFFc5e97e, 0xFFb8e26d, 0xFFabdd5e, 0xFF9fd74f, 0xFF98c95f, 0xFF92c735, 0xFF8bc942,
+ 0xFF80b34d, 0xFF009bf2, 0xFF1894f8, 0xFF1595f5, 0xFF1397f2, 0xFF1296f1, 0xFF1195f0, 0xFF1195f0,
+ 0xFF56cff4, 0xFF54cdf5, 0xFF52ccf5, 0xFF51cbf7, 0xFF51cbf9, 0xFF49c8f1, 0xFF51d5fa, 0xFF1662c1,
+ 0xFF005cbb, 0xFF0874cd, 0xFF037cce, 0xFF028dd4, 0xFF019edb, 0xFF09aedc, 0xFF37c2ee, 0xFF5acfef,
+ 0xFF7edcf0, 0xFF88e1f4, 0xFF92e6f8, 0xFFa5eef8, 0xFFb9f5f9, 0xFFc7f9fb, 0xFFd5fdfe, 0xFFdffdfc,
+ 0xFFe9fdfa, 0xFFf0fefe, 0xFFf8ffff, 0xFFfafffe, 0xFFfdfffc, 0xFFfdfbff, 0xFF1db0e8, 0xFF2ab1ee,
+ 0xFF37b2f5, 0xFF25b9f7, 0xFF29b4f8, 0xFF22aff5, 0xFF1baaf2, 0xFF9fd7f6, 0xFFfdffea, 0xFFfcfee0,
+ 0xFFfcfdd7, 0xFFf8fada, 0xFFf4f7dd, 0xFFfdfef5, 0xFFf6fae1, 0xFFdfecc3, 0xFFd8efb6, 0xFFd2eca6,
+ 0xFFccea95, 0xFFbce567, 0xFFabdb56, 0xFF9fd344, 0xFF92cb33, 0xFF85c824, 0xFF79b46a, 0xFF3a9eaf,
+ 0xFF0c97ff, 0xFF1994f9, 0xFF0f9bee, 0xFF139af0, 0xFF1699f3, 0xFF1497f1, 0xFF1295ef, 0xFF1295ef,
+ 0xFF58d0f5, 0xFF56cef5, 0xFF53cdf4, 0xFF53ccf6, 0xFF52cbf8, 0xFF53d6fb, 0xFF4fc8fc, 0xFF004cad,
+ 0xFF096fca, 0xFF0b80d4, 0xFF0588d5, 0xFF0598db, 0xFF05a8e1, 0xFF18b6e6, 0xFF3fc8f2, 0xFF63d3f3,
+ 0xFF86dff5, 0xFF91e4f7, 0xFF9ce9fa, 0xFFaef0f9, 0xFFc0f7f9, 0xFFcbfafb, 0xFFd7fdfd, 0xFFdefdfc,
+ 0xFFe6fefb, 0xFFf0fffe, 0xFFfaffff, 0xFFf2fefb, 0xFFfefffd, 0xFFc6e9fb, 0xFF1eb0ec, 0xFF30b4f6,
+ 0xFF30b7f8, 0xFF19a8f7, 0xFF26b0f0, 0xFF22aef3, 0xFF1eabf5, 0xFF27aafa, 0xFF1ca6f6, 0xFF7dcdea,
+ 0xFFdff4dd, 0xFFeaffb0, 0xFFfdfeed, 0xFFffffef, 0xFFfcf9d3, 0xFFedeeb4, 0xFFe6e9ac, 0xFFd9e68a,
+ 0xFFcbe367, 0xFFb9e153, 0xFFa6dd4d, 0xFF75c57f, 0xFF43adb0, 0xFF229bf3, 0xFF0a9cff, 0xFF0998f6,
+ 0xFF109cef, 0xFF189aee, 0xFF149ded, 0xFF159bf0, 0xFF1599f2, 0xFF1397f0, 0xFF1195ee, 0xFF1195ee,
+ 0xFF5ad1f6, 0xFF57cff5, 0xFF54cef4, 0xFF54cdf6, 0xFF53cbf8, 0xFF4dd3f4, 0xFF2c9add, 0xFF045ec1,
+ 0xFF0572c9, 0xFF0683d2, 0xFF0794dc, 0xFF08a2e2, 0xFF08b1e8, 0xFF28bfef, 0xFF48cef6, 0xFF6bd8f8,
+ 0xFF8fe3fa, 0xFF9be8fa, 0xFFa6edfb, 0xFFb7f3fb, 0xFFc7f9fa, 0xFFd0fbfc, 0xFFd9fdfd, 0xFFdefefd,
+ 0xFFe2fffc, 0xFFeffffe, 0xFFfcffff, 0xFFebfef7, 0xFFfffffe, 0xFF8fd7f8, 0xFF1eb0f1, 0xFF2eb0f6,
+ 0xFF18abec, 0xFFe0f7fd, 0xFF24ade9, 0xFF23acf1, 0xFF21acf8, 0xFF26aef7, 0xFF2cb0f6, 0xFF1aa9f5,
+ 0xFF08a3f4, 0xFF22a7f9, 0xFF4cc2f2, 0xFF6dcdef, 0xFF7ec9db, 0xFF7fcac2, 0xFF81c6c6, 0xFF61bccb,
+ 0xFF41b3d0, 0xFF24a7e9, 0xFF089bff, 0xFF119dff, 0xFF1a9fff, 0xFF0f99e9, 0xFF149cf9, 0xFF159cf7,
+ 0xFF159cf5, 0xFF179df1, 0xFF199eed, 0xFF179cef, 0xFF1599f1, 0xFF1397ef, 0xFF1195ed, 0xFF1195ed,
+ 0xFF5cd2f6, 0xFF59d0f5, 0xFF55cff3, 0xFF54cdf5, 0xFF53ccf8, 0xFF51d5f6, 0xFF167bcf, 0xFF0467c6,
+ 0xFF067bcf, 0xFF068bd7, 0xFF059cdf, 0xFF08a9e5, 0xFF0ab6eb, 0xFF2bc4f1, 0xFF4cd2f7, 0xFF6ddbf9,
+ 0xFF8ee5fa, 0xFF9deafb, 0xFFaceffb, 0xFFbdf5fb, 0xFFcefbfa, 0xFFd5fbfc, 0xFFdcfcfd, 0xFFdcfefd,
+ 0xFFddfffd, 0xFFe4fffd, 0xFFeafffd, 0xFFfffffe, 0xFFffffff, 0xFF27c0de, 0xFF26b5f6, 0xFF1fb0f9,
+ 0xFF4dc6ff, 0xFFfff9ef, 0xFFfefffa, 0xFF8bd8f7, 0xFF18a7f3, 0xFF1daaf4, 0xFF23acf6, 0xFF22acf3,
+ 0xFF22abf0, 0xFF1aa3f2, 0xFF1aa6ee, 0xFF18a8f5, 0xFF0ea2f3, 0xFF11a4f2, 0xFF14a4ff, 0xFF15a3fc,
+ 0xFF16a3fa, 0xFF17a2f3, 0xFF19a2ec, 0xFF0e99fe, 0xFF169bed, 0xFF00a1ff, 0xFF2b9de8, 0xFF61b5b0,
+ 0xFF109af7, 0xFF149cf2, 0xFF189eed, 0xFF169cef, 0xFF149af0, 0xFF1298ee, 0xFF1096ec, 0xFF1096ec,
+ 0xFF5fd3f7, 0xFF5bd2f5, 0xFF56d0f3, 0xFF55cef5, 0xFF53cdf7, 0xFF56d8f8, 0xFF005cc0, 0xFF0370cb,
+ 0xFF0785d6, 0xFF0594dc, 0xFF04a3e2, 0xFF08afe8, 0xFF0cbcee, 0xFF2ec8f3, 0xFF50d5f9, 0xFF6fdefa,
+ 0xFF8de7fb, 0xFF9fecfb, 0xFFb1f2fb, 0xFFc3f7fb, 0xFFd4fcfa, 0xFFd9fcfc, 0xFFdefcfd, 0xFFdbfdfd,
+ 0xFFd9fffd, 0xFFd9fdfb, 0xFFd9fcfa, 0xFFe5fafa, 0xFFa4eaf7, 0xFF2badfb, 0xFF2fb9fa, 0xFF1aaeed,
+ 0xFF99dbf8, 0xFFffffff, 0xFFfefdfc, 0xFFfffefd, 0xFFfffffd, 0xFF8cd4fa, 0xFF19a9f6, 0xFF18a9f7,
+ 0xFF16aaf9, 0xFF1aa7f3, 0xFF1ea5ee, 0xFF1fa7f2, 0xFF21a9f6, 0xFF1ea7f7, 0xFF1ba5f7, 0xFF17a4f9,
+ 0xFF12a2fb, 0xFF0b9dfd, 0xFF0399fe, 0xFF26a2fa, 0xFF6fc0b0, 0xFFcfca5e, 0xFFffe528, 0xFF74b4b3,
+ 0xFF0b98fa, 0xFF119af4, 0xFF179dee, 0xFF159cee, 0xFF139aef, 0xFF1198ed, 0xFF0f96eb, 0xFF0f96eb,
+ 0xFF5dd1f6, 0xFF5bd2f5, 0xFF58d2f4, 0xFF53cef4, 0xFF56d2fb, 0xFF40b2e6, 0xFF0164c6, 0xFF0376cf,
+ 0xFF0487d7, 0xFF0296dd, 0xFF01a4e4, 0xFF04b1ea, 0xFF07bdf1, 0xFF1bc8f2, 0xFF43d5fc, 0xFF64ddfb,
+ 0xFF85e6fb, 0xFF98ebfc, 0xFFacf1fd, 0xFFbef9ff, 0xFFcfffff, 0xFFcffdff, 0xFFcff9fb, 0xFFd2fefe,
+ 0xFFd5ffff, 0xFFc6f9ff, 0xFFb8efff, 0xFF5ad7d9, 0xFF40b9e9, 0xFF2fb9ff, 0xFF2bb2f0, 0xFF28afeb,
+ 0xFFdef0f2, 0xFFffffff, 0xFFfeffff, 0xFFfffefe, 0xFFfffefa, 0xFFfffffa, 0xFFfffff9, 0xFFc2e8f0,
+ 0xFF84cde7, 0xFF53bbe9, 0xFF22a9eb, 0xFF14a1ff, 0xFF069ff8, 0xFF0fa0f8, 0xFF19a3eb, 0xFF43b1e1,
+ 0xFF6ec2c9, 0xFFb0d79a, 0xFFf2eb6b, 0xFFebee32, 0xFFf8e647, 0xFFffe23a, 0xFFfde142, 0xFF0098f4,
+ 0xFF19a1fc, 0xFF169ef7, 0xFF129bf1, 0xFF139af1, 0xFF149af0, 0xFF1298ee, 0xFF1096ec, 0xFF1096ec,
+ 0xFF5ccff6, 0xFF5bd2f6, 0xFF5ad4f6, 0xFF52cdf2, 0xFF5ad6fe, 0xFF298cd5, 0xFF026ccc, 0xFF027bd2,
+ 0xFF0189d8, 0xFF0097df, 0xFF00a6e6, 0xFF00b2ed, 0xFF02bef4, 0xFF09c7f1, 0xFF35d5ff, 0xFF59ddfd,
+ 0xFF7ce5fb, 0xFF91eafd, 0xFFa6f0ff, 0xFFb1f2ff, 0xFFbbf5ff, 0xFFbef5fc, 0xFFc1f6f9, 0xFFc1f7f7,
+ 0xFFc1f9f4, 0xFFc7fdfc, 0xFFcdffff, 0xFFc2f9f8, 0xFF5acdf4, 0xFF39b1f3, 0xFF38baf5, 0xFF2ab4f7,
+ 0xFFfcfbf8, 0xFFfdfeff, 0xFFfeffff, 0xFFfffeff, 0xFFfffcf6, 0xFFfdfef2, 0xFFf7ffee, 0xFFfcffea,
+ 0xFFffffe5, 0xFFffffd8, 0xFFffffcb, 0xFFfffbf1, 0xFFffffdf, 0xFFfdfdc2, 0xFFf7ff88, 0xFFfbfe92,
+ 0xFFffff7f, 0xFFfdfc6c, 0xFFfaf759, 0xFFf8f059, 0xFFf7e958, 0xFFf7e359, 0xFFd0d368, 0xFF0998ff,
+ 0xFF189aef, 0xFF129af2, 0xFF0c99f5, 0xFF1199f3, 0xFF1599f2, 0xFF1397f0, 0xFF1195ee, 0xFF1195ee,
+ 0xFF5fd2f9, 0xFF5cd3f8, 0xFF59d4f6, 0xFF58d3f8, 0xFF5edaff, 0xFF1971cd, 0xFF026ecd, 0xFF037bd3,
+ 0xFF0488d9, 0xFF0497e0, 0xFF05a6e6, 0xFF01ade7, 0xFF00b5e8, 0xFF07beea, 0xFF23cbf5, 0xFF4cd7f8,
+ 0xFF74e4fc, 0xFF89e8fd, 0xFF9fecfe, 0xFFa5edfe, 0xFFabeffe, 0xFFaeeffc, 0xFFb0eff9, 0xFFb3f3f9,
+ 0xFFb6f6f8, 0xFFb6f9fc, 0xFFb5fcff, 0xFFdaf3ff, 0xFF1ab9f1, 0xFF28b3f4, 0xFF2bb3f6, 0xFF73cef4,
+ 0xFFfdfdf5, 0xFFfdfefa, 0xFFfdfffe, 0xFFfffef9, 0xFFfffdf3, 0xFFfdfeee, 0xFFfaffe9, 0xFFfdffe4,
+ 0xFFffffde, 0xFFffffd0, 0xFFffffc2, 0xFFfdfad7, 0xFFfffcf3, 0xFFffffc0, 0xFFfcfbc5, 0xFFfcff84,
+ 0xFFfcfb8b, 0xFFfbf67a, 0xFFf9f269, 0xFFf7ed5e, 0xFFf4e954, 0xFFf7e948, 0xFF87bda9, 0xFF109afc,
+ 0xFF179cf2, 0xFF149bf1, 0xFF119af1, 0xFF1399f2, 0xFF1698f3, 0xFF1496f1, 0xFF1294ef, 0xFF1294ef,
+ 0xFF62d4fc, 0xFF5dd4f9, 0xFF59d4f6, 0xFF56d1f6, 0xFF53cef5, 0xFF014ebe, 0xFF026fcd, 0xFF057bd4,
+ 0xFF0787da, 0xFF0996e0, 0xFF0ca5e7, 0xFF0bb0e9, 0xFF09bbeb, 0xFF15c5f3, 0xFF21d0fc, 0xFF46dafc,
+ 0xFF6ce3fc, 0xFF82e6fd, 0xFF97e9fe, 0xFF99e9fe, 0xFF9ce8fe, 0xFF9ee9fb, 0xFFa0e9f9, 0xFFa6eefa,
+ 0xFFacf3fc, 0xFFb0effc, 0xFFb5ecfb, 0xFF89ddf9, 0xFF28b4f3, 0xFF3ebef7, 0xFF1eadf7, 0xFFbde8f0,
+ 0xFFfefff2, 0xFFfefff3, 0xFFfdfff4, 0xFFfefef2, 0xFFfefef0, 0xFFfefeea, 0xFFfefee4, 0xFFfefede,
+ 0xFFfefed8, 0xFFfcffc9, 0xFFfbffba, 0xFFf6fea0, 0xFFffffce, 0xFFfff9f6, 0xFFffffc9, 0xFFfdf7be,
+ 0xFFf8f87a, 0xFFf9f66b, 0xFFf9f35c, 0xFFf5ee56, 0xFFf1e84f, 0xFFf8ee37, 0xFF3fa7ea, 0xFF189df5,
+ 0xFF179df4, 0xFF169cf1, 0xFF159bee, 0xFF169af2, 0xFF1798f5, 0xFF1596f3, 0xFF1394f1, 0xFF1394f1,
+ 0xFF66d7fc, 0xFF5fd1f5, 0xFF60d4f6, 0xFF59d8f9, 0xFF399ddb, 0xFF0858be, 0xFF096ccd, 0xFF0c7ad2,
+ 0xFF1087d7, 0xFF1296df, 0xFF13a6e8, 0xFF13b0eb, 0xFF1bc3f5, 0xFF0fc8f3, 0xFF17d0f9, 0xFF27d3f4,
+ 0xFF4bd7f7, 0xFF61dbf8, 0xFF77def9, 0xFF7fe0fa, 0xFF88e1fa, 0xFF8de4fb, 0xFF91e7fb, 0xFF96eafc,
+ 0xFF9aedfd, 0xFF9feafb, 0xFFa3e7fa, 0xFF5eccfb, 0xFF2db7f5, 0xFF24b8f9, 0xFF14b1f5, 0xFFfffbff,
+ 0xFFfeffec, 0xFFffffed, 0xFFffffee, 0xFFffffec, 0xFFfefdeb, 0xFFfefde4, 0xFFfefddd, 0xFFfefed6,
+ 0xFFfefece, 0xFFfcfdc1, 0xFFfcfcb5, 0xFFf6fb8d, 0xFFf8fc8a, 0xFFf8facc, 0xFFf8fef2, 0xFFf9ffbe,
+ 0xFFfbf9c2, 0xFFfbf8ac, 0xFFfcf796, 0xFFfaf491, 0xFFf7f18d, 0xFFffe5a9, 0xFF0096f7, 0xFF089af7,
+ 0xFF159ef7, 0xFF169df4, 0xFF169cf0, 0xFF169bf2, 0xFF1699f4, 0xFF1497f3, 0xFF1396f1, 0xFF1396f1,
+ 0xFF6bd9fb, 0xFF61cef1, 0xFF67d3f7, 0xFF5cdefd, 0xFF1f6cc0, 0xFF0f63bf, 0xFF0f6acd, 0xFF1478d1,
+ 0xFF1887d4, 0xFF1997df, 0xFF1aa6e9, 0xFF14a9e4, 0xFF1dbbef, 0xFF0dbeeb, 0xFF23c5f6, 0xFF13c6ed,
+ 0xFF2acbf3, 0xFF40cff4, 0xFF56d4f4, 0xFF65d7f6, 0xFF74daf7, 0xFF7bdffb, 0xFF83e5fe, 0xFF86e6fe,
+ 0xFF89e8fd, 0xFF8ee5fb, 0xFF92e2fa, 0xFF33bcfc, 0xFF32b9f7, 0xFF31bafd, 0xFF57c5f7, 0xFFf4ffde,
+ 0xFFfdffe7, 0xFFffffe7, 0xFFffffe7, 0xFFffffe6, 0xFFfdfce6, 0xFFfdfddd, 0xFFfdfdd5, 0xFFfdfdcd,
+ 0xFFfefdc5, 0xFFfdfaba, 0xFFfcf8af, 0xFFfef99f, 0xFFfffb8e, 0xFFfafe77, 0xFFf4fb7d, 0xFFf9f8d2,
+ 0xFFfdffee, 0xFFfefedf, 0xFFfffcd0, 0xFFfefacd, 0xFFfdf9ca, 0xFFa6d3ce, 0xFF0399eb, 0xFF1ea1ec,
+ 0xFF149ffa, 0xFF159ef6, 0xFF179ef2, 0xFF169cf3, 0xFF159af3, 0xFF1499f2, 0xFF1398f1, 0xFF1398f1,
+ 0xFF55d4f4, 0xFF5bd1f1, 0xFF69d6f6, 0xFF6ee2ff, 0xFF0c50a8, 0xFF1161be, 0xFF0f6acd, 0xFF1f83d6,
+ 0xFF1f89dc, 0xFF0f8cdd, 0xFF1a9be0, 0xFF22b1f4, 0xFF1dabe1, 0xFF14aedf, 0xFF26bdee, 0xFF15bae7,
+ 0xFF1fc1ef, 0xFF25c7ef, 0xFF2bcdef, 0xFF3dcdf1, 0xFF4ecef3, 0xFF5bd6f9, 0xFF68defe, 0xFF6eddfc,
+ 0xFF73ddfb, 0xFF76ddf5, 0xFF70d3f7, 0xFF31bafb, 0xFF33b9f6, 0xFF24b6ff, 0xFFa4dee5, 0xFFf9ffdc,
+ 0xFFfdfedc, 0xFFffffdc, 0xFFffffdc, 0xFFfefedb, 0xFFfcfdda, 0xFFfdfdd2, 0xFFfdfdcb, 0xFFfdfdc3,
+ 0xFFfefdbc, 0xFFfdfbaf, 0xFFfcfaa2, 0xFFfdfb93, 0xFFfefb83, 0xFFfcfd6b, 0xFFf9fc60, 0xFFfbf85d,
+ 0xFFfdf74c, 0xFFfef576, 0xFFfff2a1, 0xFFf6ec87, 0xFFf8e360, 0xFF51bbb4, 0xFF0d9afe, 0xFF1a9ef7,
+ 0xFF159ef6, 0xFF159df4, 0xFF159df2, 0xFF149bf2, 0xFF1299f2, 0xFF1299f2, 0xFF1299f2, 0xFF1299f2,
+ 0xFF67d4fd, 0xFF69d6f9, 0xFF6cd9f5, 0xFF4fb7dc, 0xFF1953af, 0xFF1c67c6, 0xFF005abd, 0xFF1a7eca,
+ 0xFF157bd4, 0xFF0581dc, 0xFF2aa1e7, 0xFF0189d3, 0xFF2dabe3, 0xFF23a7dc, 0xFF29b4e6, 0xFF17ade1,
+ 0xFF14b7ec, 0xFF15b9ea, 0xFF16bbe9, 0xFF1fbfec, 0xFF28c2ef, 0xFF3bcdf7, 0xFF4ed8ff, 0xFF56d5fb,
+ 0xFF5dd2f8, 0xFF5ed6f0, 0xFF4ec5f4, 0xFF2fb9fa, 0xFF35b8f4, 0xFF17b1ff, 0xFFf0f7d2, 0xFFfeffda,
+ 0xFFfdfcd2, 0xFFfdfdd1, 0xFFfdfed1, 0xFFfdfecf, 0xFFfcfecd, 0xFFfcfdc7, 0xFFfdfdc0, 0xFFfdfdb9,
+ 0xFFfdfdb2, 0xFFfdfca4, 0xFFfdfc95, 0xFFfdfc87, 0xFFfdfc79, 0xFFfdfa6c, 0xFFfef85f, 0xFFf9f645,
+ 0xFFf6ef47, 0xFFf2e938, 0xFFefe428, 0xFFeee425, 0xFFffdd05, 0xFF0399ff, 0xFF17a1f5, 0xFF179ef4,
+ 0xFF169cf3, 0xFF159cf3, 0xFF149cf3, 0xFF129bf1, 0xFF1099f0, 0xFF119af1, 0xFF129bf2, 0xFF129bf2,
+ 0xFF66d5fb, 0xFF70d5fc, 0xFF78e2ff, 0xFF3b86c7, 0xFF235fba, 0xFF1e6aba, 0xFF227ad1, 0xFF2787d8,
+ 0xFF248cd7, 0xFF1d8dd4, 0xFF2189d1, 0xFF2ca1ea, 0xFF2296d5, 0xFF31aaef, 0xFF20a1db, 0xFF17a1dd,
+ 0xFF0ea1e0, 0xFF1aace3, 0xFF13b1eb, 0xFF10b8ed, 0xFF0dc0ef, 0xFF1cc1ef, 0xFF2cc3f0, 0xFF36c4f2,
+ 0xFF40c5f4, 0xFF47c9f2, 0xFF45c3f6, 0xFF31bafa, 0xFF31b7f7, 0xFF4cc2f4, 0xFFf5fac0, 0xFFfdffc6,
+ 0xFFfdfcc5, 0xFFfdfdc4, 0xFFfdfdc4, 0xFFfcfdc2, 0xFFfbfdc1, 0xFFf8f9b6, 0xFFfdfdb3, 0xFFfdfdab,
+ 0xFFfdfca3, 0xFFfcfc95, 0xFFfcfb88, 0xFFfcfb7b, 0xFFfbfb6d, 0xFFfcf962, 0xFFfcf757, 0xFFf8f245,
+ 0xFFf4eb41, 0xFFf0e532, 0xFFebe023, 0xFFfbe01c, 0xFFc5d244, 0xFF0aa2fe, 0xFF169ff9, 0xFF179ff6,
+ 0xFF189ff3, 0xFF179ef2, 0xFF159df2, 0xFF179ff5, 0xFF18a1f8, 0xFF159ef5, 0xFF129bf2, 0xFF129bf2,
+ 0xFF65d7fa, 0xFF64d1f7, 0xFF5de7ff, 0xFF04439b, 0xFF0e4ca5, 0xFF317bcd, 0xFF0455c1, 0xFF0053c9,
+ 0xFF0368c6, 0xFF2687ca, 0xFF2881ca, 0xFF2789d1, 0xFF2791d7, 0xFF0774c9, 0xFF178dcf, 0xFF1f9ce1,
+ 0xFF179be4, 0xFF1e9eda, 0xFF0097de, 0xFF03a5e6, 0xFF08b1ee, 0xFF09b0e8, 0xFF0aafe2, 0xFF17b4e9,
+ 0xFF24b9ef, 0xFF30bdf4, 0xFF3cc1f9, 0xFF34bcf9, 0xFF2cb6f9, 0xFF80d2e8, 0xFFfafdaf, 0xFFfcfdb3,
+ 0xFFfdfcb7, 0xFFfdfcb7, 0xFFfdfdb7, 0xFFfcfcb6, 0xFFfbfcb5, 0xFFf4f4a5, 0xFFfdfda5, 0xFFfcfc9d,
+ 0xFFfcfc94, 0xFFfbfb87, 0xFFfbfb7b, 0xFFfafa6e, 0xFFfafa61, 0xFFfaf758, 0xFFfaf54e, 0xFFf7ee44,
+ 0xFFf3e73a, 0xFFede12c, 0xFFe7db1e, 0xFFffd21a, 0xFF78b090, 0xFF09a0fd, 0xFF159dfd, 0xFF18a0f8,
+ 0xFF1aa2f2, 0xFF18a0f2, 0xFF169ef2, 0xFF139bf2, 0xFF1099f1, 0xFF119af2, 0xFF129bf3, 0xFF129bf3,
+ 0xFF60d4f7, 0xFF67dcfd, 0xFF4fc2f0, 0xFF002c8a, 0xFF2e6bc0, 0xFF0547ad, 0xFF0044ba, 0xFF3685c4,
+ 0xFF064ebc, 0xFF1462c3, 0xFF2d70cb, 0xFF0f5ab4, 0xFF2274cd, 0xFF1169c2, 0xFF1979c2, 0xFF1d80d0,
+ 0xFF1980d7, 0xFF1a86d3, 0xFF1090de, 0xFF038dda, 0xFF0599e6, 0xFF059ce1, 0xFF049edd, 0xFF05a6e1,
+ 0xFF00a7de, 0xFF1fb6ee, 0xFF39bdf7, 0xFF38bcf6, 0xFF24b5fc, 0xFFbfe8b9, 0xFFfafea2, 0xFFfbfca5,
+ 0xFFfcfaa8, 0xFFfcfca7, 0xFFfdfda6, 0xFFfbfca3, 0xFFf9fb9f, 0xFFf6f795, 0xFFfafb92, 0xFFfbfb8b,
+ 0xFFfbfb85, 0xFFfafa79, 0xFFfafa6d, 0xFFf9f961, 0xFFf8f956, 0xFFf9f64c, 0xFFf9f442, 0xFFf5ec39,
+ 0xFFf2e531, 0xFFefde28, 0xFFecd620, 0xFFeed900, 0xFF32a6e5, 0xFF19a4ff, 0xFF29a4f4, 0xFF20a2f4,
+ 0xFF18a0f5, 0xFF179ef4, 0xFF159df4, 0xFF139bf3, 0xFF1199f2, 0xFF129af2, 0xFF129af3, 0xFF129af3,
+ 0xFF5bd1f5, 0xFF63dffa, 0xFF318dcc, 0xFF062d91, 0xFF0e499a, 0xFF00369f, 0xFF003897, 0xFF155fb6,
+ 0xFF53aad9, 0xFF31a6e2, 0xFF45bcef, 0xFF6dddff, 0xFF76defa, 0xFF6dd9f9, 0xFF64d5f9, 0xFF54c5f3,
+ 0xFF45b5ed, 0xFF238ed6, 0xFF1277ce, 0xFF006cc6, 0xFF0282de, 0xFF0187db, 0xFF008dd7, 0xFF079be1,
+ 0xFF0099dc, 0xFF22b1f0, 0xFF36baf4, 0xFF3cbcf4, 0xFF1cb5ff, 0xFFfffe89, 0xFFfbff96, 0xFFfbfc98,
+ 0xFFfbf99a, 0xFFfcfb98, 0xFFfdfd96, 0xFFfafb90, 0xFFf6f98a, 0xFFf7f984, 0xFFf8fa7f, 0xFFfafa7a,
+ 0xFFfbfb75, 0xFFfafa6a, 0xFFf9f960, 0xFFf8f855, 0xFFf7f84a, 0xFFf7f540, 0xFFf8f336, 0xFFf4eb2f,
+ 0xFFf0e328, 0xFFf0da24, 0xFFf0d121, 0xFFe9ca24, 0xFF049bff, 0xFF20a3f6, 0xFF16a1f7, 0xFF16a0f7,
+ 0xFF169ef7, 0xFF159df6, 0xFF149cf5, 0xFF139bf4, 0xFF129af3, 0xFF129af3, 0xFF129af3, 0xFF129af3,
+ 0xFF5ae3ff, 0xFF64d8ff, 0xFF0d4798, 0xFF002682, 0xFF1d6bb7, 0xFF3aa2de, 0xFF5fe5ff, 0xFF52d8fd,
+ 0xFF4dd6f6, 0xFF48ccf5, 0xFF5fd0f6, 0xFF68d9ff, 0xFF61d3f8, 0xFF5bd2f8, 0xFF42cbff, 0xFF53cefe,
+ 0xFF51cff5, 0xFF49caf6, 0xFF4acdff, 0xFF40baff, 0xFF0e7edb, 0xFF0069c2, 0xFF0584da, 0xFF0184d5,
+ 0xFF068cd8, 0xFF38bef8, 0xFF3abef7, 0xFF35beff, 0xFF62c7e2, 0xFFfbf379, 0xFFf8fa83, 0xFFf9f983,
+ 0xFFfaf884, 0xFFf9f77f, 0xFFf7f77b, 0xFFf8f979, 0xFFf9fa77, 0xFFf8f972, 0xFFf7f86c, 0xFFfcfc6c,
+ 0xFFf9f864, 0xFFf8f85b, 0xFFf8f752, 0xFFf7f649, 0xFFf6f53f, 0xFFf5f237, 0xFFf4ef2f, 0xFFf1e628,
+ 0xFFeede20, 0xFFead61f, 0xFFf2cc11, 0xFF9db96c, 0xFF0c9ffe, 0xFF1ba3f9, 0xFF17a2f9, 0xFF17a0f9,
+ 0xFF169ef8, 0xFF169df7, 0xFF159cf6, 0xFF149bf5, 0xFF139af5, 0xFF139af5, 0xFF139af5, 0xFF139af5,
+ 0xFF60d8f9, 0xFF5bd9f8, 0xFF4cadd7, 0xFF69ddff, 0xFF56ddf8, 0xFF55d6fc, 0xFF55d0ff, 0xFF5cd5ff,
+ 0xFF53cbf2, 0xFF4bcaf6, 0xFF43cafa, 0xFF47c9f8, 0xFF4cc8f6, 0xFF5ccff1, 0xFF46ccf8, 0xFF55caff,
+ 0xFF3ec4fa, 0xFF43c3fb, 0xFF48c2fd, 0xFF3ebff4, 0xFF44ccfb, 0xFF37b3fc, 0xFF0b7bdd, 0xFF006dc9,
+ 0xFF0d80d4, 0xFF4eccff, 0xFF3ec3fa, 0xFF2ec2ff, 0xFFa7dea8, 0xFFf8ec5b, 0xFFf5f570, 0xFFf7f66f,
+ 0xFFfaf76e, 0xFFf5f467, 0xFFf1f060, 0xFFf6f663, 0xFFfbfc65, 0xFFf8f95f, 0xFFf6f659, 0xFFfefe5d,
+ 0xFFf7f652, 0xFFf7f54c, 0xFFf7f545, 0xFFf6f33d, 0xFFf6f235, 0xFFf3ef2f, 0xFFf1eb29, 0xFFefe221,
+ 0xFFecd818, 0xFFe5d21a, 0xFFf3c700, 0xFF52a9b4, 0xFF14a4fb, 0xFF15a3fb, 0xFF17a3fc, 0xFF17a1fa,
+ 0xFF179ff8, 0xFF169df8, 0xFF159cf7, 0xFF159bf7, 0xFF1499f6, 0xFF1499f6, 0xFF1499f6, 0xFF1499f6,
+ 0xFF58cff2, 0xFF59ddfd, 0xFF55d5f9, 0xFF5ddeff, 0xFF4dcef3, 0xFF4dcbf3, 0xFF4cc8f3, 0xFF56d2fc,
+ 0xFF59d3fd, 0xFF50cefb, 0xFF47cafa, 0xFF48c9f9, 0xFF49c7f9, 0xFF51cbf6, 0xFF45c9f9, 0xFF4bc8fd,
+ 0xFF3fc5f9, 0xFF41c4fa, 0xFF43c2fb, 0xFF3bbdf3, 0xFF3ac0f4, 0xFF3ec7fc, 0xFF3ac6fc, 0xFF25a1e3,
+ 0xFF1f8dd9, 0xFF37b9f7, 0xFF26bbfa, 0xFF2abbf4, 0xFFced857, 0xFFf9fa5b, 0xFFd9db49, 0xFFedec58,
+ 0xFFfaf560, 0xFFf2ef4d, 0xFFe9ea3b, 0xFFeeef46, 0xFFf2f451, 0xFFf9f34f, 0xFFedf145, 0xFFfef84b,
+ 0xFFf4f542, 0xFFf5f43d, 0xFFf6f337, 0xFFf5f131, 0xFFf5ef2b, 0xFFf2eb27, 0xFFf0e622, 0xFFeedb1d,
+ 0xFFecd117, 0xFFf1cc09, 0xFFf5c509, 0xFF0fadff, 0xFF17a1f9, 0xFF18a1f9, 0xFF18a1f8, 0xFF18a0f9,
+ 0xFF179ff9, 0xFF169df9, 0xFF169cf8, 0xFF159bf8, 0xFF1599f8, 0xFF1599f8, 0xFF1599f8, 0xFF1599f8,
+ 0xFF60d5fb, 0xFF5bd3fb, 0xFF56d2fb, 0xFF55d1fc, 0xFF55d0fe, 0xFF54d0fa, 0xFF53d1f6, 0xFF51cef7,
+ 0xFF4ecbf8, 0xFF4dcbf9, 0xFF4ccafb, 0xFF49c8fb, 0xFF47c6fc, 0xFF45c6fb, 0xFF43c6fa, 0xFF41c6fa,
+ 0xFF40c7f9, 0xFF3fc5f9, 0xFF3ec3f9, 0xFF3fc3fb, 0xFF41c4fd, 0xFF38baf2, 0xFF40c1f8, 0xFF3dc3fb,
+ 0xFF3bc5fe, 0xFF37c1f6, 0xFF34beef, 0xFF2ebcf0, 0xFFded722, 0xFFbfdc38, 0xFFdee142, 0xFFecea4a,
+ 0xFFeae442, 0xFFeee942, 0xFFf2ee42, 0xFFeeed3f, 0xFFeaec3d, 0xFFfbee3f, 0xFFe5ec31, 0xFFfff239,
+ 0xFFf2f531, 0xFFf4f32e, 0xFFf5f12a, 0xFFf5ee25, 0xFFf4ec21, 0xFFf2e71e, 0xFFf0e11c, 0xFFeed519,
+ 0xFFecc917, 0xFFdec40c, 0xFFbbbe39, 0xFF0798f8, 0xFF1a9ff8, 0xFF1a9ff7, 0xFF1a9ff5, 0xFF189ff7,
+ 0xFF179ff9, 0xFF179ef9, 0xFF169cf9, 0xFF169bf9, 0xFF1699f9, 0xFF1699f9, 0xFF1699f9, 0xFF1699f9,
+ 0xFF5cd4f9, 0xFF58d4f9, 0xFF55d3f9, 0xFF56d2fa, 0xFF58d0fb, 0xFF56d0f8, 0xFF54d0f6, 0xFF51cef7,
+ 0xFF4dccf9, 0xFF4ccbfa, 0xFF4bcafb, 0xFF49c8fb, 0xFF47c7fb, 0xFF45c7fb, 0xFF43c6fa, 0xFF41c6fa,
+ 0xFF40c6f9, 0xFF3fc4f9, 0xFF3ec3f9, 0xFF3ec2fa, 0xFF3ec2fb, 0xFF3abef5, 0xFF3ec2f8, 0xFF3bc1f9,
+ 0xFF37c0f9, 0xFF36beff, 0xFF35bbff, 0xFF67bb84, 0xFFb0d219, 0xFFb4d31a, 0xFFd3da39, 0xFFe2dd3d,
+ 0xFFd6d532, 0xFFe1df38, 0xFFece93e, 0xFFe1e636, 0xFFe9e536, 0xFFf1e634, 0xFFe5e42b, 0xFFf6e62e,
+ 0xFFe9eb29, 0xFFf0ee2a, 0xFFf0e824, 0xFFece420, 0xFFe9e01d, 0xFFebdb1c, 0xFFedd71c, 0xFFe9ce19,
+ 0xFFe5c516, 0xFFe7c004, 0xFF6cb292, 0xFF109dfc, 0xFF18a1f7, 0xFF1aa0f5, 0xFF1ca0f3, 0xFF19a0f6,
+ 0xFF179ff9, 0xFF169ef9, 0xFF169cf9, 0xFF159bf8, 0xFF159af8, 0xFF1499f8, 0xFF1499f7, 0xFF1499f7,
+ 0xFF58d4f6, 0xFF56d4f6, 0xFF54d5f7, 0xFF57d3f7, 0xFF5bd1f8, 0xFF58d0f6, 0xFF54cff5, 0xFF50cef8,
+ 0xFF4dcdfa, 0xFF4bcbfb, 0xFF4acafb, 0xFF48c9fb, 0xFF46c7fb, 0xFF45c7fa, 0xFF43c7fa, 0xFF42c6fa,
+ 0xFF40c6f9, 0xFF3fc4f9, 0xFF3ec3f9, 0xFF3dc1f9, 0xFF3cc0f9, 0xFF3cc1f8, 0xFF3cc2f7, 0xFF38bff6,
+ 0xFF34bbf5, 0xFF35bdfd, 0xFF37beff, 0xFF46bcfc, 0xFF82c92c, 0xFFa0be02, 0xFFb8c420, 0xFFd8cf31,
+ 0xFFd2d632, 0xFFd4d52e, 0xFFd7d42a, 0xFFcdd725, 0xFFe9df2f, 0xFFe6dd2a, 0xFFe4dc25, 0xFFedd922,
+ 0xFFe0e220, 0xFFede927, 0xFFeae01e, 0xFFe4da1c, 0xFFded319, 0xFFe5d01a, 0xFFebcd1b, 0xFFe5c818,
+ 0xFFdec214, 0xFFf0bc00, 0xFF1da5eb, 0xFF19a1ff, 0xFF16a2f7, 0xFF19a2f4, 0xFF1ea2f1, 0xFF1aa0f5,
+ 0xFF169ff9, 0xFF169ef8, 0xFF159df8, 0xFF159cf8, 0xFF149bf8, 0xFF139af7, 0xFF1299f6, 0xFF1299f6,
+ 0xFF5ed5f9, 0xFF63d6fc, 0xFF68d6ff, 0xFF5fd3fc, 0xFF56d0f8, 0xFF53cff8, 0xFF51cef8, 0xFF4ecdf9,
+ 0xFF4bccfb, 0xFF4acbfb, 0xFF48cafb, 0xFF47c9fa, 0xFF46c8fb, 0xFF44c7fa, 0xFF43c7fa, 0xFF42c6fa,
+ 0xFF40c5f9, 0xFF3fc4f9, 0xFF3ec3f9, 0xFF3dc1f9, 0xFF3cc0f9, 0xFF3bc1f9, 0xFF3bc1f8, 0xFF38bff7,
+ 0xFF36bdf7, 0xFF35bdfa, 0xFF34bdfe, 0xFF22c3f6, 0xFF27bbfc, 0xFF53b0b2, 0xFF9bc606, 0xFFc1d322,
+ 0xFFd3dd36, 0xFFb4ba12, 0xFFc4c71f, 0xFFc5cf22, 0xFFd9d82d, 0xFFdfdb30, 0xFFdcd52b, 0xFFe8d520,
+ 0xFFd5d51c, 0xFFe8e428, 0xFFece324, 0xFFd1ce1f, 0xFFd3c51d, 0xFFdcc302, 0xFFcfc312, 0xFFe3c209,
+ 0xFFe3be00, 0xFF84bf6e, 0xFF0ca0f6, 0xFF129ffd, 0xFF18a2f6, 0xFF19a1f5, 0xFF1ba1f4, 0xFF18a0f6,
+ 0xFF169ff8, 0xFF159ef8, 0xFF159df8, 0xFF149cf7, 0xFF139bf7, 0xFF129af6, 0xFF1098f4, 0xFF1098f4,
+ 0xFF65d7fb, 0xFF5dd4fa, 0xFF56d2f8, 0xFF53d0f9, 0xFF50cff9, 0xFF4fcef9, 0xFF4dcdfa, 0xFF4bcdfa,
+ 0xFF4accfb, 0xFF48cbfb, 0xFF47cafb, 0xFF46c9fa, 0xFF45c8fa, 0xFF44c7fa, 0xFF43c7fa, 0xFF42c6fa,
+ 0xFF40c5fa, 0xFF3fc4f9, 0xFF3ec3f9, 0xFF3dc1f9, 0xFF3bc0f9, 0xFF3ac0f9, 0xFF39c0f9, 0xFF38bff9,
+ 0xFF37bff9, 0xFF34bef8, 0xFF31bcf7, 0xFF33bbf8, 0xFF35bbfa, 0xFF2cbcff, 0xFF61c2df, 0xFF93cb85,
+ 0xFFc5d52b, 0xFFcbd82f, 0xFFb0bb13, 0xFFb5be17, 0xFFb9c21b, 0xFFc7c826, 0xFFc5bf21, 0xFFdbc817,
+ 0xFFcac819, 0xFFdbd722, 0xFFddd61a, 0xFFb7bd0d, 0xFFc8bd04, 0xFFd0c000, 0xFFadc951, 0xFF6cb8b1,
+ 0xFF04a3ff, 0xFF13a4fb, 0xFF21a4f5, 0xFF1ea3f5, 0xFF1aa1f6, 0xFF19a1f6, 0xFF18a0f7, 0xFF17a0f7,
+ 0xFF169ff8, 0xFF159ef7, 0xFF149ef7, 0xFF139df7, 0xFF139cf6, 0xFF119af4, 0xFF0f98f2, 0xFF0f98f2,
+ 0xFF5cd5f9, 0xFF58d3f8, 0xFF53d1f8, 0xFF52d0f9, 0xFF50cff9, 0xFF4ecefa, 0xFF4ccdfa, 0xFF4accfa,
+ 0xFF48ccfa, 0xFF47cbfa, 0xFF46cafa, 0xFF45c9fa, 0xFF44c8fa, 0xFF43c7fa, 0xFF42c7fa, 0xFF41c6fa,
+ 0xFF40c5fa, 0xFF3fc4f9, 0xFF3ec2f9, 0xFF3cc1f9, 0xFF3bc0f9, 0xFF3ac0f9, 0xFF38bff9, 0xFF37bff9,
+ 0xFF36bff9, 0xFF35bdf6, 0xFF34bbf3, 0xFF35b9f7, 0xFF35b8fb, 0xFF22b5ff, 0xFF2fb5ff, 0xFF4dbae6,
+ 0xFF6bbfce, 0xFF27b1c5, 0xFF6cbc7c, 0xFF8abd49, 0xFFa7be15, 0xFFb9bf09, 0xFFccc000, 0xFFdac43d,
+ 0xFFbbca20, 0xFFaec73e, 0xFF99bc54, 0xFF5aad8b, 0xFF36abc4, 0xFF04b3ff, 0xFF15a7ff, 0xFF21a4ff,
+ 0xFF19a0fb, 0xFF1ba2fa, 0xFF1da4f9, 0xFF1ba3f8, 0xFF1aa1f7, 0xFF19a1f7, 0xFF18a0f7, 0xFF17a0f7,
+ 0xFF169ff8, 0xFF159ef7, 0xFF149ef7, 0xFF139df7, 0xFF129cf6, 0xFF119af5, 0xFF0f99f3, 0xFF0f99f3,
+ 0xFF53d2f6, 0xFF52d1f7, 0xFF51d1f8, 0xFF50d0f9, 0xFF4fcffa, 0xFF4dcefa, 0xFF4bcdfa, 0xFF49ccfa,
+ 0xFF47cbfa, 0xFF46caf9, 0xFF45caf9, 0xFF44c9f9, 0xFF44c8fa, 0xFF43c7fa, 0xFF42c6f9, 0xFF41c6f9,
+ 0xFF40c5fa, 0xFF3fc4f9, 0xFF3dc2f9, 0xFF3cc1f9, 0xFF3ac0f9, 0xFF39c0f9, 0xFF38bff9, 0xFF36bff9,
+ 0xFF35bef8, 0xFF36bcf4, 0xFF38baf0, 0xFF36b8f6, 0xFF34b5fc, 0xFF2cb6f9, 0xFF23b7f6, 0xFF25b5fa,
+ 0xFF28b4ff, 0xFF28b6ff, 0xFF29b7ff, 0xFF1fb5ff, 0xFF15b2ff, 0xFF20aef7, 0xFF3cb9ff, 0xFF5acbf0,
+ 0xFF42befa, 0xFF2ab6fc, 0xFF12adff, 0xFF18acfc, 0xFF1eacfa, 0xFF1ea9fd, 0xFF1ea7ff, 0xFF1ba8fa,
+ 0xFF18a8f4, 0xFF18a6f8, 0xFF18a4fd, 0xFF19a3fa, 0xFF1aa1f7, 0xFF19a1f7, 0xFF18a0f8, 0xFF17a0f8,
+ 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf6, 0xFF119af5, 0xFF1099f4, 0xFF1099f4,
+ 0xFF54d1f8, 0xFF52d1f8, 0xFF51d0f9, 0xFF4fcff9, 0xFF4ecffa, 0xFF4ccefa, 0xFF4acdf9, 0xFF48ccf9,
+ 0xFF45cbf9, 0xFF45caf9, 0xFF44c9f9, 0xFF43c8f9, 0xFF43c8f9, 0xFF42c7f9, 0xFF42c6f9, 0xFF41c5f9,
+ 0xFF40c5fa, 0xFF3fc4f9, 0xFF3dc2f9, 0xFF3bc1f9, 0xFF3ac0fa, 0xFF38bff9, 0xFF37bff9, 0xFF36bef9,
+ 0xFF34bef8, 0xFF35bcf6, 0xFF35baf5, 0xFF34b8f8, 0xFF33b6fc, 0xFF2eb6f9, 0xFF29b6f7, 0xFF29b5f8,
+ 0xFF2ab4fa, 0xFF2ab5fb, 0xFF2ab5fc, 0xFF2ab2f6, 0xFF2aafef, 0xFF1ba9f6, 0xFF9bcfd9, 0xFF6dcfe9,
+ 0xFF74c7e4, 0xFF80c9dd, 0xFF19adfb, 0xFF1cacf9, 0xFF1fabf8, 0xFF1fa9f9, 0xFF1ea7fb, 0xFF1ca7f9,
+ 0xFF1aa7f6, 0xFF1aa5f8, 0xFF1aa4fb, 0xFF1aa3fa, 0xFF1aa2f8, 0xFF19a1f8, 0xFF18a0f8, 0xFF17a0f8,
+ 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf6, 0xFF119bf5, 0xFF119af5, 0xFF119af5,
+ 0xFF55d0f9, 0xFF53d0fa, 0xFF51d0fa, 0xFF4fcffa, 0xFF4dcffa, 0xFF4bcefa, 0xFF49cdf9, 0xFF46ccf9,
+ 0xFF44caf8, 0xFF43caf8, 0xFF43c9f8, 0xFF43c8f9, 0xFF42c8f9, 0xFF42c7f9, 0xFF41c6f9, 0xFF41c6f9,
+ 0xFF40c5fa, 0xFF3ec3f9, 0xFF3dc2fa, 0xFF3bc1fa, 0xFF39c0fa, 0xFF38bff9, 0xFF36bff9, 0xFF35bef9,
+ 0xFF34bdf8, 0xFF33bcf9, 0xFF33bafa, 0xFF32b9fb, 0xFF32b8fc, 0xFF30b7fa, 0xFF2eb6f8, 0xFF2db5f7,
+ 0xFF2bb4f5, 0xFF2bb4f6, 0xFF2bb3f7, 0xFF29b2f9, 0xFF28b2fc, 0xFF30b2f7, 0xFF12a8fe, 0xFF7fd4e1,
+ 0xFF58bbe6, 0xFF15aafb, 0xFF1fadf8, 0xFF20acf7, 0xFF20aaf5, 0xFF1fa9f6, 0xFF1ea8f7, 0xFF1da6f7,
+ 0xFF1ca5f8, 0xFF1ca4f8, 0xFF1ba3f9, 0xFF1ba3f9, 0xFF1ba2f9, 0xFF19a1f9, 0xFF18a0f8, 0xFF17a0f8,
+ 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5,
+ 0xFF55d0f9, 0xFF53d0fa, 0xFF51d0fa, 0xFF4fcffa, 0xFF4dcffa, 0xFF4bcefa, 0xFF49cdf9, 0xFF46ccf9,
+ 0xFF44caf8, 0xFF43caf8, 0xFF43c9f8, 0xFF43c8f9, 0xFF42c8f9, 0xFF42c7f9, 0xFF41c6f9, 0xFF41c6f9,
+ 0xFF40c5fa, 0xFF3ec3f9, 0xFF3dc2fa, 0xFF3bc1fa, 0xFF39c0fa, 0xFF38bff9, 0xFF36bff9, 0xFF35bef9,
+ 0xFF34bdf8, 0xFF33bcf9, 0xFF33bafa, 0xFF32b9fb, 0xFF32b8fc, 0xFF30b7fa, 0xFF2eb6f8, 0xFF2db5f7,
+ 0xFF2bb4f5, 0xFF2bb4f6, 0xFF2bb3f7, 0xFF2ab2f8, 0xFF29b2fa, 0xFF2db6f5, 0xFF1db5f6, 0xFF239bff,
+ 0xFF20b6f3, 0xFF0cacfb, 0xFF1eacf7, 0xFF1fabf6, 0xFF20aaf5, 0xFF1fa9f6, 0xFF1ea8f7, 0xFF1da6f7,
+ 0xFF1ca5f8, 0xFF1ca4f8, 0xFF1ba3f9, 0xFF1ba3f9, 0xFF1ba2f9, 0xFF19a1f9, 0xFF18a0f8, 0xFF17a0f8,
+ 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5,
+ 0xFF55d0f9, 0xFF53d0fa, 0xFF51d0fa, 0xFF4fcffa, 0xFF4dcffa, 0xFF4bcefa, 0xFF49cdf9, 0xFF46ccf9,
+ 0xFF44caf8, 0xFF43caf8, 0xFF43c9f8, 0xFF43c8f9, 0xFF42c8f9, 0xFF42c7f9, 0xFF41c6f9, 0xFF41c6f9,
+ 0xFF40c5fa, 0xFF3ec3f9, 0xFF3dc2fa, 0xFF3bc1fa, 0xFF39c0fa, 0xFF38bff9, 0xFF36bff9, 0xFF35bef9,
+ 0xFF34bdf8, 0xFF33bcf9, 0xFF33bafa, 0xFF32b9fb, 0xFF32b8fc, 0xFF30b7fa, 0xFF2eb6f8, 0xFF2db5f7,
+ 0xFF2bb4f5, 0xFF2bb4f6, 0xFF2bb3f7, 0xFF2bb2f8, 0xFF2bb1f8, 0xFF22aff9, 0xFF19acfa, 0xFF1eadf7,
+ 0xFF24aef3, 0xFF20adf5, 0xFF1dabf6, 0xFF1fabf6, 0xFF20aaf5, 0xFF1fa9f6, 0xFF1ea8f7, 0xFF1da6f7,
+ 0xFF1ca5f8, 0xFF1ca4f8, 0xFF1ba3f9, 0xFF1ba3f9, 0xFF1ba2f9, 0xFF19a1f9, 0xFF18a0f8, 0xFF17a0f8,
+ 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5,
+ 0xFF55d0f9, 0xFF53d0fa, 0xFF51d0fa, 0xFF4fcffa, 0xFF4dcffa, 0xFF4bcefa, 0xFF49cdf9, 0xFF46ccf9,
+ 0xFF44caf8, 0xFF43caf8, 0xFF43c9f8, 0xFF43c8f9, 0xFF42c8f9, 0xFF42c7f9, 0xFF41c6f9, 0xFF41c6f9,
+ 0xFF40c5fa, 0xFF3ec3f9, 0xFF3dc2fa, 0xFF3bc1fa, 0xFF39c0fa, 0xFF38bff9, 0xFF36bff9, 0xFF35bef9,
+ 0xFF34bdf8, 0xFF33bcf9, 0xFF33bafa, 0xFF32b9fb, 0xFF32b8fc, 0xFF30b7fa, 0xFF2eb6f8, 0xFF2db5f7,
+ 0xFF2bb4f5, 0xFF2bb4f6, 0xFF2bb3f7, 0xFF2bb2f8, 0xFF2bb1f8, 0xFF22aff9, 0xFF19acfa, 0xFF1eadf7,
+ 0xFF24aef3, 0xFF20adf5, 0xFF1dabf6, 0xFF1fabf6, 0xFF20aaf5, 0xFF1fa9f6, 0xFF1ea8f7, 0xFF1da6f7,
+ 0xFF1ca5f8, 0xFF1ca4f8, 0xFF1ba3f9, 0xFF1ba3f9, 0xFF1ba2f9, 0xFF19a1f9, 0xFF18a0f8, 0xFF17a0f8,
+ 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5
+};
+
+static int test_bmp_cmp_count(const BYTE* mem1, const BYTE* mem2, int size, int channel, int margin)
+{
+ int error;
+ int count = 0;
+ int index = 0;
+
+ size /= 4;
+ mem1 += channel;
+ mem2 += channel;
+
+ for (index = 0; index < size; index++)
+ {
+ if (*mem1 != *mem2)
+ {
+ error = (*mem1 > *mem2) ? *mem1 - *mem2 : *mem2 - *mem1;
+
+ if (error > margin)
+ count++;
+ }
+
+ mem1 += 4;
+ mem2 += 4;
+ }
+
+ return count;
+}
+
+static int test_bmp_cmp_dump(const BYTE* actual, const BYTE* expected, int size, int channel, int margin)
+{
+ int x, y;
+ int error[3];
+ UINT32 pixel;
+ int count = 0;
+ int index = 0;
+ BYTE R, G, B;
+ BYTE eR, eG, eB;
+ INT16 Y, Cb, Cr;
+
+ size /= 4;
+ actual += channel;
+ expected += channel;
+
+ for (index = 0; index < size; index++)
+ {
+ if (*actual != *expected)
+ {
+ pixel = *((UINT32*) &actual[-channel]);
+ GetRGB32(R, G, B, pixel);
+
+ pixel = *((UINT32*) &expected[-channel]);
+ GetRGB32(eR, eG, eB, pixel);
+
+ Y = TEST_Y_COMPONENT[index];
+ Cb = TEST_CB_COMPONENT[index];
+ Cr = TEST_CR_COMPONENT[index];
+
+ x = index % 64;
+ y = (index - x) / 64;
+
+ error[0] = (R > eR) ? R - eR : eR - R;
+ error[1] = (G > eG) ? G - eG : eG - G;
+ error[2] = (B > eB) ? B - eB : eB - B;
+
+ if ((error[0] > margin) || (error[1] > margin) || (error[2] > margin))
+ {
+ printf("(%2d,%2d) Y: %+5d Cb: %+5d Cr: %+5d R: %03d/%03d G: %03d/%03d B: %03d/%03d %d %d %d\n",
+ x, y, Y, Cb, Cr, R, eR, G, eG, B, eB, R - eR, G - eG, B - eB);
+ count++;
+ }
+ }
+
+ actual += 4;
+ expected += 4;
+ }
+
+ return count;
+}
+
+static void test_fill_bitmap_channel(BYTE* data, int width, int height, BYTE value, int nChannel)
+{
+ int x, y;
+ BYTE* pChannel;
+
+ pChannel = data + nChannel;
+
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ *pChannel = value;
+ pChannel += 4;
+ }
+ }
+}
+
+#define TEST_FP_TYPE float
+
+static TEST_FP_TYPE TEST_YCbCrToRGB_01[4] = { 1.403f, 0.344f, 0.714f, 1.770f };
+static TEST_FP_TYPE TEST_YCbCrToRGB_02[4] = { 1.402525f, 0.343730f, 0.714401f, 1.769905f };
+static TEST_FP_TYPE TEST_YCbCrToRGB_03[4] = { 1.402524948120117L, 0.3437300026416779L, 0.7144010066986084L, 1.769904971122742L };
+
+static INT16 TEST_YCbCr_01[3] = { +3443, -1863, +272 };
+static BYTE TEST_RGB_01[3] = { 247, 249, 132 };
+
+static INT16 TEST_YCbCr_02[3] = { +1086, +1584, -2268 };
+static BYTE TEST_RGB_02[3] = { 62, 195, 249 };
+
+static INT16 TEST_YCbCr_03[3] = { -576, +2002, -2179 };
+static BYTE TEST_RGB_03[3] = { 15, 137, 221 };
+
+int test_YCbCr_fp(TEST_FP_TYPE coeffs[4], INT16 YCbCr[3], BYTE RGB[3])
+{
+ INT16 R, G, B;
+ TEST_FP_TYPE Y, Cb, Cr;
+ TEST_FP_TYPE fR, fG, fB;
+ TEST_FP_TYPE fR1, fR2;
+
+ Y = (TEST_FP_TYPE) (YCbCr[0] + 4096);
+ Cb = (TEST_FP_TYPE) (YCbCr[1]);
+ Cr = (TEST_FP_TYPE) (YCbCr[2]);
+
+#if 1
+ fR1 = Cr * coeffs[0];
+ fR2 = fR1 + Y + 16.0f;
+
+ fR = ((Cr * coeffs[0]) + Y + 16.0f);
+ fG = (Y - (Cb * coeffs[1]) - (Cr * coeffs[2]) + 16.0f);
+ fB = ((Cb * coeffs[3]) + Y + 16.0f);
+
+ printf("fR: %f fG: %f fB: %f fY: %f\n", fR, fG, fB, Y);
+
+ R = (INT16) fR;
+ G = (INT16) fG;
+ B = (INT16) fB;
+
+ printf("mR: %d mG: %d mB: %d\n",
+ (R - 16) % 32, (G - 16) % 32, (B - 16) % 32);
+
+ printf("iR: %d iG: %d iB: %d\n", R, G, B);
+
+ R >>= 5;
+ G >>= 5;
+ B >>= 5;
+
+ printf("R5: %d G5: %d B5: %d\n", R, G, B);
+
+#else
+ R = ((INT16) (((Cr * coeffs[0]) + Y + 16.0f)) >> 5);
+ G = ((INT16) ((Y - (Cb * coeffs[1]) - (Cr * coeffs[2]) + 16.0f)) >> 5);
+ B = ((INT16) (((Cb * coeffs[3]) + Y + 16.0f)) >> 5);
+#endif
+
+ if (R < 0)
+ R = 0;
+ else if (R > 255)
+ R = 255;
+
+ if (G < 0)
+ G = 0;
+ else if (G > 255)
+ G = 255;
+
+ if (B < 0)
+ B = 0;
+ else if (B > 255)
+ B = 255;
+
+ printf("--------------------------------\n");
+ printf("R: A: %3d E: %3d %s\n", R, RGB[0], (R == RGB[0]) ? "" : "***");
+ printf("G: A: %3d E: %3d %s\n", G, RGB[1], (G == RGB[1]) ? "" : "***");
+ printf("B: A: %3d E: %3d %s\n", B, RGB[2], (B == RGB[2]) ? "" : "***");
+ printf("Y: %+5d Cb: %+5d Cr: %+5d\n", YCbCr[0], YCbCr[1], YCbCr[2]);
+ //printf("[0]: %20.20lf\n", coeffs[0]);
+ //printf("[1]: %20.20lf\n", coeffs[1]);
+ //printf("[2]: %20.20lf\n", coeffs[2]);
+ //printf("[3]: %20.20lf\n", coeffs[3]);
+ printf("--------------------------------\n\n");
+
+ return 0;
+}
+
+int test_YCbCr_pixels()
+{
+ if (0)
+ {
+ test_YCbCr_fp(TEST_YCbCrToRGB_01, TEST_YCbCr_01, TEST_RGB_01);
+ test_YCbCr_fp(TEST_YCbCrToRGB_01, TEST_YCbCr_02, TEST_RGB_02);
+ test_YCbCr_fp(TEST_YCbCrToRGB_01, TEST_YCbCr_03, TEST_RGB_03);
+ }
+
+ if (1)
+ {
+ test_YCbCr_fp(TEST_YCbCrToRGB_02, TEST_YCbCr_01, TEST_RGB_01);
+ test_YCbCr_fp(TEST_YCbCrToRGB_02, TEST_YCbCr_02, TEST_RGB_02);
+ test_YCbCr_fp(TEST_YCbCrToRGB_02, TEST_YCbCr_03, TEST_RGB_03);
+ }
+
+ if (0)
+ {
+ test_YCbCr_fp(TEST_YCbCrToRGB_03, TEST_YCbCr_01, TEST_RGB_01);
+ test_YCbCr_fp(TEST_YCbCrToRGB_03, TEST_YCbCr_02, TEST_RGB_02);
+ test_YCbCr_fp(TEST_YCbCrToRGB_03, TEST_YCbCr_03, TEST_RGB_03);
+ }
+
+ return 0;
+}
+
+int TestPrimitivesYCbCr(int argc, char* argv[])
+{
+ int size;
+ int cnt[3];
+ float err[3];
+ BYTE* actual;
+ BYTE* expected;
+ int margin = 1;
+ INT16* pYCbCr[3];
+ const primitives_t* prims = primitives_get();
+ static const prim_size_t roi_64x64 = { 64, 64 };
+
+ //return test_YCbCr_pixels();
+
+ expected = (BYTE*) TEST_XRGB_IMAGE;
+
+ size = 64 * 64 * 4;
+ actual = _aligned_malloc(size, 16);
+
+ if (!actual)
+ return 1;
+
+ ZeroMemory(actual, size);
+
+ pYCbCr[0] = TEST_Y_COMPONENT;
+ pYCbCr[1] = TEST_CB_COMPONENT;
+ pYCbCr[2] = TEST_CR_COMPONENT;
+
+ if (1)
+ {
+ prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pYCbCr, 64 * 2,
+ actual, 64 * 4, &roi_64x64);
+ }
+ else
+ {
+ INT16* pSrcDst[3];
+
+ pSrcDst[0] = _aligned_malloc(4096 * 2, 16);
+ pSrcDst[1] = _aligned_malloc(4096 * 2, 16);
+ pSrcDst[2] = _aligned_malloc(4096 * 2, 16);
+
+ CopyMemory(pSrcDst[0], pYCbCr[0], 4096 * 2);
+ CopyMemory(pSrcDst[1], pYCbCr[1], 4096 * 2);
+ CopyMemory(pSrcDst[2], pYCbCr[2], 4096 * 2);
+
+ prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * 2,
+ pSrcDst, 64 * 2, &roi_64x64);
+
+ prims->RGBToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2,
+ actual, 64 * 4, &roi_64x64);
+
+ _aligned_free(pSrcDst[0]);
+ _aligned_free(pSrcDst[1]);
+ _aligned_free(pSrcDst[2]);
+ }
+
+ if (0)
+ {
+ test_fill_bitmap_channel(actual, 64, 64, 0, 2); /* red */
+ test_fill_bitmap_channel(expected, 64, 64, 0, 2); /* red */
+ }
+
+ if (0)
+ {
+ test_fill_bitmap_channel(actual, 64, 64, 0, 1); /* green */
+ test_fill_bitmap_channel(expected, 64, 64, 0, 1); /* green */
+ }
+
+ if (0)
+ {
+ test_fill_bitmap_channel(actual, 64, 64, 0, 0); /* blue */
+ test_fill_bitmap_channel(expected, 64, 64, 0, 0); /* blue */
+ }
+
+ cnt[2] = test_bmp_cmp_count(actual, expected, size, 2, margin); /* red */
+ err[2] = ((float) cnt[2]) / ((float) size / 4) * 100.0f;
+
+ cnt[1] = test_bmp_cmp_count(actual, expected, size, 1, margin); /* green */
+ err[1] = ((float) cnt[1]) / ((float) size / 4) * 100.0f;
+
+ cnt[0] = test_bmp_cmp_count(actual, expected, size, 0, margin); /* blue */
+ err[0] = ((float) cnt[0]) / ((float) size / 4) * 100.0f;
+
+ if (cnt[0] || cnt[1] || cnt[2])
+ {
+ printf("Red Error Dump:\n");
+ test_bmp_cmp_dump(actual, expected, size, 2, margin); /* red */
+
+ printf("Green Error Dump:\n");
+ test_bmp_cmp_dump(actual, expected, size, 1, margin); /* green */
+
+ printf("Blue Error Dump:\n");
+ test_bmp_cmp_dump(actual, expected, size, 0, margin); /* blue */
+
+ printf("R: diff: %d (%f%%)\n", cnt[2], err[2]);
+ printf("G: diff: %d (%f%%)\n", cnt[1], err[1]);
+ printf("B: diff: %d (%f%%)\n", cnt[0], err[0]);
+ }
+
+ _aligned_free(actual);
+
+ return 0;
+}
+
static const int YCOCG_TRIAL_ITERATIONS = 20000;
static const float TEST_TIME = 4.0;
-extern pstatus_t general_YCoCgRToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep,
+extern BOOL g_TestPrimitivesPerformance;
+
+extern pstatus_t general_YCoCgToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep,
BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height,
UINT8 shift, BOOL withAlpha, BOOL invert);
extern pstatus_t ssse3_YCoCgRToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep,
testStr[0] = '\0';
get_random_data(in, sizeof(in));
- general_YCoCgRToRGB_8u_AC4R((const BYTE *) (in+1), 63*4,
+ general_YCoCgToRGB_8u_AC4R((const BYTE *) (in+1), 63*4,
(BYTE *) out_c, 63*4, 63, 61, 2, TRUE, FALSE);
- general_YCoCgRToRGB_8u_AC4R((const BYTE *) (in+1), 63*4,
+ general_YCoCgToRGB_8u_AC4R((const BYTE *) (in+1), 63*4,
(BYTE *) out_c_inv, 63*4, 63, 61, 2, TRUE, TRUE);
#ifdef WITH_SSE2
if (IsProcessorFeaturePresentEx(PF_EX_SSSE3))
/* ------------------------------------------------------------------------- */
STD_SPEED_TEST(
ycocg_to_rgb_speed, const BYTE, BYTE, PRIM_NOP,
- TRUE, general_YCoCgRToRGB_8u_AC4R(src1, 64*4, dst, 64*4, 64, 64, 2, FALSE, FALSE),
+ TRUE, general_YCoCgToRGB_8u_AC4R(src1, 64*4, dst, 64*4, 64, 64, 2, FALSE, FALSE),
#ifdef WITH_SSE2
TRUE, ssse3_YCoCgRToRGB_8u_AC4R(src1, 64*4, dst, 64*4, 64, 64, 2, FALSE, FALSE),
PF_EX_SSSE3, TRUE,
{
INT32 ALIGN(in[4096]);
INT32 ALIGN(out[4096]);
- int i;
int size_array[] = { 64 };
get_random_data(in, sizeof(in));
size_array, 1, YCOCG_TRIAL_ITERATIONS, TEST_TIME);
return SUCCESS;
}
+
+int TestPrimitivesYCoCg(int argc, char* argv[])
+{
+ int status;
+
+ status = test_YCoCgRToRGB_8u_AC4R_func();
+
+ if (status != SUCCESS)
+ return 1;
+
+ if (g_TestPrimitivesPerformance)
+ {
+ status = test_YCoCgRToRGB_8u_AC4R_speed();
+
+ if (status != SUCCESS)
+ return 1;
+ }
+
+ return 0;
+}
* Define GOOGLE_PROFILER if you want gperftools included.
*/
-#ifdef _GNUC_
-# pragma once
-#endif
-
#ifndef __MEASURE_H_INCLUDED__
#define __MEASURE_H_INCLUDED__
#include <sys/param.h>
#endif
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include <winpr/crt.h>
+
+#ifdef _WIN32
+
+#define PROFILER_START(_prefix_)
+#define PROFILER_STOP
+
+#define MEASURE_LOOP_START(_prefix_, _count_)
+#define MEASURE_LOOP_STOP
+#define MEASURE_GET_RESULTS(_result_)
+#define MEASURE_SHOW_RESULTS(_result_)
+#define MEASURE_SHOW_RESULTS_SCALED(_scale_, _label_)
+#define MEASURE_TIMED(_label_, _init_iter_, _test_time_, _result_, _call_)
+
+#else
#ifdef GOOGLE_PROFILER
#include <gperftools/profiler.h>
MEASURE_SHOW_RESULTS(_result_); \
}
+#endif
+
#endif // __MEASURE_H_INCLUDED__
#include "prim_test.h"
+#ifndef _WIN32
+#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
-#include <winpr/platform.h>
+#endif
+
#include <winpr/sysinfo.h>
+#include <winpr/platform.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include <stdlib.h>
-#include <time.h>
-
+BOOL g_TestPrimitivesPerformance = FALSE;
int test_sizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
-int Quiet = 0;
-
-
-
-/* ------------------------------------------------------------------------- */
-typedef struct
-{
- UINT32 flag;
- const char *str;
-} flagpair_t;
-
-static const flagpair_t flags[] =
-{
-#ifdef _M_IX86_AMD64
- { PF_MMX_INSTRUCTIONS_AVAILABLE, "MMX" },
- { PF_3DNOW_INSTRUCTIONS_AVAILABLE, "3DNow" },
- { PF_SSE_INSTRUCTIONS_AVAILABLE, "SSE" },
- { PF_SSE2_INSTRUCTIONS_AVAILABLE, "SSE2" },
- { PF_SSE3_INSTRUCTIONS_AVAILABLE, "SSE3" },
-#elif defined(_M_ARM)
- { PF_ARM_VFP3, "VFP3" },
- { PF_ARM_INTEL_WMMX, "IWMMXT" },
- { PF_ARM_NEON_INSTRUCTIONS_AVAILABLE, "NEON" },
-#endif
-};
-
-static const flagpair_t flags_extended[] =
-{
-#ifdef _M_IX86_AMD64
- { PF_EX_3DNOW_PREFETCH, "3DNow-PF" },
- { PF_EX_SSSE3, "SSSE3" },
- { PF_EX_SSE41, "SSE4.1" },
- { PF_EX_SSE42, "SSE4.2" },
- { PF_EX_AVX, "AVX" },
- { PF_EX_FMA, "FMA" },
- { PF_EX_AVX_AES, "AVX-AES" },
- { PF_EX_AVX2, "AVX2" },
-#elif defined(_M_ARM)
- { PF_EX_ARM_VFP1, "VFP1"},
- { PF_EX_ARM_VFP4, "VFP4" },
-#endif
-};
-
-void primitives_flags_str(char* str, size_t len)
-{
- int i;
-
- *str = '\0';
- --len; /* for the '/0' */
-
- for (i = 0; i < sizeof(flags) / sizeof(flagpair_t); ++i)
- {
- if (IsProcessorFeaturePresent(flags[i].flag))
- {
- int slen = strlen(flags[i].str) + 1;
-
- if (len < slen)
- break;
-
- if (*str != '\0')
- strcat(str, " ");
-
- strcat(str, flags[i].str);
- len -= slen;
- }
- }
- for (i = 0; i < sizeof(flags_extended) / sizeof(flagpair_t); ++i)
- {
- if (IsProcessorFeaturePresentEx(flags_extended[i].flag))
- {
- int slen = strlen(flags_extended[i].str) + 1;
-
- if (len < slen)
- break;
-
- if (*str != '\0')
- strcat(str, " ");
-
- strcat(str, flags_extended[i].str);
- len -= slen;
- }
- }
-}
/* ------------------------------------------------------------------------- */
-static void get_random_data_lrand(
- void *buffer,
- size_t size)
+static void get_random_data_lrand(void *buffer, size_t size)
{
static int seeded = 0;
long int *ptr = (long int *) buffer;
}
/* ------------------------------------------------------------------------- */
-void get_random_data(
- void *buffer,
- size_t size)
+void get_random_data(void *buffer, size_t size)
{
-#ifdef linux
+#ifdef __linux__
size_t offset = 0;
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0)
}
/* ------------------------------------------------------------------------- */
-float _delta_time(
- const struct timespec *t0,
- const struct timespec *t1)
+
+#ifdef _WIN32
+float _delta_time(const struct timespec *t0, const struct timespec *t1) { return 0.0f; }
+#else
+float _delta_time(const struct timespec *t0, const struct timespec *t1)
{
- INT64 secs = (INT64) (t1->tv_sec) - (INT64) (t0->tv_sec);
- long nsecs = t1->tv_nsec - t0->tv_nsec;
+ INT64 secs = (INT64) (t1->tv_sec) - (INT64) (t0->tv_sec);
+ long nsecs = t1->tv_nsec - t0->tv_nsec;
double retval;
- if (nsecs < 0)
+ if (nsecs < 0)
{
- --secs;
- nsecs += 1000000000;
- }
- retval = (double) secs + (double) nsecs / (double) 1000000000.0;
- return (retval < 0.0) ? 0.0 : (float) retval;
-}
+ --secs;
+ nsecs += 1000000000;
+ }
-/* ------------------------------------------------------------------------- */
-void _floatprint(
- float t,
- char *output)
-{
- /* I don't want to link against -lm, so avoid log,exp,... */
- float f = 10.0;
- int i;
- while (t > f) f *= 10.0;
- f /= 1000.0;
- i = ((int) (t/f+0.5)) * (int) f;
- if (t < 0.0) sprintf(output, "%f", t);
- else if (i == 0) sprintf(output, "%d", (int) (t+0.5));
- else if (t < 1e+3) sprintf(output, "%3d", i);
- else if (t < 1e+6) sprintf(output, "%3d,%03d",
- i/1000, i % 1000);
- else if (t < 1e+9) sprintf(output, "%3d,%03d,000",
- i/1000000, (i % 1000000) / 1000);
- else if (t < 1e+12) sprintf(output, "%3d,%03d,000,000",
- i/1000000000, (i % 1000000000) / 1000000);
- else sprintf(output, "%f", t);
+ retval = (double) secs + (double) nsecs / (double) 1000000000.0;
+ return (retval < 0.0) ? 0.0 : (float) retval;
}
+#endif
/* ------------------------------------------------------------------------- */
-/* Specific areas to test: */
-#define TEST_COPY8 (1<<0)
-#define TEST_SET8 (1<<1)
-#define TEST_SET32S (1<<2)
-#define TEST_SET32U (1<<3)
-#define TEST_SIGN16S (1<<4)
-#define TEST_ADD16S (1<<5)
-#define TEST_LSHIFT16S (1<<6)
-#define TEST_LSHIFT16U (1<<7)
-#define TEST_RSHIFT16S (1<<8)
-#define TEST_RSHIFT16U (1<<9)
-#define TEST_RGB (1<<10)
-#define TEST_ALPHA (1<<11)
-#define TEST_AND (1<<12)
-#define TEST_OR (1<<13)
-#define TEST_YCOCG (1<<14)
-#define TEST_16TO32 (1<<15)
-
-/* Specific types of testing: */
-#define TEST_FUNCTIONALITY (1<<0)
-#define TEST_PERFORMANCE (1<<1)
-
-/* ------------------------------------------------------------------------- */
-
-typedef struct
-{
- const char *testStr;
- UINT32 bits;
-} test_t;
-
-static const test_t testList[] =
-{
- { "all", 0xFFFFFFFFU },
- { "copy", TEST_COPY8 },
- { "copy8", TEST_COPY8 },
- { "set", TEST_SET8|TEST_SET32S|TEST_SET32U },
- { "set8", TEST_SET8 },
- { "set32", TEST_SET32S|TEST_SET32U },
- { "set32s", TEST_SET32S },
- { "set32u", TEST_SET32U },
- { "sign", TEST_SIGN16S },
- { "sign16s", TEST_SIGN16S },
- { "add", TEST_ADD16S },
- { "add16s", TEST_ADD16S },
- { "lshift", TEST_LSHIFT16S|TEST_LSHIFT16U },
- { "rshift", TEST_RSHIFT16S|TEST_RSHIFT16U },
- { "shift", TEST_LSHIFT16S|TEST_LSHIFT16U|TEST_RSHIFT16S|TEST_RSHIFT16U },
- { "lshift16s", TEST_LSHIFT16S },
- { "lshift16u", TEST_LSHIFT16U },
- { "rshift16s", TEST_RSHIFT16S },
- { "rshift16u", TEST_RSHIFT16U },
- { "rgb", TEST_RGB },
- { "color", TEST_RGB },
- { "colors", TEST_RGB },
- { "ycocg", TEST_YCOCG },
- { "alpha", TEST_ALPHA },
- { "and", TEST_AND },
- { "or", TEST_OR },
- { "16to32", TEST_16TO32 }
-};
-
-#define NUMTESTS (sizeof(testList)/sizeof(test_t))
-
-static const test_t testTypeList[] =
-{
- { "functionality", TEST_FUNCTIONALITY },
- { "performance", TEST_PERFORMANCE },
-};
-
-#define NUMTESTTYPES (sizeof(testTypeList)/sizeof(test_t))
-
-int main(int argc, char** argv)
+void _floatprint(float t, char *output)
{
+ /* I don't want to link against -lm, so avoid log,exp,... */
+ float f = 10.0;
int i;
- char hints[1024];
- UINT32 testSet = 0;
- UINT32 testTypes = 0;
- int results = SUCCESS;
-
- /* Parse command line for the test set. */
-
- for (i = 1; i < argc; ++i)
- {
- int j;
- BOOL found = 0;
-
- for (j=0; j<NUMTESTS; ++j)
- {
- if (strcasecmp(argv[i], testList[j].testStr) == 0)
- {
- testSet |= testList[j].bits;
- found = 1;
- break;
- }
- }
- for (j=0; j<NUMTESTTYPES; ++j)
- {
- if (strcasecmp(argv[i], testTypeList[j].testStr) == 0)
- {
- testTypes |= testTypeList[j].bits;
- found = 1;
- break;
- }
- }
- if (!found)
- {
- if (strstr(argv[i], "help") != NULL)
- {
- printf("Available tests:\n");
- for (j=0; j<NUMTESTS; ++j)
- {
- printf(" %s\n", testList[j].testStr);
- }
- for (j=0; j<NUMTESTTYPES; ++j)
- {
- printf(" %s\n", testTypeList[j].testStr);
- }
- }
- else fprintf(stderr, "Unknown parameter '%s'!\n", argv[i]);
- }
- }
-
- if (testSet == 0)
- testSet = 0xffffffff;
- if (testTypes == 0)
- testTypes = 0xffffffff;
-
- primitives_init();
-
- primitives_flags_str(hints, sizeof(hints));
- printf("Hints: %s\n", hints);
-
- /* COPY */
- if (testSet & TEST_COPY8)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_copy8u_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_copy8u_speed();
- }
- }
- /* SET */
- if (testSet & TEST_SET8)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_set8u_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_set8u_speed();
- }
- }
- if (testSet & TEST_SET32S)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_set32s_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_set32s_speed();
- }
- }
- if (testSet & TEST_SET32U)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_set32u_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_set32u_speed();
- }
- }
- /* SIGN */
- if (testSet & TEST_SIGN16S)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_sign16s_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_sign16s_speed();
- }
- }
- /* ADD */
- if (testSet & TEST_ADD16S)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_add16s_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_add16s_speed();
- }
- }
- /* SHIFTS */
- if (testSet & TEST_LSHIFT16S)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_lShift_16s_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_lShift_16s_speed();
- }
- }
- if (testSet & TEST_LSHIFT16U)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_lShift_16u_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_lShift_16u_speed();
- }
- }
- if (testSet & TEST_RSHIFT16S)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_rShift_16s_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_rShift_16s_speed();
- }
- }
- if (testSet & TEST_RSHIFT16U)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_rShift_16u_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_rShift_16u_speed();
- }
- }
- /* COLORS */
- if (testSet & TEST_RGB)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_RGBToRGB_16s8u_P3AC4R_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_RGBToRGB_16s8u_P3AC4R_speed();
- }
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_yCbCrToRGB_16s16s_P3P3_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_yCbCrToRGB_16s16s_P3P3_speed();
- }
- }
- if (testSet & TEST_YCOCG)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_YCoCgRToRGB_8u_AC4R_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_YCoCgRToRGB_8u_AC4R_speed();
- }
- }
- /* 16 to 32 BPP */
- if (testSet & TEST_16TO32)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_RGB565ToARGB_16u32u_C3C4_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_RGB565ToARGB_16u32u_C3C4_speed();
- }
- }
- /* ALPHA COMPOSITION */
- if (testSet & TEST_ALPHA)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_alphaComp_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_alphaComp_speed();
- }
- }
- /* AND & OR */
- if (testSet & TEST_AND)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_and_32u_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_and_32u_speed();
- }
- }
- if (testSet & TEST_OR)
- {
- if (testTypes & TEST_FUNCTIONALITY)
- {
- results |= test_or_32u_func();
- }
- if (testTypes & TEST_PERFORMANCE)
- {
- results |= test_or_32u_speed();
- }
- }
-
- primitives_deinit();
- return results;
+ while (t > f) f *= 10.0;
+ f /= 1000.0;
+ i = ((int) (t/f+0.5)) * (int) f;
+ if (t < 0.0) sprintf(output, "%f", t);
+ else if (i == 0) sprintf(output, "%d", (int) (t+0.5));
+ else if (t < 1e+3) sprintf(output, "%3d", i);
+ else if (t < 1e+6) sprintf(output, "%3d,%03d",
+ i/1000, i % 1000);
+ else if (t < 1e+9) sprintf(output, "%3d,%03d,000",
+ i/1000000, (i % 1000000) / 1000);
+ else if (t < 1e+12) sprintf(output, "%3d,%03d,000,000",
+ i/1000000000, (i % 1000000000) / 1000000);
+ else sprintf(output, "%f", t);
}
* this code may be covered by patents by HP, Microsoft, or other parties.
*/
-#ifdef __GNUC__
-# pragma once
-#endif
-
#ifndef __PRIMTEST_H_INCLUDED__
#define __PRIMTEST_H_INCLUDED__
-#include <config.h>
-#include <stdint.h>
+#include <winpr/crt.h>
+#include <winpr/spec.h>
#include <winpr/wtypes.h>
-
-#include <measure.h>
-#include <string.h>
-#include <stdio.h>
+#include <winpr/platform.h>
#include <freerdp/primitives.h>
-#include <winpr/platform.h>
+
+#include "measure.h"
#ifdef WITH_IPP
#include <ipps.h>
#include <ippi.h>
#endif
-#define BLOCK_ALIGNMENT 16
-#ifdef __GNUC__
-#define ALIGN(x) x __attribute((aligned(BLOCK_ALIGNMENT)))
-#define POSSIBLY_UNUSED(x) x __attribute((unused))
-#else
-/* TODO: Someone needs to finish this for non-GNU C */
+#ifdef _WIN32
#define ALIGN(x) x
-#define POSSIBLY_UNUSED(x) x
+#else
+#define ALIGN(x) x DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
#endif
+
#define ABS(_x_) ((_x_) < 0 ? (-(_x_)) : (_x_))
#define MAX_TEST_SIZE 4096
#define PRIM_NOP do {} while (0)
/* ------------------------------------------------------------------------- */
+
+#ifdef _WIN32
+#define STD_SPEED_TEST( \
+ _name_, _srctype_, _dsttype_, _prework_, \
+ _doNormal_, _funcNormal_, \
+ _doOpt_, _funcOpt_, _flagOpt_, _flagExt_, \
+ _doIPP_, _funcIPP_)
+#else
#define STD_SPEED_TEST( \
_name_, _srctype_, _dsttype_, _prework_, \
_doNormal_, _funcNormal_, \
} \
free(resultNormal); free(resultOpt); free(resultIPP); \
}
+#endif
#endif // !__PRIMTEST_H_INCLUDED__
#include <winpr/stream.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/rail/icon.h>
ICON_INFO* icon_cache_get(rdpIconCache* cache, BYTE id, UINT16 index, void** extra)
if (id >= cache->numCaches)
{
- fprintf(stderr, "invalid window icon cache id:%d\n", id);
+ DEBUG_WARN( "invalid window icon cache id:%d\n", id);
return (ICON_INFO*) NULL;
}
if (index >= cache->numCacheEntries)
{
- fprintf(stderr, "invalid window icon cache index:%d in cache id:%d\n", index, id);
+ DEBUG_WARN( "invalid window icon cache index:%d in cache id:%d\n", index, id);
return (ICON_INFO*) NULL;
}
{
if (id >= cache->numCaches)
{
- fprintf(stderr, "invalid window icon cache id:%d\n", id);
+ DEBUG_WARN( "invalid window icon cache id:%d\n", id);
return;
}
if (index >= cache->numCacheEntries)
{
- fprintf(stderr, "invalid window icon cache index:%d in cache id:%d\n", index, id);
+ DEBUG_WARN( "invalid window icon cache index:%d in cache id:%d\n", index, id);
return;
}
#include "librail.h"
+#include <freerdp/log.h>
#include <freerdp/rail/window.h>
+#define TAG FREERDP_TAG("rail")
+
struct _WINDOW_STYLE
{
UINT32 style;
void print_window_styles(UINT32 style)
{
int i;
+ DEBUG_WARN("Window Styles:\n{\n");
- fprintf(stderr, "Window Styles:\n{\n");
for (i = 0; i < ARRAYSIZE(WINDOW_STYLES); i++)
{
if (style & WINDOW_STYLES[i].style)
if (WINDOW_STYLES[i].multi)
{
if ((style & WINDOW_STYLES[i].style) != WINDOW_STYLES[i].style)
- continue;
+ continue;
}
- fprintf(stderr, "\t%s\n", WINDOW_STYLES[i].name);
+ DEBUG_WARN("\t%s\n", WINDOW_STYLES[i].name);
}
}
- fprintf(stderr, "}\n");
+
+ DEBUG_WARN("}\n");
}
void print_extended_window_styles(UINT32 style)
{
int i;
+ DEBUG_WARN("Extended Window Styles:\n{\n");
- fprintf(stderr, "Extended Window Styles:\n{\n");
for (i = 0; i < ARRAYSIZE(EXTENDED_WINDOW_STYLES); i++)
{
if (style & EXTENDED_WINDOW_STYLES[i].style)
if (EXTENDED_WINDOW_STYLES[i].multi)
{
if ((style & EXTENDED_WINDOW_STYLES[i].style) != EXTENDED_WINDOW_STYLES[i].style)
- continue;
+ continue;
}
- fprintf(stderr, "\t%s\n", EXTENDED_WINDOW_STYLES[i].name);
+ DEBUG_WARN("\t%s\n", EXTENDED_WINDOW_STYLES[i].name);
}
}
- fprintf(stderr, "}\n");
+
+ DEBUG_WARN("}\n");
}
void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state)
}
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);
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
}
{
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)
{
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)
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);
}
}
{
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)
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);
}
}
}
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
{
{
IFCALL(rail->rail_SetWindowRects, rail, window);
}
+
if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
{
IFCALL(rail->rail_SetWindowVisibilityRects, rail, window);
{
if (window->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
{
-
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
{
-
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
}
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) ||
if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
{
-
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
if (window->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
{
-
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
set(${MODULE_PREFIX}_SRCS
event.c
- bitmap.c
passphrase.c
pcap.c
profiler.c
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * Bitmap File Format Utils
- *
- * Copyright 2011 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 <stdio.h>
-#include <string.h>
-
-#include <freerdp/types.h>
-
-#include <freerdp/utils/bitmap.h>
-
-typedef struct
-{
- BYTE magic[2];
-} BITMAP_MAGIC;
-
-typedef struct
-{
- UINT32 filesz;
- UINT16 creator1;
- UINT16 creator2;
- UINT32 bmp_offset;
-} BITMAP_CORE_HEADER;
-
-typedef struct
-{
- UINT32 header_sz;
- INT32 width;
- INT32 height;
- UINT16 nplanes;
- UINT16 bitspp;
- UINT32 compress_type;
- UINT32 bmp_bytesz;
- INT32 hres;
- INT32 vres;
- UINT32 ncolors;
- UINT32 nimpcolors;
-} BITMAP_INFO_HEADER;
-
-void freerdp_bitmap_write(char* filename, void* data, int width, int height, int bpp)
-{
- FILE* fp;
- BITMAP_MAGIC magic;
- BITMAP_CORE_HEADER header;
- BITMAP_INFO_HEADER info_header;
-
- fp = fopen(filename, "w+b");
-
- if (fp == NULL)
- {
- fprintf(stderr, "failed to open file %s\n", filename);
- return;
- }
-
- magic.magic[0] = 'B';
- magic.magic[1] = 'M';
-
- header.creator1 = 0;
- header.creator2 = 0;
-
- header.bmp_offset =
- sizeof(BITMAP_MAGIC) +
- sizeof(BITMAP_CORE_HEADER) +
- sizeof(BITMAP_INFO_HEADER);
-
- info_header.bmp_bytesz = width * height * (bpp / 8);
-
- header.filesz =
- header.bmp_offset +
- info_header.bmp_bytesz;
-
- info_header.width = width;
- info_header.height = (-1) * height;
- info_header.nplanes = 1;
- info_header.bitspp = bpp;
- info_header.compress_type = 0;
- info_header.hres = width;
- info_header.vres = height;
- info_header.ncolors = 0;
- info_header.nimpcolors = 0;
- info_header.header_sz = sizeof(BITMAP_INFO_HEADER);
-
- fwrite((void*) &magic, sizeof(BITMAP_MAGIC), 1, fp);
- fwrite((void*) &header, sizeof(BITMAP_CORE_HEADER), 1, fp);
- fwrite((void*) &info_header, sizeof(BITMAP_INFO_HEADER), 1, fp);
- fwrite((void*) data, info_header.bmp_bytesz, 1, fp);
-
- fclose(fp);
-}
-
MSUSB_PIPE_DESCRIPTOR * MsPipe;
int inum = 0, pnum = 0;
- fprintf(stderr, "=================MsConfig:========================\n");
- fprintf(stderr, "wTotalLength:%d\n", MsConfig->wTotalLength);
- fprintf(stderr, "bConfigurationValue:%d\n", MsConfig->bConfigurationValue);
- fprintf(stderr, "ConfigurationHandle:0x%x\n", MsConfig->ConfigurationHandle);
- fprintf(stderr, "InitCompleted:%d\n", MsConfig->InitCompleted);
- fprintf(stderr, "MsOutSize:%d\n", MsConfig->MsOutSize);
- fprintf(stderr, "NumInterfaces:%d\n\n", MsConfig->NumInterfaces);
+ DEBUG_WARN( "=================MsConfig:========================\n");
+ DEBUG_WARN( "wTotalLength:%d\n", MsConfig->wTotalLength);
+ DEBUG_WARN( "bConfigurationValue:%d\n", MsConfig->bConfigurationValue);
+ DEBUG_WARN( "ConfigurationHandle:0x%x\n", MsConfig->ConfigurationHandle);
+ DEBUG_WARN( "InitCompleted:%d\n", MsConfig->InitCompleted);
+ DEBUG_WARN( "MsOutSize:%d\n", MsConfig->MsOutSize);
+ DEBUG_WARN( "NumInterfaces:%d\n\n", MsConfig->NumInterfaces);
MsInterfaces = MsConfig->MsInterfaces;
for(inum = 0; inum < MsConfig->NumInterfaces; inum++)
{
MsInterface = MsInterfaces[inum];
- fprintf(stderr, " Interfase: %d\n", MsInterface->InterfaceNumber);
- fprintf(stderr, " Length: %d\n", MsInterface->Length);
- fprintf(stderr, " NumberOfPipesExpected: %d\n", MsInterface->NumberOfPipesExpected);
- fprintf(stderr, " AlternateSetting: %d\n", MsInterface->AlternateSetting);
- fprintf(stderr, " NumberOfPipes: %d\n", MsInterface->NumberOfPipes);
- fprintf(stderr, " InterfaceHandle: 0x%x\n", MsInterface->InterfaceHandle);
- fprintf(stderr, " bInterfaceClass: 0x%x\n", MsInterface->bInterfaceClass);
- fprintf(stderr, " bInterfaceSubClass: 0x%x\n", MsInterface->bInterfaceSubClass);
- fprintf(stderr, " bInterfaceProtocol: 0x%x\n", MsInterface->bInterfaceProtocol);
- fprintf(stderr, " InitCompleted: %d\n\n", MsInterface->InitCompleted);
+ DEBUG_WARN( " Interfase: %d\n", MsInterface->InterfaceNumber);
+ DEBUG_WARN( " Length: %d\n", MsInterface->Length);
+ DEBUG_WARN( " NumberOfPipesExpected: %d\n", MsInterface->NumberOfPipesExpected);
+ DEBUG_WARN( " AlternateSetting: %d\n", MsInterface->AlternateSetting);
+ DEBUG_WARN( " NumberOfPipes: %d\n", MsInterface->NumberOfPipes);
+ DEBUG_WARN( " InterfaceHandle: 0x%x\n", MsInterface->InterfaceHandle);
+ DEBUG_WARN( " bInterfaceClass: 0x%x\n", MsInterface->bInterfaceClass);
+ DEBUG_WARN( " bInterfaceSubClass: 0x%x\n", MsInterface->bInterfaceSubClass);
+ DEBUG_WARN( " bInterfaceProtocol: 0x%x\n", MsInterface->bInterfaceProtocol);
+ DEBUG_WARN( " InitCompleted: %d\n\n", MsInterface->InitCompleted);
MsPipes = MsInterface->MsPipes;
for (pnum = 0; pnum < MsInterface->NumberOfPipes; pnum++)
{
MsPipe = MsPipes[pnum];
- fprintf(stderr, " Pipe: %d\n", pnum);
- fprintf(stderr, " MaximumPacketSize: 0x%x\n", MsPipe->MaximumPacketSize);
- fprintf(stderr, " MaximumTransferSize: 0x%x\n", MsPipe->MaximumTransferSize);
- fprintf(stderr, " PipeFlags: 0x%x\n", MsPipe->PipeFlags);
- fprintf(stderr, " PipeHandle: 0x%x\n", MsPipe->PipeHandle);
- fprintf(stderr, " bEndpointAddress: 0x%x\n", MsPipe->bEndpointAddress);
- fprintf(stderr, " bInterval: %d\n", MsPipe->bInterval);
- fprintf(stderr, " PipeType: 0x%x\n", MsPipe->PipeType);
- fprintf(stderr, " InitCompleted: %d\n\n", MsPipe->InitCompleted);
+ DEBUG_WARN( " Pipe: %d\n", pnum);
+ DEBUG_WARN( " MaximumPacketSize: 0x%x\n", MsPipe->MaximumPacketSize);
+ DEBUG_WARN( " MaximumTransferSize: 0x%x\n", MsPipe->MaximumTransferSize);
+ DEBUG_WARN( " PipeFlags: 0x%x\n", MsPipe->PipeFlags);
+ DEBUG_WARN( " PipeHandle: 0x%x\n", MsPipe->PipeHandle);
+ DEBUG_WARN( " bEndpointAddress: 0x%x\n", MsPipe->bEndpointAddress);
+ DEBUG_WARN( " bInterval: %d\n", MsPipe->bInterval);
+ DEBUG_WARN( " PipeType: 0x%x\n", MsPipe->PipeType);
+ DEBUG_WARN( " InitCompleted: %d\n\n", MsPipe->InitCompleted);
}
}
- fprintf(stderr, "==================================================\n");
+ DEBUG_WARN( "==================================================\n");
}
#include <string.h>
#include <winpr/crt.h>
+#include <freerdp/utils/debug.h>
#ifndef _WIN32
#include <sys/time.h>
if (pcap_fp == NULL)
{
- perror("opening pcap dump");
+ DEBUG_WARN("opening pcap dump");
return NULL;
}
#include <stdlib.h>
#include <freerdp/utils/profiler.h>
+#include <freerdp/utils/debug.h>
PROFILER* profiler_create(char* name)
{
void profiler_print_header()
{
- fprintf(stderr, "\n");
- fprintf(stderr, " |-----------------------|\n" );
- fprintf(stderr, " PROFILER | elapsed seconds |\n" );
- fprintf(stderr, "|--------------------------------------------|-----------------------|\n" );
- fprintf(stderr, "| code section | iterations | total | avg. |\n" );
- fprintf(stderr, "|-------------------------------|------------|-----------|-----------|\n" );
+ DEBUG_WARN( "\n");
+ DEBUG_WARN( " |-----------------------|\n" );
+ DEBUG_WARN( " PROFILER | elapsed seconds |\n" );
+ DEBUG_WARN( "|--------------------------------------------|-----------------------|\n" );
+ DEBUG_WARN( "| code section | iterations | total | avg. |\n" );
+ DEBUG_WARN( "|-------------------------------|------------|-----------|-----------|\n" );
}
void profiler_print(PROFILER* profiler)
double elapsed_sec = stopwatch_get_elapsed_time_in_seconds(profiler->stopwatch);
double avg_sec = elapsed_sec / (double) profiler->stopwatch->count;
- fprintf(stderr, "| %-30.30s| %10du | %9f | %9f |\n",
+ DEBUG_WARN( "| %-30.30s| %10du | %9f | %9f |\n",
profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec);
}
void profiler_print_footer()
{
- fprintf(stderr, "|--------------------------------------------------------------------|\n" );
+ DEBUG_WARN( "|--------------------------------------------------------------------|\n" );
}
new_order = malloc(order_size);
CopyMemory(new_order, order, order_size);
- //fprintf(stderr, "rail_clone_order: type=%d order=%p\n", event_type, new_order);
+ //DEBUG_WARN( "rail_clone_order: type=%d order=%p\n", event_type, new_order);
// Create copy of variable data for some orders
if ((event_type == RailChannel_GetSystemParam) ||
void rail_free_cloned_order(UINT32 event_type, void* order)
{
- //fprintf(stderr, "rail_free_cloned_order: type=%d order=%p\n", event_type, order);
+ //DEBUG_WARN( "rail_free_cloned_order: type=%d order=%p\n", event_type, order);
if ((event_type == RailChannel_GetSystemParam) ||
(event_type == RailChannel_ClientSystemParam))
{
#include <winpr/crt.h>
#include <freerdp/utils/signal.h>
+#include <freerdp/utils/debug.h>
#ifdef _WIN32
struct sigaction default_sigaction;
sigset_t this_mask;
- printf("fatal_handler: signum=%d\n", signum);
+ DEBUG_MSG("fatal_handler: signum=%d\n", signum);
if (terminal_needs_reset)
tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags);
Stream_Release(plugin->data_in);
plugin->data_in = StreamPool_Take(plugin->pool, totalLength);
- Stream_AddRef(plugin->data_in);
}
s = plugin->data_in;
if (dataFlags & CHANNEL_FLAG_LAST)
{
- if (Stream_Capacity(s) != Stream_GetPosition(s))
- {
- fprintf(stderr, "svc_plugin_process_received: read error\n");
- }
-
plugin->data_in = NULL;
Stream_SealLength(s);
Stream_SetPosition(s, 0);
if (!plugin)
{
- fprintf(stderr, "svc_plugin_open_event: error no match\n");
+ DEBUG_WARN( "svc_plugin_open_event: error no match\n");
return;
}
if (status != CHANNEL_RC_OK)
{
- fprintf(stderr, "svc_plugin_process_connected: open failed: status: %d\n", status);
+ DEBUG_WARN( "svc_plugin_process_connected: open failed: status: %d\n", status);
return;
}
if (plugin->data_in)
{
- Stream_Free(plugin->data_in, TRUE);
+ Stream_Release(plugin->data_in);
plugin->data_in = NULL;
}
if (!plugin)
{
- fprintf(stderr, "svc_plugin_init_event: error no match\n");
+ DEBUG_WARN( "svc_plugin_init_event: error no match\n");
return;
}
if (status != CHANNEL_RC_OK)
{
Stream_Free(data_out, TRUE);
- fprintf(stderr, "svc_plugin_send: VirtualChannelWrite failed %d\n", status);
+ DEBUG_WARN( "svc_plugin_send: VirtualChannelWrite failed %d\n", status);
}
return status;
status = plugin->channel_entry_points.pVirtualChannelEventPush(plugin->OpenHandle, event);
if (status != CHANNEL_RC_OK)
- fprintf(stderr, "svc_plugin_send_event: VirtualChannelEventPush failed %d\n", status);
+ DEBUG_WARN( "svc_plugin_send_event: VirtualChannelEventPush failed %d\n", status);
return status;
}
#include <winpr/crt.h>
#include <winpr/winsock.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/utils/tcp.h>
#include <stdio.h>
if (status != 0)
{
- //fprintf(stderr, "tcp_connect: getaddrinfo (%s)\n", gai_strerror(status));
+ //DEBUG_WARN( "tcp_connect: getaddrinfo (%s)\n", gai_strerror(status));
return -1;
}
if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == 0)
{
- fprintf(stderr, "connected to %s:%s\n", hostname, servname);
+ DEBUG_WARN( "connected to %s:%s\n", hostname, servname);
break;
}
if (sockfd == -1)
{
- fprintf(stderr, "unable to connect to %s:%s\n", hostname, servname);
+ DEBUG_WARN( "unable to connect to %s:%s\n", hostname, servname);
return -1;
}
if (wsa_error == WSAEWOULDBLOCK)
return 0;
- fprintf(stderr, "recv() error: %d\n", wsa_error);
+ DEBUG_WARN( "recv() error: %d\n", wsa_error);
#else
/* No data available */
if (errno == EAGAIN || errno == EWOULDBLOCK)
return 0;
- perror("recv");
+ DEBUG_WARN("recv");
#endif
return -1;
}
if (wsa_error == WSAEWOULDBLOCK)
status = 0;
else
- perror("send");
+ DEBUG_WARN("send");
#else
if (errno == EAGAIN || errno == EWOULDBLOCK)
status = 0;
else
- perror("send");
+ DEBUG_WARN("send");
#endif
}
if (sockfd < 1)
{
- fprintf(stderr, "Invalid socket to watch: %d\n", sockfd);
+ DEBUG_WARN( "Invalid socket to watch: %d\n", sockfd);
return 0 ;
}
if (sockfd < 1)
{
- fprintf(stderr, "Invalid socket to watch: %d\n", sockfd);
+ DEBUG_WARN( "Invalid socket to watch: %d\n", sockfd);
return 0 ;
}
if (ringbuffer_used(&ringBuffer) != 15)
{
- fprintf(stderr, "invalid used size got %d when i would expect 15\n", ringbuffer_used(&ringBuffer));
+ fprintf(stderr, "invalid used size got %ld when i would expect 15\n", ringbuffer_used(&ringBuffer));
return -1;
}
if (ringbuffer_used(&ringBuffer) != 5)
{
- fprintf(stderr, "invalid used size after read got %d when i would expect 5\n", ringbuffer_used(&ringBuffer));
+ fprintf(stderr, "invalid used size after read got %ld when i would expect 5\n", ringbuffer_used(&ringBuffer));
return -1;
}
if (ringbuffer_capacity(&ringBuffer) != 10)
{
- fprintf(stderr, "not the expected capacity, have %d and expects 10\n", ringbuffer_capacity(&ringBuffer));
+ fprintf(stderr, "not the expected capacity, have %ld and expects 10\n", ringbuffer_capacity(&ringBuffer));
return -1;
}
fprintf(stderr, "ok\n");
fprintf(stderr, "%d: specific overlaps test...", ++testNo);
if (!test_overlaps())
{
- fprintf(stderr, "ko\n", i);
+ fprintf(stderr, "ko\n");
return -1;
}
fprintf(stderr, "ok\n");
#endif
#include <freerdp/utils/uds.h>
+#include <freerdp/utils/debug.h>
#include <stdio.h>
#include <stdlib.h>
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1)
{
- perror("socket");
+ DEBUG_WARN("socket");
return -1;
}
status = connect(sockfd, (struct sockaddr *) &addr, sizeof(addr));
if (status < 0)
{
- perror("connect");
+ DEBUG_WARN("connect");
close(sockfd);
return -1;
}
--- /dev/null
+#!/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
-#!/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 $?
!/Sample
!/Windows
!/X11
+!/shadow
!/CmakeLists.txt
# Servers
add_subdirectory(common)
+add_subdirectory(shadow)
if(FREERDP_VENDOR)
if(WITH_SAMPLE)
endif()
if(NOT WIN32)
- if(WITH_X11)
- add_subdirectory(X11)
- endif()
-
if(APPLE AND (NOT IOS))
add_subdirectory(Mac)
endif()
else()
- add_subdirectory(Windows)
+ #add_subdirectory(Windows)
endif()
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/FreeRDS")
foreach(FREERDP_SERVER ${FREERDP_EXTRA_SERVERS})
add_subdirectory(${FREERDP_SERVER})
endforeach()
+
static void mf_peer_audin_opening(audin_server_context* context)
{
- fprintf(stderr, "AUDIN opening.\n");
+ DEBUG_WARN( "AUDIN opening.\n");
/* Simply choose the first format supported by the client. */
context->SelectFormat(context, 0);
}
static void mf_peer_audin_open_result(audin_server_context* context, UINT32 result)
{
- fprintf(stderr, "AUDIN open result %d.\n", result);
+ DEBUG_WARN( "AUDIN open result %d.\n", result);
}
static void mf_peer_audin_receive_samples(audin_server_context* context, const void* buf, int nframes)
{
- fprintf(stderr, "AUDIN receive %d frames.\n", nframes);
+ DEBUG_WARN( "AUDIN receive %d frames.\n", nframes);
}
void mf_peer_audin_init(mfPeerContext* context)
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Mac OS X Server (Audio Input)\r
- *\r
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>\r
- * Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef MF_AUDIN_H\r
-#define MF_AUDIN_H\r
-\r
-#include <freerdp/freerdp.h>\r
-#include <freerdp/listener.h>\r
-\r
-#include "mf_interface.h"\r
-#include "mfreerdp.h"\r
-\r
-\r
-void mf_peer_audin_init(mfPeerContext* context);\r
-\r
-#endif /* MF_AUDIN_H */\r
-\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Mac OS X Server (Audio Input)
+ *
+ * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2013 Corey Clayton <can.of.tuna@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 MF_AUDIN_H
+#define MF_AUDIN_H
+
+#include <freerdp/freerdp.h>
+#include <freerdp/listener.h>
+
+#include "mf_interface.h"
+#include "mfreerdp.h"
+
+
+void mf_peer_audin_init(mfPeerContext* context);
+
+#endif /* MF_AUDIN_H */
+
length = write(event_queue->pipe_fd[1], "sig", 4);
if (length != 4)
- fprintf(stderr, "mf_signal_event: error\n");
+ DEBUG_WARN( "mf_signal_event: error\n");
}
void mf_set_event(mfEventQueue* event_queue)
length = write(event_queue->pipe_fd[1], "sig", 4);
if (length != 4)
- fprintf(stderr, "mf_set_event: error\n");
+ DEBUG_WARN( "mf_set_event: error\n");
}
void mf_clear_events(mfEventQueue* event_queue)
length = read(event_queue->pipe_fd[0], &length, 4);
if (length != 4)
- fprintf(stderr, "mf_clear_event: error\n");
+ DEBUG_WARN( "mf_clear_event: error\n");
}
}
length = read(event_queue->pipe_fd[0], &length, 4);
if (length != 4)
- fprintf(stderr, "mf_clear_event: error\n");
+ DEBUG_WARN( "mf_clear_event: error\n");
}
void mf_event_push(mfEventQueue* event_queue, mfEvent* event)
event_queue->events = (mfEvent**) malloc(sizeof(mfEvent*) * event_queue->size);
if (pipe(event_queue->pipe_fd) < 0)
- fprintf(stderr, "mf_event_queue_new: pipe failed\n");
+ DEBUG_WARN( "mf_event_queue_new: pipe failed\n");
pthread_mutex_init(&(event_queue->mutex), NULL);
}
*/
#ifndef __MF_EVENT_H
-#define __XMF_EVENT_H
+#define __MF_EVENT_H
typedef struct mf_event mfEvent;
typedef struct mf_event_queue mfEventQueue;
break;\r
\r
default:\r
- printf("mf_info_lock failed with %#X\n", status);\r
+ DEBUG_MSG("mf_info_lock failed with %#X\n", status);\r
return -1;\r
break;\r
}\r
break;\r
\r
default:\r
- printf("mf_info_try_lock failed with %#X\n", status);\r
+ DEBUG_MSG("mf_info_try_lock failed with %#X\n", status);\r
return -1;\r
break;\r
}\r
break;\r
\r
default:\r
- printf("mf_info_unlock failed with %#X\n", status);\r
+ DEBUG_MSG("mf_info_unlock failed with %#X\n", status);\r
return -1;\r
break;\r
}\r
\r
if (mutexInitStatus != 0)\r
{\r
- printf(_T("CreateMutex error: %#X\n"), mutexInitStatus);\r
+ DEBUG_MSG(_T("CreateMutex error: %#X\n"), mutexInitStatus);\r
}\r
\r
mfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * MF_INFO_MAXPEERS);\r
int peerId;\r
if (mfi->peerCount == MF_INFO_MAXPEERS)\r
{\r
- printf("TODO: socketClose on OS X\n");\r
+ DEBUG_MSG("TODO: socketClose on OS X\n");\r
//context->socketClose = TRUE;\r
mf_info_unlock(mfi);\r
return;\r
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Mac OS X Server\r
- *\r
- * Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef MF_INFO_H\r
-#define MF_INFO_H\r
-\r
-#define MF_INFO_DEFAULT_FPS 1\r
-#define MF_INFO_MAXPEERS 1\r
-\r
-\r
-\r
-#include <winpr/wtypes.h>\r
-#include <freerdp/codec/rfx.h>\r
-\r
-#include "mf_interface.h"\r
-\r
-int mf_info_lock(mfInfo* mfi);\r
-int mf_info_try_lock(mfInfo* mfi, UINT32 ms);\r
-int mf_info_unlock(mfInfo* mfi);\r
-\r
-mfInfo* mf_info_get_instance(void);\r
-void mf_info_peer_register(mfInfo* mfi, mfPeerContext* context);\r
-void mf_info_peer_unregister(mfInfo* mfi, mfPeerContext* context);\r
-\r
-BOOL mf_info_have_updates(mfInfo* mfi);\r
-void mf_info_update_changes(mfInfo* mfi);\r
-void mf_info_find_invalid_region(mfInfo* mfi);\r
-void mf_info_clear_invalid_region(mfInfo* mfi);\r
-void mf_info_invalidate_full_screen(mfInfo* mfi);\r
-BOOL mf_info_have_invalid_region(mfInfo* mfi);\r
-void mf_info_getScreenData(mfInfo* mfi, long* width, long* height, BYTE** pBits, int* pitch);\r
-//BOOL CALLBACK mf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData);\r
-\r
-#endif /* mf_info_H */\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Mac OS X Server
+ *
+ * Copyright 2012 Corey Clayton <can.of.tuna@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 MF_INFO_H
+#define MF_INFO_H
+
+#define MF_INFO_DEFAULT_FPS 1
+#define MF_INFO_MAXPEERS 1
+
+
+
+#include <winpr/wtypes.h>
+#include <freerdp/codec/rfx.h>
+
+#include "mf_interface.h"
+
+int mf_info_lock(mfInfo* mfi);
+int mf_info_try_lock(mfInfo* mfi, UINT32 ms);
+int mf_info_unlock(mfInfo* mfi);
+
+mfInfo* mf_info_get_instance(void);
+void mf_info_peer_register(mfInfo* mfi, mfPeerContext* context);
+void mf_info_peer_unregister(mfInfo* mfi, mfPeerContext* context);
+
+BOOL mf_info_have_updates(mfInfo* mfi);
+void mf_info_update_changes(mfInfo* mfi);
+void mf_info_find_invalid_region(mfInfo* mfi);
+void mf_info_clear_invalid_region(mfInfo* mfi);
+void mf_info_invalidate_full_screen(mfInfo* mfi);
+BOOL mf_info_have_invalid_region(mfInfo* mfi);
+void mf_info_getScreenData(mfInfo* mfi, long* width, long* height, BYTE** pBits, int* pitch);
+//BOOL CALLBACK mf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData);
+
+#endif /* mf_info_H */
/*
if (flags & KBD_FLAGS_EXTENDED)
- fprintf(stderr, "extended ");
- fprintf(stderr, "keypress: down = %d, SCAN=%#0X, VK=%#0X\n", keyDown, code, keymap[code]);
+ DEBUG_WARN( "extended ");
+ DEBUG_WARN( "keypress: down = %d, SCAN=%#0X, VK=%#0X\n", keyDown, code, keymap[code]);
*/
}
void mf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
- fprintf(stderr, "Unhandled mouse event!!!\n");
+ DEBUG_WARN( "Unhandled mouse event!!!\n");
/*
if ((flags & PTR_XFLAGS_BUTTON1) || (flags & PTR_XFLAGS_BUTTON2))
{
switch(status)
{
case kCGDisplayStreamFrameStatusFrameIdle:
- printf("kCGDisplayStreamFrameStatusFrameIdle\n");
+ DEBUG_MSG("kCGDisplayStreamFrameStatusFrameIdle\n");
break;
case kCGDisplayStreamFrameStatusStopped:
break;
case kCGDisplayStreamFrameStatusFrameBlank:
- printf("kCGDisplayStreamFrameStatusFrameBlank\n");
+ DEBUG_MSG("kCGDisplayStreamFrameStatusFrameBlank\n");
break;
default:
- printf("Unhandled Frame Status!!!\n");
+ DEBUG_MSG("Unhandled Frame Status!!!\n");
}
}
err = CGDisplayStreamStart(stream);
if(err != kCGErrorSuccess)
{
- printf("Failed to start displaystream!! err = %d\n", err);
+ DEBUG_MSG("Failed to start displaystream!! err = %d\n", err);
return 1;
}
err = CGDisplayStreamStop(stream);
if(err != kCGErrorSuccess)
{
- printf("Failed to stop displaystream!! err = %d\n", err);
+ DEBUG_MSG("Failed to stop displaystream!! err = %d\n", err);
return 1;
}
{\r
if (event->type == MF_EVENT_TYPE_REGION)\r
{\r
- fprintf(stderr, "unhandled event\n");\r
+ DEBUG_WARN( "unhandled event\n");\r
}\r
else if (event->type == MF_EVENT_TYPE_FRAME_TICK)\r
{\r
\r
if(info_timer)\r
{\r
- //fprintf(stderr, "created timer\n");\r
+ //DEBUG_WARN( "created timer\n");\r
dispatch_source_set_timer(info_timer, DISPATCH_TIME_NOW, 42ull * NSEC_PER_MSEC, 100ull * NSEC_PER_MSEC);\r
dispatch_source_set_event_handler(info_timer, ^{\r
- //fprintf(stderr, "dispatch\n");\r
+ //DEBUG_WARN( "dispatch\n");\r
mfEvent* event = mf_event_new(MF_EVENT_TYPE_FRAME_TICK);\r
mf_event_push(info_event_queue, (mfEvent*) event);}\r
);\r
mfPeerContext* context = (mfPeerContext*) client->context;\r
rdpSettings* settings = client->settings;\r
\r
- fprintf(stderr, "Client %s post connect\n", client->hostname);\r
+ DEBUG_WARN( "Client %s post connect\n", client->hostname);\r
\r
if (client->settings->AutoLogonEnabled)\r
{\r
- fprintf(stderr, " and wants to login automatically as %s\\%s",\r
+ DEBUG_WARN( " and wants to login automatically as %s\\%s",\r
client->settings->Domain ? client->settings->Domain : "",\r
client->settings->Username);\r
\r
/* A real server may perform OS login here if NLA is not executed previously. */\r
}\r
- fprintf(stderr, "\n");\r
+ DEBUG_WARN( "\n");\r
\r
mfInfo* mfi = mf_info_get_instance();\r
mfi->scale = 1;\r
\r
if ((settings->DesktopWidth != mfi->servscreen_width) || (settings->DesktopHeight != mfi->servscreen_height))\r
{\r
- fprintf(stderr, "Client requested resolution %dx%d, but will resize to %dx%d\n",\r
+ DEBUG_WARN( "Client requested resolution %dx%d, but will resize to %dx%d\n",\r
settings->DesktopWidth, settings->DesktopHeight, mfi->servscreen_width, mfi->servscreen_height);\r
}\r
\r
\r
void mf_peer_synchronize_event(rdpInput* input, UINT32 flags)\r
{\r
- fprintf(stderr, "Client sent a synchronize event (flags:0x%08X)\n", flags);\r
+ DEBUG_WARN( "Client sent a synchronize event (flags:0x%08X)\n", flags);\r
}\r
\r
void mf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)\r
{\r
- fprintf(stderr, "Client sent a keyboard event (flags:0x%04X code:0x%04X)\n", flags, code);\r
+ DEBUG_WARN( "Client sent a keyboard event (flags:0x%04X code:0x%04X)\n", flags, code);\r
\r
UINT16 down = 0x4000;\r
//UINT16 up = 0x8000;\r
\r
void mf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)\r
{\r
- fprintf(stderr, "Client sent a unicode keyboard event (flags:0x%04X code:0x%04X)\n", flags, code);\r
+ DEBUG_WARN( "Client sent a unicode keyboard event (flags:0x%04X code:0x%04X)\n", flags, code);\r
}\r
\r
/*void mf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)\r
{\r
- //fprintf(stderr, "Client sent a mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y);\r
+ //DEBUG_WARN( "Client sent a mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y);\r
}\r
\r
void mf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)\r
{\r
- //fprintf(stderr, "Client sent an extended mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y);\r
+ //DEBUG_WARN( "Client sent an extended mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y);\r
}\r
*/\r
/*static void mf_peer_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_16* areas)\r
{\r
BYTE i;\r
\r
- fprintf(stderr, "Client requested to refresh:\n");\r
+ DEBUG_WARN( "Client requested to refresh:\n");\r
\r
for (i = 0; i < count; i++)\r
{\r
- fprintf(stderr, " (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom);\r
+ DEBUG_WARN( " (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom);\r
}\r
}*/\r
\r
{\r
if (allow > 0)\r
{\r
- fprintf(stderr, "Client restore output (%d, %d) (%d, %d).\n", area->left, area->top, area->right, area->bottom);\r
+ DEBUG_WARN( "Client restore output (%d, %d) (%d, %d).\n", area->left, area->top, area->right, area->bottom);\r
}\r
else\r
{\r
- fprintf(stderr, "Client minimized and suppress output.\n");\r
+ DEBUG_WARN( "Client minimized and suppress output.\n");\r
}\r
}\r
\r
client->Initialize(client);\r
context = (mfPeerContext*) client->context;\r
\r
- fprintf(stderr, "We've got a client %s\n", client->local ? "(local)" : client->hostname);\r
+ DEBUG_WARN( "We've got a client %s\n", client->local ? "(local)" : client->hostname);\r
\r
while (1)\r
{\r
\r
if (client->GetFileDescriptor(client, rfds, &rcount) != TRUE)\r
{\r
- fprintf(stderr, "Failed to get FreeRDP file descriptor\n");\r
+ DEBUG_WARN( "Failed to get FreeRDP file descriptor\n");\r
break;\r
}\r
if (mf_peer_get_fds(client, rfds, &rcount) != TRUE)\r
{\r
- fprintf(stderr, "Failed to get mfreerdp file descriptor\n");\r
+ DEBUG_WARN( "Failed to get mfreerdp file descriptor\n");\r
break;\r
}\r
\r
(errno == EINPROGRESS) ||\r
(errno == EINTR))) /* signal occurred */\r
{\r
- fprintf(stderr, "select failed\n");\r
+ DEBUG_WARN( "select failed\n");\r
break;\r
}\r
}\r
\r
if (client->CheckFileDescriptor(client) != TRUE)\r
{\r
- fprintf(stderr, "Failed to check freerdp file descriptor\n");\r
+ DEBUG_WARN( "Failed to check freerdp file descriptor\n");\r
break;\r
}\r
\r
if ((mf_peer_check_fds(client)) != TRUE)\r
{\r
- fprintf(stderr, "Failed to check mfreerdp file descriptor\n");\r
+ DEBUG_WARN( "Failed to check mfreerdp file descriptor\n");\r
break;\r
}\r
\r
}\r
}\r
\r
- fprintf(stderr, "Client %s disconnected.\n", client->local ? "(local)" : client->hostname);\r
+ DEBUG_WARN( "Client %s disconnected.\n", client->local ? "(local)" : client->hostname);\r
\r
client->Disconnect(client);\r
freerdp_peer_context_free(client);\r
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Mac OS X Server\r
- *\r
- * Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef WF_PEER_H\r
-#define WF_PEER_H\r
-\r
-#include "mf_interface.h"\r
-\r
-BOOL mf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount);\r
-BOOL mf_peer_check_fds(freerdp_peer* client);\r
-\r
-void mf_peer_rfx_update(freerdp_peer* client);\r
-\r
-int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context);\r
-void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context);\r
-\r
-void mf_peer_init(freerdp_peer* client);\r
-\r
-BOOL mf_peer_post_connect(freerdp_peer* client);\r
-BOOL mf_peer_activate(freerdp_peer* client);\r
-\r
-void mf_peer_synchronize_event(rdpInput* input, UINT32 flags);\r
-\r
-void mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);\r
-\r
-void* mf_peer_main_loop(void* arg);\r
-\r
-#endif /* MF_PEER_H */\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Mac OS X Server
+ *
+ * Copyright 2012 Corey Clayton <can.of.tuna@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_PEER_H
+#define WF_PEER_H
+
+#include "mf_interface.h"
+
+BOOL mf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount);
+BOOL mf_peer_check_fds(freerdp_peer* client);
+
+void mf_peer_rfx_update(freerdp_peer* client);
+
+int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context);
+void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context);
+
+void mf_peer_init(freerdp_peer* client);
+
+BOOL mf_peer_post_connect(freerdp_peer* client);
+BOOL mf_peer_activate(freerdp_peer* client);
+
+void mf_peer_synchronize_event(rdpInput* input, UINT32 flags);
+
+void mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);
+
+void* mf_peer_main_loop(void* arg);
+
+#endif /* MF_PEER_H */
#include "config.h"
#endif
+#include <winpr/crt.h>
+#include <winpr/sysinfo.h>
+
#include <freerdp/server/rdpsnd.h>
#include "mf_info.h"
static const AUDIO_FORMAT supported_audio_formats[] =
{
- { WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, NULL },
- { WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, NULL }
+ { WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
+ { WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
};
static void mf_peer_rdpsnd_activated(RdpsndServerContext* context)
//we should actually loop through the list of client formats here
//and see if we can send the client something that it supports...
- printf("Client supports the following %d formats: \n", context->num_client_formats);
+ DEBUG_MSG("Client supports the following %d formats: \n", context->num_client_formats);
for (i = 0; i < context->num_client_formats; i++)
{
(context->client_formats[i].nChannels == context->server_formats[j].nChannels) &&
(context->client_formats[i].nSamplesPerSec == context->server_formats[j].nSamplesPerSec))
{
- printf("agreed on format!\n");
+ DEBUG_MSG("agreed on format!\n");
formatAgreed = TRUE;
agreedFormat = (AUDIO_FORMAT*)&context->server_formats[j];
break;
if (formatAgreed == FALSE)
{
- printf("Could not agree on a audio format with the server\n");
+ DEBUG_MSG("Could not agree on a audio format with the server\n");
return;
}
if (status != noErr)
{
- printf("Failed to create a new Audio Queue. Status code: %d\n", status);
+ DEBUG_MSG("Failed to create a new Audio Queue. Status code: %d\n", status);
}
context->rdpsnd->Activated = mf_peer_rdpsnd_activated;
- context->rdpsnd->Initialize(context->rdpsnd);
+ context->rdpsnd->Initialize(context->rdpsnd, TRUE);
return TRUE;
}
if (status != noErr)
{
- printf("AudioQueueEnqueueBuffer() returned status = %d\n", status);
+ DEBUG_MSG("AudioQueueEnqueueBuffer() returned status = %d\n", status);
}
}
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Mac OS X Server (Audio Output)\r
- *\r
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef MF_RDPSND_H\r
-#define MF_RDPSND_H\r
-\r
-#include <CoreAudio/CoreAudio.h>\r
-#include <AudioToolbox/AudioToolbox.h>\r
-\r
-#include <freerdp/freerdp.h>\r
-#include <freerdp/listener.h>\r
-#include <freerdp/server/rdpsnd.h>\r
-\r
-#include "mf_interface.h"\r
-#include "mfreerdp.h"\r
-\r
-void mf_rdpsnd_derive_buffer_size (AudioQueueRef audioQueue,\r
- AudioStreamBasicDescription *ASBDescription,\r
- Float64 seconds,\r
- UInt32 *outBufferSize);\r
-\r
-void mf_peer_rdpsnd_input_callback (void *inUserData,\r
- AudioQueueRef inAQ,\r
- AudioQueueBufferRef inBuffer,\r
- const AudioTimeStamp *inStartTime,\r
- UInt32 inNumberPacketDescriptions,\r
- const AudioStreamPacketDescription *inPacketDescs);\r
-\r
-\r
-#define SND_NUMBUFFERS 3\r
-struct _AQRecorderState\r
-{\r
- AudioStreamBasicDescription dataFormat;\r
- AudioQueueRef queue;\r
- AudioQueueBufferRef buffers[SND_NUMBUFFERS];\r
- AudioFileID audioFile;\r
- UInt32 bufferByteSize;\r
- SInt64 currentPacket;\r
- bool isRunning;\r
- RdpsndServerContext* snd_context;\r
- \r
-};\r
-\r
-typedef struct _AQRecorderState AQRecorderState;\r
-\r
-BOOL mf_peer_rdpsnd_init(mfPeerContext* context);\r
-BOOL mf_peer_rdpsnd_stop(void);\r
-\r
-#endif /* MF_RDPSND_H */\r
-\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Mac OS X Server (Audio Output)
+ *
+ * Copyright 2012 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 MF_RDPSND_H
+#define MF_RDPSND_H
+
+#include <CoreAudio/CoreAudio.h>
+#include <AudioToolbox/AudioToolbox.h>
+
+#include <freerdp/freerdp.h>
+#include <freerdp/listener.h>
+#include <freerdp/server/rdpsnd.h>
+
+#include "mf_interface.h"
+#include "mfreerdp.h"
+
+void mf_rdpsnd_derive_buffer_size (AudioQueueRef audioQueue,
+ AudioStreamBasicDescription *ASBDescription,
+ Float64 seconds,
+ UInt32 *outBufferSize);
+
+void mf_peer_rdpsnd_input_callback (void *inUserData,
+ AudioQueueRef inAQ,
+ AudioQueueBufferRef inBuffer,
+ const AudioTimeStamp *inStartTime,
+ UInt32 inNumberPacketDescriptions,
+ const AudioStreamPacketDescription *inPacketDescs);
+
+
+#define SND_NUMBUFFERS 3
+struct _AQRecorderState
+{
+ AudioStreamBasicDescription dataFormat;
+ AudioQueueRef queue;
+ AudioQueueBufferRef buffers[SND_NUMBUFFERS];
+ AudioFileID audioFile;
+ UInt32 bufferByteSize;
+ SInt64 currentPacket;
+ bool isRunning;
+ RdpsndServerContext* snd_context;
+
+};
+
+typedef struct _AQRecorderState AQRecorderState;
+
+BOOL mf_peer_rdpsnd_init(mfPeerContext* context);
+BOOL mf_peer_rdpsnd_stop(void);
+
+#endif /* MF_RDPSND_H */
+
if (instance->GetFileDescriptor(instance, rfds, &rcount) != TRUE)
{
- fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
+ DEBUG_WARN( "Failed to get FreeRDP file descriptor\n");
break;
}
(errno == EINPROGRESS) ||
(errno == EINTR))) /* signal occurred */
{
- fprintf(stderr, "select failed\n");
+ DEBUG_WARN( "select failed\n");
break;
}
}
if (instance->CheckFileDescriptor(instance) != TRUE)
{
- fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
+ DEBUG_WARN( "Failed to check FreeRDP file descriptor\n");
break;
}
}
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Mac OS X Server\r
- *\r
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>\r
- * Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef MFREERDP_SERVER_H\r
-#define MFREERDP_SERVER_H\r
-\r
-#include <freerdp/freerdp.h>\r
-#include <freerdp/listener.h>\r
-#include <freerdp/codec/rfx.h>\r
-\r
-#endif /* MFREERDP_SERVER_H */\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Mac OS X Server
+ *
+ * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2012 Corey Clayton <can.of.tuna@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 MFREERDP_SERVER_H
+#define MFREERDP_SERVER_H
+
+#include <freerdp/freerdp.h>
+#include <freerdp/listener.h>
+#include <freerdp/codec/rfx.h>
+
+#endif /* MFREERDP_SERVER_H */
#include "config.h"
#endif
+#include <freerdp/utils/debug.h>
+
#include "sfreerdp.h"
#include "sf_audin.h"
static void sf_peer_audin_opening(audin_server_context* context)
{
- printf("AUDIN opening.\n");
+ DEBUG_MSG("AUDIN opening.\n");
/* Simply choose the first format supported by the client. */
context->SelectFormat(context, 0);
}
static void sf_peer_audin_open_result(audin_server_context* context, UINT32 result)
{
- printf("AUDIN open result %d.\n", result);
+ DEBUG_MSG("AUDIN open result %d.\n", result);
}
static void sf_peer_audin_receive_samples(audin_server_context* context, const void* buf, int nframes)
{
- printf("AUDIN receive %d frames.\n", nframes);
+ DEBUG_MSG("AUDIN receive %d frames.\n", nframes);
}
void sf_peer_audin_init(testPeerContext* context)
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Sample Server (Audio Input)\r
- *\r
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef SF_AUDIN_H\r
-#define SF_AUDIN_H\r
-\r
-#include <freerdp/freerdp.h>\r
-#include <freerdp/listener.h>\r
-#include <freerdp/server/audin.h>\r
-\r
-#include "sfreerdp.h"\r
-\r
-void sf_peer_audin_init(testPeerContext* context);\r
-\r
-#endif /* WF_AUDIN_H */\r
-\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Sample Server (Audio Input)
+ *
+ * Copyright 2012 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 SF_AUDIN_H
+#define SF_AUDIN_H
+
+#include <freerdp/freerdp.h>
+#include <freerdp/listener.h>
+#include <freerdp/server/audin.h>
+
+#include "sfreerdp.h"
+
+void sf_peer_audin_init(testPeerContext* context);
+
+#endif /* WF_AUDIN_H */
+
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Sample Server (Lync Multiparty)\r
- *\r
- * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef SF_ENCOMSP_H\r
-#define SF_ENCOMSP_H\r
-\r
-#include <freerdp/freerdp.h>\r
-#include <freerdp/listener.h>\r
-#include <freerdp/server/encomsp.h>\r
-\r
-#include "sfreerdp.h"\r
-\r
-BOOL sf_peer_encomsp_init(testPeerContext* context);\r
-\r
-#endif /* SF_ENCOMSP_H */\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Sample Server (Lync Multiparty)
+ *
+ * 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 SF_ENCOMSP_H
+#define SF_ENCOMSP_H
+
+#include <freerdp/freerdp.h>
+#include <freerdp/listener.h>
+#include <freerdp/server/encomsp.h>
+
+#include "sfreerdp.h"
+
+BOOL sf_peer_encomsp_init(testPeerContext* context);
+
+#endif /* SF_ENCOMSP_H */
#endif
#include <freerdp/server/audin.h>
+#include <freerdp/utils/debug.h>
#include "sf_rdpsnd.h"
static void sf_peer_rdpsnd_activated(RdpsndServerContext* context)
{
- printf("RDPSND Activated\n");
+ DEBUG_MSG("RDPSND Activated\n");
}
BOOL sf_peer_rdpsnd_init(testPeerContext* context)
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Sample Server (Audio Output)\r
- *\r
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef SF_RDPSND_H\r
-#define SF_RDPSND_H\r
-\r
-#include <freerdp/freerdp.h>\r
-#include <freerdp/listener.h>\r
-#include <freerdp/server/rdpsnd.h>\r
-\r
-#include "sfreerdp.h"\r
-\r
-BOOL sf_peer_rdpsnd_init(testPeerContext* context);\r
-\r
-#endif /* SF_RDPSND_H */\r
-\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Sample Server (Audio Output)
+ *
+ * Copyright 2012 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 SF_RDPSND_H
+#define SF_RDPSND_H
+
+#include <freerdp/freerdp.h>
+#include <freerdp/listener.h>
+#include <freerdp/server/rdpsnd.h>
+
+#include "sfreerdp.h"
+
+BOOL sf_peer_rdpsnd_init(testPeerContext* context);
+
+#endif /* SF_RDPSND_H */
+
#include <freerdp/channels/wtsvc.h>
#include <freerdp/channels/channels.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/constants.h>
#include <freerdp/utils/tcp.h>
if ((sec < 0) || ((sec == 0) && (usec < 0)))
{
- printf("Invalid time stamp detected.\n");
+ DEBUG_MSG("Invalid time stamp detected.\n");
return FALSE;
}
Stream_SetPosition(s, BytesReturned);
- printf("got %lu bytes\n", BytesReturned);
+ DEBUG_MSG("got %lu bytes\n", BytesReturned);
}
Stream_Free(s, TRUE);
* callback returns.
*/
- printf("Client %s is activated (osMajorType %d osMinorType %d)", client->local ? "(local)" : client->hostname,
+ DEBUG_MSG("Client %s is activated (osMajorType %d osMinorType %d)", client->local ? "(local)" : client->hostname,
client->settings->OsMajorType, client->settings->OsMinorType);
if (client->settings->AutoLogonEnabled)
{
- printf(" and wants to login automatically as %s\\%s",
+ DEBUG_MSG(" and wants to login automatically as %s\\%s",
client->settings->Domain ? client->settings->Domain : "",
client->settings->Username);
/* A real server may perform OS login here if NLA is not executed previously. */
}
- printf("\n");
+ DEBUG_MSG("\n");
- printf("Client requested desktop: %dx%dx%d\n",
+ DEBUG_MSG("Client requested desktop: %dx%dx%d\n",
client->settings->DesktopWidth, client->settings->DesktopHeight, client->settings->ColorDepth);
#if (SAMPLE_SERVER_USE_CLIENT_RESOLUTION == 1)
context->rfx_context->width = client->settings->DesktopWidth;
context->rfx_context->height = client->settings->DesktopHeight;
- printf("Using resolution requested by client.\n");
+ DEBUG_MSG("Using resolution requested by client.\n");
#else
client->settings->DesktopWidth = context->rfx_context->width;
client->settings->DesktopHeight = context->rfx_context->height;
- printf("Resizing client to %dx%d\n", client->settings->DesktopWidth, client->settings->DesktopHeight);
+ DEBUG_MSG("Resizing client to %dx%d\n", client->settings->DesktopWidth, client->settings->DesktopHeight);
client->update->DesktopResize(client->update->context);
#endif
if (context->debug_channel != NULL)
{
- printf("Open channel rdpdbg.\n");
+ DEBUG_MSG("Open channel rdpdbg.\n");
context->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
void tf_peer_synchronize_event(rdpInput* input, UINT32 flags)
{
- printf("Client sent a synchronize event (flags:0x%X)\n", flags);
+ DEBUG_MSG("Client sent a synchronize event (flags:0x%X)\n", flags);
}
void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
rdpUpdate* update = client->update;
testPeerContext* context = (testPeerContext*) input->context;
- printf("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code);
+ DEBUG_MSG("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code);
if ((flags & 0x4000) && code == 0x22) /* 'g' key */
{
void tf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
{
- printf("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code);
+ DEBUG_MSG("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code);
}
void tf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
BYTE i;
- printf("Client requested to refresh:\n");
+ DEBUG_MSG("Client requested to refresh:\n");
for (i = 0; i < count; i++)
{
- printf(" (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom);
+ DEBUG_MSG(" (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom);
}
}
{
if (allow > 0)
{
- printf("Client restore output (%d, %d) (%d, %d).\n", area->left, area->top, area->right, area->bottom);
+ DEBUG_MSG("Client restore output (%d, %d) (%d, %d).\n", area->left, area->top, area->right, area->bottom);
}
else
{
- printf("Client minimized and suppress output.\n");
+ DEBUG_MSG("Client minimized and suppress output.\n");
}
}
client->Initialize(client);
context = (testPeerContext*) client->context;
- printf("We've got a client %s\n", client->local ? "(local)" : client->hostname);
+ DEBUG_MSG("We've got a client %s\n", client->local ? "(local)" : client->hostname);
while (1)
{
memset(rfds, 0, sizeof(rfds));
if (client->GetFileDescriptor(client, rfds, &rcount) != TRUE)
{
- printf("Failed to get FreeRDP file descriptor\n");
+ DEBUG_MSG("Failed to get FreeRDP file descriptor\n");
break;
}
(wsa_error == WSAEINPROGRESS) ||
(wsa_error == WSAEINTR)))
{
- printf("select failed (WSAGetLastError: %d)\n", wsa_error);
+ DEBUG_MSG("select failed (WSAGetLastError: %d)\n", wsa_error);
break;
}
#else
(errno == EINPROGRESS) ||
(errno == EINTR))) /* signal occurred */
{
- printf("select failed (errno: %d)\n", errno);
+ DEBUG_MSG("select failed (errno: %d)\n", errno);
break;
}
#endif
break;
}
- printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname);
+ DEBUG_MSG("Client %s disconnected.\n", client->local ? "(local)" : client->hostname);
client->Disconnect(client);
freerdp_peer_context_free(client);
memset(rfds, 0, sizeof(rfds));
if (instance->GetFileDescriptor(instance, rfds, &rcount) != TRUE)
{
- printf("Failed to get FreeRDP file descriptor\n");
+ DEBUG_MSG("Failed to get FreeRDP file descriptor\n");
break;
}
(errno == EINPROGRESS) ||
(errno == EINTR))) /* signal occurred */
{
- printf("select failed\n");
+ DEBUG_MSG("select failed\n");
break;
}
}
if (instance->CheckFileDescriptor(instance) != TRUE)
{
- printf("Failed to check FreeRDP file descriptor\n");
+ DEBUG_MSG("Failed to check FreeRDP file descriptor\n");
break;
}
}
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Sample Server\r
- *\r
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef SFREERDP_SERVER_H\r
-#define SFREERDP_SERVER_H\r
-\r
-#include <freerdp/freerdp.h>\r
-#include <freerdp/listener.h>\r
-#include <freerdp/codec/rfx.h>\r
-#include <freerdp/codec/nsc.h>\r
-#include <freerdp/channels/wtsvc.h>\r
-#include <freerdp/server/audin.h>\r
-#include <freerdp/server/rdpsnd.h>\r
-#include <freerdp/server/encomsp.h>\r
-\r
-#include <winpr/crt.h>\r
-#include <winpr/synch.h>\r
-#include <winpr/thread.h>\r
-\r
-struct test_peer_context\r
-{\r
- rdpContext _p;\r
-\r
- RFX_CONTEXT* rfx_context;\r
- NSC_CONTEXT* nsc_context;\r
- wStream* s;\r
- BYTE* icon_data;\r
- BYTE* bg_data;\r
- int icon_width;\r
- int icon_height;\r
- int icon_x;\r
- int icon_y;\r
- BOOL activated;\r
- HANDLE event;\r
- HANDLE stopEvent;\r
- HANDLE vcm;\r
- void* debug_channel;\r
- HANDLE debug_channel_thread;\r
- audin_server_context* audin;\r
- BOOL audin_open;\r
- UINT32 frame_id;\r
- RdpsndServerContext* rdpsnd;\r
- EncomspServerContext* encomsp;\r
-};\r
-typedef struct test_peer_context testPeerContext;\r
-\r
-#endif /* SFREERDP_SERVER_H */\r
-\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Sample Server
+ *
+ * Copyright 2012 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 SFREERDP_SERVER_H
+#define SFREERDP_SERVER_H
+
+#include <freerdp/freerdp.h>
+#include <freerdp/listener.h>
+#include <freerdp/codec/rfx.h>
+#include <freerdp/codec/nsc.h>
+#include <freerdp/channels/wtsvc.h>
+#include <freerdp/server/audin.h>
+#include <freerdp/server/rdpsnd.h>
+#include <freerdp/server/encomsp.h>
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+
+struct test_peer_context
+{
+ rdpContext _p;
+
+ RFX_CONTEXT* rfx_context;
+ NSC_CONTEXT* nsc_context;
+ wStream* s;
+ BYTE* icon_data;
+ BYTE* bg_data;
+ int icon_width;
+ int icon_height;
+ int icon_x;
+ int icon_y;
+ BOOL activated;
+ HANDLE event;
+ HANDLE stopEvent;
+ HANDLE vcm;
+ void* debug_channel;
+ HANDLE debug_channel_thread;
+ audin_server_context* audin;
+ BOOL audin_open;
+ UINT32 frame_id;
+ RdpsndServerContext* rdpsnd;
+ EncomspServerContext* encomsp;
+};
+typedef struct test_peer_context testPeerContext;
+
+#endif /* SFREERDP_SERVER_H */
+
\r
if(WITH_SERVER_INTERFACE)\r
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})\r
- if (WITH_LIBRARY_VERSIONING)
- set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION})
- endif()
+ if (WITH_LIBRARY_VERSIONING)\r
+ set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION})\r
+ endif()\r
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "lib")\r
else()\r
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/wfreerdp.c cli/wfreerdp.h)\r
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})\r
endif()\r
-
\r
-if(WITH_WIN8) \r
+\r
+if(CMAKE_WINDOWS_VERSION STREQUAL "WIN8")\r
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} d3d11 dxgi dxguid)\r
endif()\r
\r
BOOL CALLBACK moncb(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
- printf("%d\t(%d, %d), (%d, %d)\n",
+ DEBUG_MSG("%d\t(%d, %d), (%d, %d)\n",
IDcount, lprcMonitor->left, lprcMonitor->top,
lprcMonitor->right, lprcMonitor->bottom);
vscreen_w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
vscreen_h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
- printf("\n");
+ DEBUG_MSG("\n");
EnumDisplayMonitors(NULL, NULL, moncb, 0);
IDcount = 0;
- printf("\nVirtual Screen = %dx%d\n", vscreen_w, vscreen_h);
+ DEBUG_MSG("\nVirtual Screen = %dx%d\n", vscreen_w, vscreen_h);
}
return 0;
index++;
if (index == argc)
{
- printf("missing screen id parameter\n");
+ DEBUG_MSG("missing screen id parameter\n");
return 0;
}
}
}
- printf("Starting server\n");
+ DEBUG_MSG("Starting server\n");
wfreerdp_server_start(server);
WaitForSingleObject(server->thread, INFINITE);
- printf("Stopping server\n");
+ DEBUG_MSG("Stopping server\n");
wfreerdp_server_stop(server);
wfreerdp_server_free(server);
wfi = wf_info_get_instance();
- printf("RDPSND (direct sound) Activated\n");
+ DEBUG_MSG("RDPSND (direct sound) Activated\n");
hr = DirectSoundCaptureCreate8(NULL, &cap, NULL);
#include "wf_interface.h"
-#ifdef WITH_WIN8
+#ifdef WITH_DXGI_1_2
#define CINTERFACE
int wf_dxgi_init(wfInfo* wfi)
{
- //not sure if needed
gAcquiredDesktopImage = NULL;
if (wf_dxgi_createDevice(wfi) != 0)
}
return 0;
-
}
int wf_dxgi_createDevice(wfInfo* wfi)
break;\r
\r
case WAIT_FAILED:\r
- printf("wf_info_lock failed with 0x%08X\n", GetLastError());\r
+ DEBUG_WARN("wf_info_lock failed with 0x%08X\n", GetLastError());\r
return -1;\r
break;\r
}\r
break;\r
\r
case WAIT_FAILED:\r
- printf("wf_info_try_lock failed with 0x%08X\n", GetLastError());\r
+ DEBUG_WARN("wf_info_try_lock failed with 0x%08X\n", GetLastError());\r
return -1;\r
break;\r
}\r
{\r
if (ReleaseMutex(wfi->mutex) == 0)\r
{\r
- printf("wf_info_unlock failed with 0x%08X\n", GetLastError());\r
+ DEBUG_WARN("wf_info_unlock failed with 0x%08X\n", GetLastError());\r
return -1;\r
}\r
\r
EnumDisplayMonitors(NULL, NULL, wf_info_monEnumCB, 0);\r
_IDcount = 0;\r
\r
-#ifdef WITH_WIN8\r
+#ifdef WITH_DXGI_1_2\r
if (wfi->peerCount == 0)\r
wf_dxgi_init(wfi);\r
#else\r
wfi->peers[peerId] = ((rdpContext*) context)->peer;\r
wfi->peers[peerId]->pId = peerId;\r
wfi->peerCount++;\r
- printf("Registering Peer: id=%d #=%d\n", peerId, wfi->peerCount);\r
+ DEBUG_WARN("Registering Peer: id=%d #=%d\n", peerId, wfi->peerCount);\r
\r
wf_info_unlock(wfi);\r
\r
wfi->peerCount--;\r
CloseHandle(context->updateEvent);\r
\r
- printf("Unregistering Peer: id=%d, #=%d\n", peerId, wfi->peerCount);\r
+ DEBUG_WARN("Unregistering Peer: id=%d, #=%d\n", peerId, wfi->peerCount);\r
\r
-#ifdef WITH_WIN8\r
+#ifdef WITH_DXGI_1_2\r
if (wfi->peerCount == 0)\r
wf_dxgi_cleanup(wfi);\r
#endif\r
\r
BOOL wf_info_have_updates(wfInfo* wfi)\r
{\r
-#ifdef WITH_WIN8\r
+#ifdef WITH_DXGI_1_2\r
if(wfi->framesWaiting == 0)\r
return FALSE;\r
#else\r
\r
void wf_info_update_changes(wfInfo* wfi)\r
{\r
-#ifdef WITH_WIN8\r
+#ifdef WITH_DXGI_1_2\r
wf_dxgi_nextFrame(wfi, wfi->framesPerSecond * 1000);\r
#else\r
GETCHANGESBUF* buf;\r
\r
void wf_info_find_invalid_region(wfInfo* wfi)\r
{\r
-#ifdef WITH_WIN8\r
+#ifdef WITH_DXGI_1_2\r
wf_dxgi_getInvalidRegion(&wfi->invalid);\r
#else\r
int i;\r
*width = (wfi->invalid.right - wfi->invalid.left);\r
*height = (wfi->invalid.bottom - wfi->invalid.top);\r
\r
-#ifdef WITH_WIN8\r
+#ifdef WITH_DXGI_1_2\r
wf_dxgi_getPixelData(wfi, pBits, pitch, &wfi->invalid);\r
#else\r
{\r
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Windows Server\r
- *\r
- * Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef WF_INFO_H\r
-#define WF_INFO_H\r
-\r
-#include "wf_interface.h"\r
-\r
-#define WF_INFO_DEFAULT_FPS 24\r
-#define WF_INFO_MAXPEERS 32\r
-\r
-int wf_info_lock(wfInfo* wfi);\r
-int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds);\r
-int wf_info_unlock(wfInfo* wfi);\r
-\r
-wfInfo* wf_info_get_instance(void);\r
-void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context);\r
-void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context);\r
-\r
-BOOL wf_info_have_updates(wfInfo* wfi);\r
-void wf_info_update_changes(wfInfo* wfi);\r
-void wf_info_find_invalid_region(wfInfo* wfi);\r
-void wf_info_clear_invalid_region(wfInfo* wfi);\r
-void wf_info_invalidate_full_screen(wfInfo* wfi);\r
-BOOL wf_info_have_invalid_region(wfInfo* wfi);\r
-void wf_info_getScreenData(wfInfo* wfi, long* width, long* height, BYTE** pBits, int* pitch);\r
-BOOL CALLBACK wf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData);\r
-\r
-#endif /* WF_INFO_H */\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Windows Server
+ *
+ * Copyright 2012 Corey Clayton <can.of.tuna@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_INFO_H
+#define WF_INFO_H
+
+#include "wf_interface.h"
+
+#define WF_INFO_DEFAULT_FPS 24
+#define WF_INFO_MAXPEERS 32
+
+int wf_info_lock(wfInfo* wfi);
+int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds);
+int wf_info_unlock(wfInfo* wfi);
+
+wfInfo* wf_info_get_instance(void);
+void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context);
+void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context);
+
+BOOL wf_info_have_updates(wfInfo* wfi);
+void wf_info_update_changes(wfInfo* wfi);
+void wf_info_find_invalid_region(wfInfo* wfi);
+void wf_info_clear_invalid_region(wfInfo* wfi);
+void wf_info_invalidate_full_screen(wfInfo* wfi);
+BOOL wf_info_have_invalid_region(wfInfo* wfi);
+void wf_info_getScreenData(wfInfo* wfi, long* width, long* height, BYTE** pBits, int* pitch);
+BOOL CALLBACK wf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData);
+
+#endif /* WF_INFO_H */
x += wfi->servscreen_xoffset;
y += wfi->servscreen_yoffset;
- //mouse_event.mi.dx = x * (0xFFFF / width);
- //mouse_event.mi.dy = y * (0xFFFF / height);
mouse_event.mi.dx = (LONG) ((float) x * (65535.0f / width));
mouse_event.mi.dy = (LONG) ((float) y * (65535.0f / height));
mouse_event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
if (instance->GetFileDescriptor(instance, rfds, &rcount) != TRUE)
{
- printf("Failed to get FreeRDP file descriptor\n");
+ DEBUG_WARN("Failed to get FreeRDP file descriptor\n");
break;
}
if (instance->CheckFileDescriptor(instance) != TRUE)
{
- printf("Failed to check FreeRDP file descriptor\n");
+ DEBUG_WARN("Failed to check FreeRDP file descriptor\n");
break;
}
}
- printf("wf_server_main_loop terminating\n");
+ DEBUG_WARN("wf_server_main_loop terminating\n");
instance->Close(instance);
wfi = wf_info_get_instance();
- printf("Stopping server\n");
+ DEBUG_WARN("Stopping server\n");
wfi->force_all_disconnect = TRUE;
server->instance->Close(server->instance);
return TRUE;
bRet = GetExitCodeThread(server->thread, &tStatus);
if (bRet == 0)
{
- printf("Error in call to GetExitCodeThread\n");
+ DEBUG_WARN("Error in call to GetExitCodeThread\n");
return FALSE;
}
}
else
{
- printf("nonexistent peer id=%d\n", pId);
+ DEBUG_WARN("nonexistent peer id=%d\n", pId);
return 0;
}
}
#include <freerdp/freerdp.h>
#include <freerdp/codec/rfx.h>
+#include <freerdp/utils/debug.h>
#include <freerdp/server/rdpsnd.h>
+#if _WIN32_WINNT >= 0x0602
+#define WITH_DXGI_1_2 1
+#endif
+
#define WF_SRV_CALLBACK_EVENT_CONNECT 1
#define WF_SRV_CALLBACK_EVENT_DISCONNECT 2
#define WF_SRV_CALLBACK_EVENT_ACTIVATE 4
int servscreen_height;
int servscreen_xoffset;
int servscreen_yoffset;
- //int width;
- //int height;
int frame_idx;
int bitsPerPixel;
\r
if (status != ERROR_SUCCESS)\r
{\r
- printf("Error opening RegKey: status=%0X\n", status);\r
+ DEBUG_WARN("Error opening RegKey: status=%0X\n", status);\r
if (status == ERROR_ACCESS_DENIED) \r
- printf("access denied. Do you have admin privleges?\n");\r
+ DEBUG_WARN("access denied. Do you have admin privleges?\n");\r
return FALSE;\r
}\r
\r
\r
if (status != ERROR_SUCCESS)\r
{\r
- printf("Error querying RegKey: status=%0X\n", status);\r
+ DEBUG_WARN("Error querying RegKey: status=%0X\n", status);\r
if (status == ERROR_ACCESS_DENIED) \r
- printf("access denied. Do you have admin privleges?\n");\r
+ DEBUG_WARN("access denied. Do you have admin privleges?\n");\r
return FALSE;\r
}\r
\r
\r
if (status != ERROR_SUCCESS)\r
{ \r
- printf("Error writing registry key: %d ", status);\r
+ DEBUG_WARN("Error writing registry key: %d ", status);\r
if (status == ERROR_ACCESS_DENIED) \r
- printf("access denied. Do you have admin privleges?");\r
- printf("\n");\r
+ DEBUG_WARN("access denied. Do you have admin privleges?");\r
+ DEBUG_WARN("\n");\r
return FALSE;\r
}\r
}\r
\r
if ( (mode != MIRROR_LOAD) && (mode != MIRROR_UNLOAD) )\r
{\r
- printf("Invalid mirror mode!\n");\r
+ DEBUG_WARN("Invalid mirror mode!\n");\r
return FALSE;\r
}\r
\r
{\r
if (!wfi->mirrorDriverActive)\r
{\r
- printf("Activating Mirror Driver\n");\r
+ DEBUG_WARN("Activating Mirror Driver\n");\r
\r
if (wf_mirror_driver_find_display_device(wfi) == FALSE)\r
{\r
- printf("Could not find dfmirage mirror driver! Is it installed?\n");\r
+ DEBUG_WARN("Could not find dfmirage mirror driver! Is it installed?\n");\r
return FALSE;\r
}\r
\r
if (wf_mirror_driver_display_device_attach(wfi, 1) == FALSE)\r
{\r
- printf("Could not attach display device!\n");\r
+ DEBUG_WARN("Could not attach display device!\n");\r
return FALSE;\r
}\r
\r
if (wf_mirror_driver_update(wfi, MIRROR_LOAD) == FALSE)\r
{\r
- printf("could not update system with new display settings!\n");\r
+ DEBUG_WARN("could not update system with new display settings!\n");\r
return FALSE;\r
}\r
\r
if (wf_mirror_driver_map_memory(wfi) == FALSE)\r
{\r
- printf("Unable to map memory for mirror driver!\n");\r
+ DEBUG_WARN("Unable to map memory for mirror driver!\n");\r
return FALSE;\r
}\r
wfi->mirrorDriverActive = TRUE;\r
{\r
if (wfi->mirrorDriverActive)\r
{\r
- printf("Deactivating Mirror Driver\n");\r
+ DEBUG_WARN("Deactivating Mirror Driver\n");\r
\r
wf_mirror_driver_cleanup(wfi);\r
wf_mirror_driver_display_device_attach(wfi, 0);\r
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Windows Server\r
- *\r
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>\r
- * Copyright 2012-2013 Corey Clayton <can.of.tuna@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef WF_MIRAGE_H\r
-#define WF_MIRAGE_H\r
-\r
-#include "wf_interface.h"\r
-\r
-enum\r
-{\r
- MIRROR_LOAD = 0,\r
- MIRROR_UNLOAD = 1\r
-};\r
-\r
-\r
-\r
-enum\r
-{\r
- DMF_ESCAPE_BASE_1_VB = 1030,\r
- DMF_ESCAPE_BASE_2_VB = 1026, \r
- DMF_ESCAPE_BASE_3_VB = 24\r
-};\r
-\r
-#ifdef _WIN64\r
-\r
-#define CLIENT_64BIT 0x8000\r
-\r
-enum\r
-{\r
- DMF_ESCAPE_BASE_1 = CLIENT_64BIT | DMF_ESCAPE_BASE_1_VB,\r
- DMF_ESCAPE_BASE_2 = CLIENT_64BIT | DMF_ESCAPE_BASE_2_VB, \r
- DMF_ESCAPE_BASE_3 = CLIENT_64BIT | DMF_ESCAPE_BASE_3_VB, \r
-};\r
-\r
-#else\r
-\r
-enum\r
-{\r
- DMF_ESCAPE_BASE_1 = DMF_ESCAPE_BASE_1_VB,\r
- DMF_ESCAPE_BASE_2 = DMF_ESCAPE_BASE_2_VB, \r
- DMF_ESCAPE_BASE_3 = DMF_ESCAPE_BASE_3_VB, \r
-};\r
-\r
-#endif\r
-\r
-typedef enum\r
-{\r
- dmf_esc_qry_ver_info = DMF_ESCAPE_BASE_2 + 0,\r
- dmf_esc_usm_pipe_map = DMF_ESCAPE_BASE_1 + 0,\r
- dmf_esc_usm_pipe_unmap = DMF_ESCAPE_BASE_1 + 1,\r
- dmf_esc_test = DMF_ESCAPE_BASE_1 + 20,\r
- dmf_esc_usm_pipe_mapping_test = DMF_ESCAPE_BASE_1 + 21,\r
- dmf_esc_pointer_shape_get = DMF_ESCAPE_BASE_3,\r
-\r
-} dmf_escape;\r
-\r
-#define CLIP_LIMIT 50\r
-#define MAXCHANGES_BUF 20000\r
-\r
-typedef enum\r
-{\r
- dmf_dfo_IGNORE = 0,\r
- dmf_dfo_FROM_SCREEN = 1,\r
- dmf_dfo_FROM_DIB = 2,\r
- dmf_dfo_TO_SCREEN = 3,\r
- dmf_dfo_SCREEN_SCREEN = 11,\r
- dmf_dfo_BLIT = 12,\r
- dmf_dfo_SOLIDFILL = 13,\r
- dmf_dfo_BLEND = 14,\r
- dmf_dfo_TRANS = 15,\r
- dmf_dfo_PLG = 17,\r
- dmf_dfo_TEXTOUT = 18,\r
- dmf_dfo_Ptr_Shape = 19,\r
- dmf_dfo_Ptr_Engage = 48,\r
- dmf_dfo_Ptr_Avert = 49,\r
- dmf_dfn_assert_on = 64,\r
- dmf_dfn_assert_off = 65,\r
-} dmf_UpdEvent;\r
-\r
-#define NOCACHE 1\r
-#define OLDCACHE 2\r
-#define NEWCACHE 3\r
-\r
-typedef struct\r
-{\r
- ULONG type;\r
- RECT rect;\r
-#ifndef DFMIRAGE_LEAN\r
- RECT origrect;\r
- POINT point;\r
- ULONG color;\r
- ULONG refcolor;\r
-#endif\r
-} CHANGES_RECORD;\r
-\r
-typedef CHANGES_RECORD* PCHANGES_RECORD;\r
-\r
-typedef struct\r
-{\r
- ULONG counter;\r
- CHANGES_RECORD pointrect[MAXCHANGES_BUF];\r
-} CHANGES_BUF;\r
-\r
-#define EXT_DEVMODE_SIZE_MAX 3072\r
-#define DMF_PIPE_SEC_SIZE_DEFAULT ALIGN64K(sizeof(CHANGES_BUF))\r
-\r
-typedef struct\r
-{\r
- CHANGES_BUF* buffer;\r
- PVOID Userbuffer;\r
-} GETCHANGESBUF;\r
-\r
-#define dmf_sprb_ERRORMASK 0x07FF\r
-#define dmf_sprb_STRICTSESSION_AFF 0x1FFF\r
-\r
-typedef enum\r
-{\r
- dmf_sprb_internal_error = 0x0001,\r
- dmf_sprb_miniport_gen_error = 0x0004,\r
- dmf_sprb_memory_alloc_failed = 0x0008,\r
- dmf_sprb_pipe_buff_overflow = 0x0010,\r
- dmf_sprb_pipe_buff_insufficient = 0x0020,\r
- dmf_sprb_pipe_not_ready = 0x0040,\r
- dmf_sprb_gdi_err = 0x0100,\r
- dmf_sprb_owner_died = 0x0400,\r
- dmf_sprb_tgtwnd_gone = 0x0800,\r
- dmf_sprb_pdev_detached = 0x2000,\r
-} dmf_session_prob_status;\r
-\r
-#define DMF_ESC_RET_FAILF 0x80000000\r
-#define DMF_ESC_RET_SSTMASK 0x0000FFFF\r
-#define DMF_ESC_RET_IMMMASK 0x7FFF0000\r
-\r
-typedef enum\r
-{\r
- dmf_escret_generic_ok = 0x00010000,\r
- dmf_escret_bad_state = 0x00100000,\r
- dmf_escret_access_denied = 0x00200000,\r
- dmf_escret_bad_buffer_size = 0x00400000,\r
- dmf_escret_internal_err = 0x00800000,\r
- dmf_escret_out_of_memory = 0x02000000,\r
- dmf_escret_already_connected = 0x04000000,\r
- dmf_escret_oh_boy_too_late = 0x08000000,\r
- dmf_escret_bad_window = 0x10000000,\r
- dmf_escret_drv_ver_higher = 0x20000000,\r
- dmf_escret_drv_ver_lower = 0x40000000,\r
-} dmf_esc_retcode;\r
-\r
-typedef struct\r
-{\r
- ULONG cbSize;\r
- ULONG app_actual_version;\r
- ULONG display_minreq_version;\r
- ULONG connect_options;\r
-} Esc_dmf_Qvi_IN;\r
-\r
-enum\r
-{\r
- esc_qvi_prod_name_max = 16,\r
-};\r
-\r
-#define ESC_QVI_PROD_MIRAGE "MIRAGE"\r
-#define ESC_QVI_PROD_QUASAR "QUASAR"\r
-\r
-typedef struct\r
-{\r
- ULONG cbSize;\r
- ULONG display_actual_version;\r
- ULONG miniport_actual_version;\r
- ULONG app_minreq_version;\r
- ULONG display_buildno;\r
- ULONG miniport_buildno;\r
- char prod_name[esc_qvi_prod_name_max];\r
-} Esc_dmf_Qvi_OUT;\r
-\r
-typedef struct\r
-{\r
- ULONG cbSize;\r
- char* pDstBmBuf;\r
- ULONG nDstBmBufSize;\r
-} Esc_dmf_pointer_shape_get_IN;\r
-\r
-typedef struct\r
-{\r
- ULONG cbSize;\r
- POINTL BmSize;\r
- char* pMaskBm;\r
- ULONG nMaskBmSize;\r
- char* pColorBm;\r
- ULONG nColorBmSize;\r
- char* pColorBmPal;\r
- ULONG nColorBmPalEntries;\r
-} Esc_dmf_pointer_shape_get_OUT;\r
-\r
-BOOL wf_mirror_driver_find_display_device(wfInfo* wfi);\r
-BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode);\r
-BOOL wf_mirror_driver_update(wfInfo* wfi, int mode);\r
-BOOL wf_mirror_driver_map_memory(wfInfo* wfi);\r
-BOOL wf_mirror_driver_cleanup(wfInfo* wfi);\r
-\r
-BOOL wf_mirror_driver_activate(wfInfo* wfi);\r
-void wf_mirror_driver_deactivate(wfInfo* wfi);\r
-\r
-#endif /* WF_MIRAGE_H */\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Windows Server
+ *
+ * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2012-2013 Corey Clayton <can.of.tuna@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_MIRAGE_H
+#define WF_MIRAGE_H
+
+#include "wf_interface.h"
+
+enum
+{
+ MIRROR_LOAD = 0,
+ MIRROR_UNLOAD = 1
+};
+
+
+
+enum
+{
+ DMF_ESCAPE_BASE_1_VB = 1030,
+ DMF_ESCAPE_BASE_2_VB = 1026,
+ DMF_ESCAPE_BASE_3_VB = 24
+};
+
+#ifdef _WIN64
+
+#define CLIENT_64BIT 0x8000
+
+enum
+{
+ DMF_ESCAPE_BASE_1 = CLIENT_64BIT | DMF_ESCAPE_BASE_1_VB,
+ DMF_ESCAPE_BASE_2 = CLIENT_64BIT | DMF_ESCAPE_BASE_2_VB,
+ DMF_ESCAPE_BASE_3 = CLIENT_64BIT | DMF_ESCAPE_BASE_3_VB,
+};
+
+#else
+
+enum
+{
+ DMF_ESCAPE_BASE_1 = DMF_ESCAPE_BASE_1_VB,
+ DMF_ESCAPE_BASE_2 = DMF_ESCAPE_BASE_2_VB,
+ DMF_ESCAPE_BASE_3 = DMF_ESCAPE_BASE_3_VB,
+};
+
+#endif
+
+typedef enum
+{
+ dmf_esc_qry_ver_info = DMF_ESCAPE_BASE_2 + 0,
+ dmf_esc_usm_pipe_map = DMF_ESCAPE_BASE_1 + 0,
+ dmf_esc_usm_pipe_unmap = DMF_ESCAPE_BASE_1 + 1,
+ dmf_esc_test = DMF_ESCAPE_BASE_1 + 20,
+ dmf_esc_usm_pipe_mapping_test = DMF_ESCAPE_BASE_1 + 21,
+ dmf_esc_pointer_shape_get = DMF_ESCAPE_BASE_3,
+
+} dmf_escape;
+
+#define CLIP_LIMIT 50
+#define MAXCHANGES_BUF 20000
+
+typedef enum
+{
+ dmf_dfo_IGNORE = 0,
+ dmf_dfo_FROM_SCREEN = 1,
+ dmf_dfo_FROM_DIB = 2,
+ dmf_dfo_TO_SCREEN = 3,
+ dmf_dfo_SCREEN_SCREEN = 11,
+ dmf_dfo_BLIT = 12,
+ dmf_dfo_SOLIDFILL = 13,
+ dmf_dfo_BLEND = 14,
+ dmf_dfo_TRANS = 15,
+ dmf_dfo_PLG = 17,
+ dmf_dfo_TEXTOUT = 18,
+ dmf_dfo_Ptr_Shape = 19,
+ dmf_dfo_Ptr_Engage = 48,
+ dmf_dfo_Ptr_Avert = 49,
+ dmf_dfn_assert_on = 64,
+ dmf_dfn_assert_off = 65,
+} dmf_UpdEvent;
+
+#define NOCACHE 1
+#define OLDCACHE 2
+#define NEWCACHE 3
+
+typedef struct
+{
+ ULONG type;
+ RECT rect;
+#ifndef DFMIRAGE_LEAN
+ RECT origrect;
+ POINT point;
+ ULONG color;
+ ULONG refcolor;
+#endif
+} CHANGES_RECORD;
+
+typedef CHANGES_RECORD* PCHANGES_RECORD;
+
+typedef struct
+{
+ ULONG counter;
+ CHANGES_RECORD pointrect[MAXCHANGES_BUF];
+} CHANGES_BUF;
+
+#define EXT_DEVMODE_SIZE_MAX 3072
+#define DMF_PIPE_SEC_SIZE_DEFAULT ALIGN64K(sizeof(CHANGES_BUF))
+
+typedef struct
+{
+ CHANGES_BUF* buffer;
+ PVOID Userbuffer;
+} GETCHANGESBUF;
+
+#define dmf_sprb_ERRORMASK 0x07FF
+#define dmf_sprb_STRICTSESSION_AFF 0x1FFF
+
+typedef enum
+{
+ dmf_sprb_internal_error = 0x0001,
+ dmf_sprb_miniport_gen_error = 0x0004,
+ dmf_sprb_memory_alloc_failed = 0x0008,
+ dmf_sprb_pipe_buff_overflow = 0x0010,
+ dmf_sprb_pipe_buff_insufficient = 0x0020,
+ dmf_sprb_pipe_not_ready = 0x0040,
+ dmf_sprb_gdi_err = 0x0100,
+ dmf_sprb_owner_died = 0x0400,
+ dmf_sprb_tgtwnd_gone = 0x0800,
+ dmf_sprb_pdev_detached = 0x2000,
+} dmf_session_prob_status;
+
+#define DMF_ESC_RET_FAILF 0x80000000
+#define DMF_ESC_RET_SSTMASK 0x0000FFFF
+#define DMF_ESC_RET_IMMMASK 0x7FFF0000
+
+typedef enum
+{
+ dmf_escret_generic_ok = 0x00010000,
+ dmf_escret_bad_state = 0x00100000,
+ dmf_escret_access_denied = 0x00200000,
+ dmf_escret_bad_buffer_size = 0x00400000,
+ dmf_escret_internal_err = 0x00800000,
+ dmf_escret_out_of_memory = 0x02000000,
+ dmf_escret_already_connected = 0x04000000,
+ dmf_escret_oh_boy_too_late = 0x08000000,
+ dmf_escret_bad_window = 0x10000000,
+ dmf_escret_drv_ver_higher = 0x20000000,
+ dmf_escret_drv_ver_lower = 0x40000000,
+} dmf_esc_retcode;
+
+typedef struct
+{
+ ULONG cbSize;
+ ULONG app_actual_version;
+ ULONG display_minreq_version;
+ ULONG connect_options;
+} Esc_dmf_Qvi_IN;
+
+enum
+{
+ esc_qvi_prod_name_max = 16,
+};
+
+#define ESC_QVI_PROD_MIRAGE "MIRAGE"
+#define ESC_QVI_PROD_QUASAR "QUASAR"
+
+typedef struct
+{
+ ULONG cbSize;
+ ULONG display_actual_version;
+ ULONG miniport_actual_version;
+ ULONG app_minreq_version;
+ ULONG display_buildno;
+ ULONG miniport_buildno;
+ char prod_name[esc_qvi_prod_name_max];
+} Esc_dmf_Qvi_OUT;
+
+typedef struct
+{
+ ULONG cbSize;
+ char* pDstBmBuf;
+ ULONG nDstBmBufSize;
+} Esc_dmf_pointer_shape_get_IN;
+
+typedef struct
+{
+ ULONG cbSize;
+ POINTL BmSize;
+ char* pMaskBm;
+ ULONG nMaskBmSize;
+ char* pColorBm;
+ ULONG nColorBmSize;
+ char* pColorBmPal;
+ ULONG nColorBmPalEntries;
+} Esc_dmf_pointer_shape_get_OUT;
+
+BOOL wf_mirror_driver_find_display_device(wfInfo* wfi);
+BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode);
+BOOL wf_mirror_driver_update(wfInfo* wfi, int mode);
+BOOL wf_mirror_driver_map_memory(wfInfo* wfi);
+BOOL wf_mirror_driver_cleanup(wfInfo* wfi);
+
+BOOL wf_mirror_driver_activate(wfInfo* wfi);
+void wf_mirror_driver_deactivate(wfInfo* wfi);
+
+#endif /* WF_MIRAGE_H */
if ((settings->DesktopWidth != wfi->servscreen_width) || (settings->DesktopHeight != wfi->servscreen_height))\r
{\r
/*\r
- printf("Client requested resolution %dx%d, but will resize to %dx%d\n",\r
+ DEBUG_WARN("Client requested resolution %dx%d, but will resize to %dx%d\n",\r
settings->DesktopWidth, settings->DesktopHeight, wfi->servscreen_width, wfi->servscreen_height);\r
*/\r
\r
\r
BOOL wf_peer_logon(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* identity, BOOL automatic)\r
{\r
- /*\r
- if (automatic)\r
- {\r
- _tprintf(_T("Logon: User:%s Domain:%s Password:%s\n"),\r
- identity->User, identity->Domain, identity->Password);\r
- }\r
- */\r
-\r
wfreerdp_server_peer_callback_event(((rdpContext*) client->context)->peer->pId, WF_SRV_CALLBACK_EVENT_AUTH);\r
return TRUE;\r
}\r
\r
if (wfi->input_disabled)\r
{\r
- printf("client input is disabled\n");\r
+ DEBUG_WARN("client input is disabled\n");\r
client->input->KeyboardEvent = wf_peer_keyboard_event_dummy;\r
client->input->UnicodeKeyboardEvent = wf_peer_unicode_keyboard_event_dummy;\r
client->input->MouseEvent = wf_peer_mouse_event_dummy;\r
context->socketSemaphore = CreateSemaphore(NULL, 0, 1, NULL);\r
context->socketThread = CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL);\r
\r
- printf("We've got a client %s\n", client->local ? "(local)" : client->hostname);\r
+ DEBUG_WARN("We've got a client %s\n", client->local ? "(local)" : client->hostname);\r
\r
nCount = 0;\r
handles[nCount++] = context->updateEvent;\r
\r
if ((status == WAIT_FAILED) || (status == WAIT_TIMEOUT))\r
{\r
- printf("WaitForMultipleObjects failed\n");\r
+ DEBUG_WARN("WaitForMultipleObjects failed\n");\r
break;\r
}\r
\r
//force disconnect\r
if (wfi->force_all_disconnect == TRUE)\r
{\r
- printf("Forcing Disconnect -> ");\r
+ DEBUG_WARN("Forcing Disconnect -> ");\r
break;\r
}\r
\r
break;\r
}\r
\r
- printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname);\r
+ DEBUG_WARN("Client %s disconnected.\n", client->local ? "(local)" : client->hostname);\r
\r
if (WaitForSingleObject(context->updateEvent, 0) == 0)\r
{\r
-/**\r
- * FreeRDP: A Remote Desktop Protocol Implementation\r
- * FreeRDP Windows Server\r
- *\r
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef WF_PEER_H\r
-#define WF_PEER_H\r
-\r
-#include "wf_interface.h"\r
-\r
-#include <freerdp/listener.h>\r
-\r
-\r
-\r
-void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context);\r
-void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context);\r
-\r
-void wf_peer_init(freerdp_peer* client);\r
-\r
-void wf_dxgi_encode(freerdp_peer* client, UINT timeout);\r
-void wf_rfx_encode(freerdp_peer* client);\r
-\r
-BOOL wf_peer_post_connect(freerdp_peer* client);\r
-BOOL wf_peer_activate(freerdp_peer* client);\r
-\r
-void wf_peer_synchronize_event(rdpInput* input, UINT32 flags);\r
-\r
-void wf_peer_send_changes(freerdp_peer* client);\r
-\r
-void wf_detect_win_ver(void);\r
-\r
-void wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);\r
-\r
-DWORD WINAPI wf_peer_main_loop(LPVOID lpParam);\r
-\r
-\r
-#endif /* WF_PEER_H */\r
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Windows Server
+ *
+ * Copyright 2012 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_PEER_H
+#define WF_PEER_H
+
+#include "wf_interface.h"
+
+#include <freerdp/listener.h>
+
+
+
+void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context);
+void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context);
+
+void wf_peer_init(freerdp_peer* client);
+
+void wf_dxgi_encode(freerdp_peer* client, UINT timeout);
+void wf_rfx_encode(freerdp_peer* client);
+
+BOOL wf_peer_post_connect(freerdp_peer* client);
+BOOL wf_peer_activate(freerdp_peer* client);
+
+void wf_peer_synchronize_event(rdpInput* input, UINT32 flags);
+
+void wf_peer_send_changes(freerdp_peer* client);
+
+void wf_detect_win_ver(void);
+
+void wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);
+
+DWORD WINAPI wf_peer_main_loop(LPVOID lpParam);
+
+
+#endif /* WF_PEER_H */
wfi = wf_info_get_instance();
wfi->agreed_format = NULL;
- printf("Client supports the following %d formats: \n", context->num_client_formats);
+ DEBUG_WARN("Client supports the following %d formats: \n", context->num_client_formats);
for(i = 0; i < context->num_client_formats; i++)
{
//TODO: improve the way we agree on a format
(context->client_formats[i].nChannels == context->server_formats[j].nChannels) &&
(context->client_formats[i].nSamplesPerSec == context->server_formats[j].nSamplesPerSec))
{
- printf("agreed on format!\n");
+ DEBUG_WARN("agreed on format!\n");
wfi->agreed_format = (AUDIO_FORMAT*) &context->server_formats[j];
break;
}
if (wfi->agreed_format == NULL)
{
- printf("Could not agree on a audio format with the server\n");
+ DEBUG_WARN("Could not agree on a audio format with the server\n");
return;
}
break;
case WAIT_FAILED:
- printf("wf_rdpsnd_lock failed with 0x%08X\n", GetLastError());
+ DEBUG_WARN("wf_rdpsnd_lock failed with 0x%08X\n", GetLastError());
return -1;
break;
}
if (ReleaseMutex(wfi->snd_mutex) == 0)
{
- printf("wf_rdpsnd_unlock failed with 0x%08X\n", GetLastError());
+ DEBUG_WARN("wf_rdpsnd_unlock failed with 0x%08X\n", GetLastError());
return -1;
}
/* This is an unexpected error condition */
- printf("Unexpected Frame Index: Actual: %d Expected: %d\n",
+ DEBUG_WARN("Unexpected Frame Index: Actual: %d Expected: %d\n",
wfi->frame_idx, context->frame_idx + 1);
}
{
if (wf_info_lock(wfi) > 0)
{
- printf("Resetting encoder\n");
+ DEBUG_WARN("Resetting encoder\n");
if (wfi->rfx_context)
{
{
if (wfi->activePeerCount < 1)
{
-#ifndef WITH_WIN8
+#ifndef WITH_DXGI_1_2
wf_mirror_driver_activate(wfi);
#endif
ResumeThread(wfi->updateThread);
wf_update_encoder_reset(wfi);
wfi->activePeerCount++;
- printf("Activating Peer Updates: %d\n", wfi->activePeerCount);
+ DEBUG_WARN("Activating Peer Updates: %d\n", wfi->activePeerCount);
wf_info_unlock(wfi);
}
client->activated = FALSE;
wfi->activePeerCount--;
- printf("Deactivating Peer Updates: %d\n", wfi->activePeerCount);
+ DEBUG_WARN("Deactivating Peer Updates: %d\n", wfi->activePeerCount);
}
wf_info_unlock(wfi);
return 1;
}
- printf("RDPSND (WASAPI) Activated\n");
+ DEBUG_WARN("RDPSND (WASAPI) Activated\n");
CreateThread(NULL, 0, wf_rdpsnd_wasapi_thread, latestPeer, 0, NULL);
+++ /dev/null
-# FreeRDP: A Remote Desktop Protocol Implementation
-# FreeRDP X11 Server cmake build script
-#
-# Copyright 2012 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.
-
-set(MODULE_NAME "xfreerdp-server")
-set(MODULE_PREFIX "FREERDP_SERVER_X11_CONTROL")
-
-include_directories(${X11_INCLUDE_DIRS})
-include_directories("../../winpr/tools/makecert")
-
-set(${MODULE_PREFIX}_SRCS
- xf_peer.c
- xf_peer.h
- xf_input.c
- xf_input.h
- xf_encode.c
- xf_encode.h
- xf_update.c
- xf_update.h
- xf_cursor.c
- xf_cursor.h
- xf_monitors.c
- xf_monitors.h
- xf_interface.c
- xf_interface.h
- xfreerdp.h)
-
-if(WITH_SERVER_INTERFACE)
- if(SERVER_INTERFACE_SHARED)
- add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS})
- else()
- add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
- endif()
- if (WITH_LIBRARY_VERSIONING)
- set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION})
- endif()
- set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "lib")
-else()
- set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/xfreerdp.c)
- add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
- set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp-server")
-endif()
-
-set(XEXT_FEATURE_TYPE "RECOMMENDED")
-set(XEXT_FEATURE_PURPOSE "X11 extension")
-set(XEXT_FEATURE_DESCRIPTION "X11 core extensions")
-
-set(XSHM_FEATURE_TYPE "RECOMMENDED")
-set(XSHM_FEATURE_PURPOSE "X11 shared memory")
-set(XSHM_FEATURE_DESCRIPTION "X11 shared memory extension")
-
-set(XINERAMA_FEATURE_TYPE "RECOMMENDED")
-set(XINERAMA_FEATURE_PURPOSE "multi-monitor")
-set(XINERAMA_FEATURE_DESCRIPTION "X11 multi-monitor extension")
-
-set(XTEST_FEATURE_TYPE "RECOMMENDED")
-set(XTEST_FEATURE_PURPOSE "X11 input event injection")
-set(XTEST_FEATURE_DESCRIPTION "X11 input event injection extension")
-
-set(XCURSOR_FEATURE_TYPE "RECOMMENDED")
-set(XCURSOR_FEATURE_PURPOSE "cursor")
-set(XCURSOR_FEATURE_DESCRIPTION "X11 cursor extension")
-
-set(XFIXES_FEATURE_TYPE "RECOMMENDED")
-set(XFIXES_FEATURE_PURPOSE "X11 region")
-set(XFIXES_FEATURE_DESCRIPTION "X11 region fix extension")
-
-set(XRANDR_FEATURE_TYPE "RECOMMENDED")
-set(XRANDR_FEATURE_PURPOSE "X11 resize, rotate and reflect")
-set(XRANDR_FEATURE_DESCRIPTION "X11 resize, rotate and reflect extension")
-
-set(XDAMAGE_FEATURE_TYPE "RECOMMENDED")
-set(XDAMAGE_FEATURE_PURPOSE "X11 region damage")
-set(XDAMAGE_FEATURE_DESCRIPTION "X11 region damage extension")
-
-find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DESCRIPTION})
-find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION})
-find_feature(XTest ${XTEST_FEATURE_TYPE} ${XTEST_FEATURE_PURPOSE} ${XTEST_FEATURE_DESCRIPTION})
-find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION})
-find_feature(XRandR ${XRANDR_FEATURE_TYPE} ${XRANDR_FEATURE_PURPOSE} ${XRANDR_FEATURE_DESCRIPTION})
-find_feature(Xdamage ${XDAMAGE_FEATURE_TYPE} ${XDAMAGE_FEATURE_PURPOSE} ${XDAMAGE_FEATURE_DESCRIPTION})
-find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSOR_FEATURE_DESCRIPTION})
-find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION})
-
-if(WITH_XSHM)
- add_definitions(-DWITH_XSHM)
- include_directories(${XSHM_INCLUDE_DIRS})
-endif()
-
-if(WITH_XEXT)
- add_definitions(-DWITH_XEXT)
- include_directories(${XEXT_INCLUDE_DIRS})
- set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XEXT_LIBRARIES})
-endif()
-
-if(WITH_XINERAMA)
- add_definitions(-DWITH_XINERAMA)
- include_directories(${XINERAMA_INCLUDE_DIRS})
- set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XINERAMA_LIBRARIES})
-endif()
-
-if(WITH_XCURSOR)
- add_definitions(-DWITH_XCURSOR)
- include_directories(${XCURSOR_INCLUDE_DIRS})
- set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XCURSOR_LIBRARIES})
-endif()
-
-if(WITH_XDAMAGE)
- add_definitions(-DWITH_XDAMAGE)
- include_directories(${XDAMAGE_INCLUDE_DIRS})
- set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XDAMAGE_LIBRARIES})
-endif()
-
-if(WITH_XFIXES)
- add_definitions(-DWITH_XFIXES)
- include_directories(${XFIXES_INCLUDE_DIRS})
- target_link_libraries(${MODULE_NAME} ${XFIXES_LIBRARIES})
- set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XFIXES_LIBRARIES})
-endif()
-
-if(WITH_XTEST)
- add_definitions(-DWITH_XTEST)
- include_directories(${XTEST_INCLUDE_DIRS})
- set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XTEST_LIBRARIES})
-endif()
-
-if(WITH_XRANDR)
- add_definitions(-DWITH_XRANDR)
- include_directories(${XRANDR_INCLUDE_DIRS})
- set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRANDR_LIBRARIES})
-endif()
-
-set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${X11_LIBRARIES})
-
-set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
- MONOLITHIC ${MONOLITHIC_BUILD}
- MODULE freerdp
- MODULES freerdp-core freerdp-common freerdp-codec freerdp-primitives freerdp-utils freerdp-gdi freerdp-crypto freerdp-locale)
-
-set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr)
-
-set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr-makecert-tool)
-
-target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
-
-if(WITH_SERVER_INTERFACE)
- install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries)
- add_subdirectory(cli)
-else()
- install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server)
-endif()
-
-set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/X11")
-
+++ /dev/null
-
-set(FREERDP_SERVER_NAME "xfreerdp-server")
-set(FREERDP_SERVER_PLATFORM "X11")
-set(FREERDP_SERVER_VENDOR "FreeRDP")
+++ /dev/null
-# FreeRDP: A Remote Desktop Protocol Implementation
-# FreeRDP X11 cmake build script
-#
-# Copyright 2012 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.
-
-set(MODULE_NAME "xfreerdp-server-cli")
-set(MODULE_PREFIX "FREERDP_SERVER_X11")
-
-include_directories(..)
-
-set(${MODULE_PREFIX}_SRCS
- xfreerdp.c)
-
-add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
-set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp-server" RUNTIME_OUTPUT_DIRECTORY "..")
-
-set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} xfreerdp-server)
-
-target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
-
-install(TARGETS ${MODULE_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server)
-
-set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/X11")
-
+++ /dev/null
------BEGIN CERTIFICATE-----
-MIICyzCCAbOgAwIBAgIJANbqtAWwlQZuMA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV
-BAMTB0ZyZWVSRFAwHhcNMDkxMDI5MDA0MTQ5WhcNMDkxMTI4MDA0MTQ5WjASMRAw
-DgYDVQQDEwdGcmVlUkRQMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
-q7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1TptzXTcmfDrDslTGwcEY
-hTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2SXvTiaV26VPPxddGb
-o6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJLd2SU4ItWHj8zjz1f
-eGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsjgvz4yP7I3TL8+GsN
-MjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdymrulJSIhoOVfKkwi
-ptTe43FgwxVRIygJP9HjHQIDAQABoyQwIjATBgNVHSUEDDAKBggrBgEFBQcDATAL
-BgNVHQ8EBAMCBDAwDQYJKoZIhvcNAQEFBQADggEBAIOdEDhOX2kbl02znltd9hCr
-nV4kRPKm979RKwBNkrEuwYSlcsjAHg5MZ5itH3wFOUo2s5pjt7/vMOAg+6rOBbIa
-nqr22/gKBtOmuaJLG1yjxDC2vfez7f3B26pKgxa/krM8oxiFdT9n8QbdxdkN7/D9
-3RLU/aCfgrMzXxRus7eq3kR00jnSs6ggnAfE1E9gric3vFgr1wCzdcriRXmXDfUb
-hRq+4VG+ZWk16TwCofV5GVU39XWCv5HNO2swAdjkNXgI5e3tQbV3wWLZLqqYzBco
-iWulAXtoCGmE81+u1Ms7hLLzpXitLZSGPu1r+sDdkKPLCmOvkAaljDQ4nBz7fIA=
------END CERTIFICATE-----
+++ /dev/null
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1Tptz
-XTcmfDrDslTGwcEYhTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2S
-XvTiaV26VPPxddGbo6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJL
-d2SU4ItWHj8zjz1feGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsj
-gvz4yP7I3TL8+GsNMjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdy
-mrulJSIhoOVfKkwiptTe43FgwxVRIygJP9HjHQIDAQABAoIBAAVv5K54xtc1JtBR
-1lfdPbSqDlnjx8aOnVIPg5TnqMp3sR8jBt0NsPc/+RA9ZOmfjoIxFAEJaZ9zSDJC
-5BqmnxC5R1mfCQkSd2haQ+4pdFvWyrv4Bblh8YU6hXrJGn0LfO0KlIcywtAvKpsi
-LtTyZkWmaW2HeF/+pO32jYygw38R1wd8Tl6GwjOXwTF6lFACJXOT4YAzcfp3FKSB
-AiKBIGuMzozoSND7KPFNRrhGhNumJpdS5A8Fb8D2c/ZMv6Cq5IbwOgTfKun+Bz+s
-mFbnzeb1uWRqQbsVXOBBW/zHfuG3SU5qeZsaAyuu4DTy+LE1oAHF9uhBSHuT5C6i
-vCJ8A8ECgYEA1iaOmiEJYBrs25iAc4SjCKqhY0mwR3wtu3I06vmgUoML5fhPMv36
-SvYQIqDyNw3p7TE6mZtw9+G+kK3PqhuJhogwSwg0a6o51RdKnhXH3/68oNWtKCLC
-1AmR8q/Gd3FwAR3b49CuOIZ9uOiJrc/ejzKdFEJTDR1/TX1frWfZznECgYEAzUiz
-XxFf7YrGel7JgmfRD2eZRYngOoteFlg5Tee42UjeAY2Pt2aiDLk+2TqQEdI9+Xg7
-LcFdBqcSNd8bh33xSzgNthIkX+lTDzx0SmKGfyxfFBJcY8nzsLvvnNt3YeuMeaJQ
-CPszwoZ0jcD46jTCjbrKhaLyEWmUkDp1O71NTW0CgYAXKF49Xpsz8FVyvcAOPeaf
-dkwzf3F3mX8ciRId4taqdY9g1AREgGCDoK5IAF2RBIkqZCtxFvUVaS0BWjpdq9Ko
-YKvQQVfh2KueVoF0LOjLWTGutsydzXyCD3Lf6pAstHCnPkJcFWHxrOGFkGfrCtKH
-a7K+0RlIDsuIZqllCBjukQKBgA31+MTpYJW+D1t5IMkumEgs6n6RLt+sZLyuSU9k
-B+03CGogn3qAj1rAKmcJlYywuKhDpfqpoNL3/8QMJUokpYlRCZWtTC39pzltCheY
-9b6mXNz3lrLupBUL4vLO9iKBq28GO90wgEelbz3ItuTuq6CJ6IYIG+BVRtY8M4bZ
-i+1NAoGANXZjYnJYDnh8Je9SDxDSc5byzK7ddkQoId64RCIfNHqNKH63P81vjgnH
-YBIPtagY75ZVVNxujCF7m8Rety+d8tEFwfQKDin2EVI7PD2rOJra385/izp7HuBR
-vqxvLzG9Xv3cNOU2l7PttVw4Pa2i5E37atKi3V3Zp2kMW+KaKPQ=
------END RSA PRIVATE KEY-----
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * X11 Server Cursor
- *
- * Copyright 2013 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 <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#ifdef WITH_XCURSOR
-#include <X11/Xcursor/Xcursor.h>
-#endif
-
-#ifdef WITH_XFIXES
-#include <X11/extensions/Xfixes.h>
-#endif
-
-#include <winpr/crt.h>
-
-#include "xf_cursor.h"
-
-int xf_cursor_init(xfInfo* xfi)
-{
-#ifdef WITH_XFIXES
- int event;
- int error;
-
- if (!XFixesQueryExtension(xfi->display, &event, &error))
- {
- fprintf(stderr, "XFixesQueryExtension failed\n");
- return -1;
- }
-
- xfi->xfixes_notify_event = event + XFixesCursorNotify;
-
- XFixesSelectCursorInput(xfi->display, DefaultRootWindow(xfi->display), XFixesDisplayCursorNotifyMask);
-#endif
-
- return 0;
-}
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * X11 RemoteFX Encoder
- *
- * Copyright 2011 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 <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#include <sys/select.h>
-#include <sys/signal.h>
-
-#include <winpr/crt.h>
-
-#include "xf_encode.h"
-
-XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height)
-{
- XImage* image;
- xfInfo* xfi = xfp->info;
-
- if (xfi->use_xshm)
- {
- XCopyArea(xfi->display, xfi->root_window, xfi->fb_pixmap, xfi->xdamage_gc, x, y, width, height, x, y);
- image = xfi->fb_image;
- }
- else
- {
- image = XGetImage(xfi->display, xfi->root_window, x, y, width, height, AllPlanes, ZPixmap);
- }
-
- return image;
-}
-
-void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height)
-{
- XRectangle region;
- xfInfo* xfi = xfp->info;
-
- region.x = x;
- region.y = y;
- region.width = width;
- region.height = height;
-
-#ifdef WITH_XFIXES
- XFixesSetRegion(xfi->display, xfi->xdamage_region, ®ion, 1);
- XDamageSubtract(xfi->display, xfi->xdamage, xfi->xdamage_region, None);
-#endif
-}
-
-int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height)
-{
- wStream* s;
- BYTE* data;
- xfInfo* xfi;
- RFX_RECT rect;
- XImage* image;
- rdpUpdate* update;
- xfPeerContext* xfp;
- SURFACE_BITS_COMMAND* cmd;
-
- update = client->update;
- xfp = (xfPeerContext*) client->context;
- cmd = &update->surface_bits_command;
- xfi = xfp->info;
-
- if (width * height <= 0)
- {
- cmd->bitmapDataLength = 0;
- return -1;
- }
-
- s = xfp->s;
- Stream_Clear(s);
- Stream_SetPosition(s, 0);
-
- if (xfi->use_xshm)
- {
- /**
- * Passing an offset source rectangle to rfx_compose_message()
- * leads to protocol errors, so offset the data pointer instead.
- */
-
- rect.x = 0;
- rect.y = 0;
- rect.width = width;
- rect.height = height;
-
- image = xf_snapshot(xfp, x, y, width, height);
-
- data = (BYTE*) image->data;
- data = &data[(y * image->bytes_per_line) + (x * image->bits_per_pixel / 8)];
-
- rfx_compose_message(xfp->rfx_context, s, &rect, 1, data,
- width, height, image->bytes_per_line);
-
- cmd->destLeft = x;
- cmd->destTop = y;
- cmd->destRight = x + width;
- cmd->destBottom = y + height;
- }
- else
- {
- rect.x = 0;
- rect.y = 0;
- rect.width = width;
- rect.height = height;
-
- image = xf_snapshot(xfp, x, y, width, height);
-
- data = (BYTE*) image->data;
-
- rfx_compose_message(xfp->rfx_context, s, &rect, 1, data,
- width, height, image->bytes_per_line);
-
- cmd->destLeft = x;
- cmd->destTop = y;
- cmd->destRight = x + width;
- cmd->destBottom = y + height;
-
- XDestroyImage(image);
- }
-
- cmd->bpp = 32;
- cmd->codecID = client->settings->RemoteFxCodecId;
- cmd->width = width;
- cmd->height = height;
- cmd->bitmapDataLength = Stream_GetPosition(s);
- cmd->bitmapData = Stream_Buffer(s);
-
- return 0;
-}
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * X11 Server Input
- *
- * Copyright 2011 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 <X11/Xlib.h>
-
-#include <freerdp/locale/keyboard.h>
-
-#include <winpr/crt.h>
-#include <winpr/input.h>
-
-#include "xf_peer.h"
-
-#include "xf_input.h"
-
-void xf_input_synchronize_event(rdpInput* input, UINT32 flags)
-{
- fprintf(stderr, "Client sent a synchronize event (flags:0x%X)\n", flags);
-}
-
-void xf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
-{
-#ifdef WITH_XTEST
- DWORD vkcode;
- DWORD keycode;
- BOOL extended = FALSE;
- xfPeerContext* xfp = (xfPeerContext*) input->context;
- xfInfo* xfi = xfp->info;
-
- if (flags & KBD_FLAGS_EXTENDED)
- extended = TRUE;
-
- if (extended)
- code |= KBDEXT;
-
- vkcode = GetVirtualKeyCodeFromVirtualScanCode(code, 4);
- keycode = GetKeycodeFromVirtualKeyCode(vkcode, KEYCODE_TYPE_EVDEV);
-
- if (keycode != 0)
- {
- XTestGrabControl(xfi->display, True);
-
- if (flags & KBD_FLAGS_DOWN)
- XTestFakeKeyEvent(xfi->display, keycode, True, 0);
- else if (flags & KBD_FLAGS_RELEASE)
- XTestFakeKeyEvent(xfi->display, keycode, False, 0);
-
- XTestGrabControl(xfi->display, False);
- }
-#endif
-}
-
-void xf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
-{
- fprintf(stderr, "Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code);
-}
-
-void xf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
-{
-#ifdef WITH_XTEST
- xfPeerContext* xfp = (xfPeerContext*) input->context;
- int button = 0;
- BOOL down = FALSE;
- xfInfo* xfi = xfp->info;
-
- XTestGrabControl(xfi->display, True);
-
- if (flags & PTR_FLAGS_WHEEL)
- {
- BOOL negative = FALSE;
-
- if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
- negative = TRUE;
-
- button = (negative) ? 5 : 4;
-
- XTestFakeButtonEvent(xfi->display, button, True, 0);
- XTestFakeButtonEvent(xfi->display, button, False, 0);
- }
- else
- {
- if (flags & PTR_FLAGS_MOVE)
- XTestFakeMotionEvent(xfi->display, 0, x, y, 0);
-
- if (flags & PTR_FLAGS_BUTTON1)
- button = 1;
- else if (flags & PTR_FLAGS_BUTTON2)
- button = 3;
- else if (flags & PTR_FLAGS_BUTTON3)
- button = 2;
-
- if (flags & PTR_FLAGS_DOWN)
- down = TRUE;
-
- if (button != 0)
- XTestFakeButtonEvent(xfi->display, button, down, 0);
- }
-
- XTestGrabControl(xfi->display, False);
-#endif
-}
-
-void xf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
-{
-#ifdef WITH_XTEST
- xfPeerContext* xfp = (xfPeerContext*) input->context;
- int button = 0;
- BOOL down = FALSE;
- xfInfo* xfi = xfp->info;
-
- XTestGrabControl(xfi->display, True);
- XTestFakeMotionEvent(xfi->display, 0, x, y, CurrentTime);
-
- if (flags & PTR_XFLAGS_BUTTON1)
- button = 8;
- else if (flags & PTR_XFLAGS_BUTTON2)
- button = 9;
-
- if (flags & PTR_XFLAGS_DOWN)
- down = TRUE;
-
- if (button != 0)
- XTestFakeButtonEvent(xfi->display, button, down, 0);
-
- XTestGrabControl(xfi->display, False);
-#endif
-}
-
-void xf_input_register_callbacks(rdpInput* input)
-{
- input->SynchronizeEvent = xf_input_synchronize_event;
- input->KeyboardEvent = xf_input_keyboard_event;
- input->UnicodeKeyboardEvent = xf_input_unicode_keyboard_event;
- input->MouseEvent = xf_input_mouse_event;
- input->ExtendedMouseEvent = xf_input_extended_mouse_event;
-}
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * X11 Server Input
- *
- * Copyright 2011 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 __XF_INPUT_H
-#define __XF_INPUT_H
-
-#include <pthread.h>
-
-#include "xfreerdp.h"
-
-void xf_input_synchronize_event(rdpInput* input, UINT32 flags);
-void xf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code);
-void xf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code);
-void xf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
-void xf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
-void xf_input_register_callbacks(rdpInput* input);
-
-#endif /* __XF_INPUT_H */
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * FreeRDP X11 Server Interface
- *
- * Copyright 2013 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.
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <sys/select.h>
-#include <sys/signal.h>
-
-#include "xf_peer.h"
-#include "xfreerdp.h"
-
-#include "xf_interface.h"
-
-void* xf_server_thread(void* param)
-{
- int i;
- int fds;
- int max_fds;
- int rcount;
- void* rfds[32];
- fd_set rfds_set;
- xfServer* server;
- freerdp_listener* listener;
-
- server = (xfServer*) param;
- listener = server->listener;
-
- while (1)
- {
- rcount = 0;
-
- ZeroMemory(rfds, sizeof(rfds));
- if (listener->GetFileDescriptor(listener, rfds, &rcount) != TRUE)
- {
- fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
- break;
- }
-
- max_fds = 0;
- FD_ZERO(&rfds_set);
-
- for (i = 0; i < rcount; i++)
- {
- fds = (int)(long)(rfds[i]);
-
- if (fds > max_fds)
- max_fds = fds;
-
- FD_SET(fds, &rfds_set);
- }
-
- if (max_fds == 0)
- break;
-
- if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1)
- {
- /* these are not really errors */
- if (!((errno == EAGAIN) ||
- (errno == EWOULDBLOCK) ||
- (errno == EINPROGRESS) ||
- (errno == EINTR))) /* signal occurred */
- {
- fprintf(stderr, "select failed\n");
- break;
- }
- }
-
- if (listener->CheckFileDescriptor(listener) != TRUE)
- {
- fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
- break;
- }
- }
-
- ExitThread(0);
-
- return NULL;
-}
-
-int freerdp_server_global_init()
-{
- /*
- * ignore SIGPIPE, otherwise an SSL_write failure could crash the server
- */
- signal(SIGPIPE, SIG_IGN);
-
- return 0;
-}
-
-int freerdp_server_global_uninit()
-{
- return 0;
-}
-
-int freerdp_server_start(xfServer* server)
-{
- assert(NULL != server);
-
- server->thread = NULL;
- if (server->listener->Open(server->listener, NULL, 3389))
- {
- server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
- xf_server_thread, (void*) server, 0, NULL);
- }
-
- return 0;
-}
-
-int freerdp_server_stop(xfServer* server)
-{
- if (server->thread)
- {
- /* ATTENTION: Terminate thread kills a thread, assure
- * no resources are allocated during thread execution,
- * as they will not be freed! */
- TerminateThread(server->thread, 0);
- WaitForSingleObject(server->thread, INFINITE);
- CloseHandle(server->thread);
-
- server->listener->Close(server->listener);
- }
- return 0;
-}
-
-HANDLE freerdp_server_get_thread(xfServer* server)
-{
- return server->thread;
-}
-
-xfServer* freerdp_server_new(int argc, char** argv)
-{
- xfServer* server;
-
- server = (xfServer*) malloc(sizeof(xfServer));
-
- if (server)
- {
- server->listener = freerdp_listener_new();
- server->listener->PeerAccepted = xf_peer_accepted;
- }
-
- return server;
-}
-
-void freerdp_server_free(xfServer* server)
-{
- if (server)
- {
- freerdp_listener_free(server->listener);
- free(server);
- }
-}
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * FreeRDP X11 Server Interface
- *
- * Copyright 2013 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 XFREERDP_SERVER_INTERFACE_H
-#define XFREERDP_SERVER_INTERFACE_H
-
-#include <winpr/crt.h>
-
-#include <freerdp/api.h>
-#include <freerdp/freerdp.h>
-
-typedef struct xf_info xfInfo;
-typedef struct xf_server xfServer;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Server Interface
- */
-
-FREERDP_API int freerdp_server_global_init();
-FREERDP_API int freerdp_server_global_uninit();
-
-FREERDP_API int freerdp_server_start(xfServer* server);
-FREERDP_API int freerdp_server_stop(xfServer* server);
-
-FREERDP_API HANDLE freerdp_server_get_thread(xfServer* server);
-
-FREERDP_API xfServer* freerdp_server_new(int argc, char** argv);
-FREERDP_API void freerdp_server_free(xfServer* server);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* XFREERDP_SERVER_INTERFACE_H */
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * X11 Server Monitors
- *
- * Copyright 2013 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 <winpr/crt.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#ifdef WITH_XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-
-#include "xf_monitors.h"
-
-int xf_list_monitors(xfInfo* xfi)
-{
-#ifdef WITH_XINERAMAZ
- int i, nmonitors = 0;
- int ignored, ignored2;
- XineramaScreenInfo* screen = NULL;
-
- if (XineramaQueryExtension(xfi->display, &ignored, &ignored2))
- {
- if (XineramaIsActive(xfi->display))
- {
- screen = XineramaQueryScreens(xfi->display, &nmonitors);
-
- for (i = 0; i < nmonitors; i++)
- {
- printf(" %s [%d] %dx%d\t+%d+%d\n",
- (i == 0) ? "*" : " ", i,
- screen[i].width, screen[i].height,
- screen[i].x_org, screen[i].y_org);
- }
-
- XFree(screen);
- }
- }
-#else
- Screen* screen;
-
- screen = ScreenOfDisplay(xfi->display, DefaultScreen(xfi->display));
- printf(" * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen), HeightOfScreen(screen), 0, 0);
-#endif
-
- return 0;
-}
-
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * X11 Peer
- *
- * Copyright 2011 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 <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <sys/select.h>
-
-#include <winpr/crt.h>
-#include <winpr/file.h>
-#include <winpr/path.h>
-#include <winpr/synch.h>
-#include <winpr/thread.h>
-
-#include <freerdp/freerdp.h>
-#include <freerdp/codec/color.h>
-#include <freerdp/locale/keyboard.h>
-
-#include "xf_input.h"
-#include "xf_cursor.h"
-#include "xf_encode.h"
-#include "xf_update.h"
-#include "xf_monitors.h"
-
-#include <winpr/tools/makecert.h>
-
-#include "xf_peer.h"
-
-#ifdef WITH_XDAMAGE
-
-void xf_xdamage_init(xfInfo* xfi)
-{
- int damage_event;
- int damage_error;
- int major, minor;
- XGCValues values;
-
- if (XDamageQueryExtension(xfi->display, &damage_event, &damage_error) == 0)
- {
- fprintf(stderr, "XDamageQueryExtension failed\n");
- return;
- }
-
- XDamageQueryVersion(xfi->display, &major, &minor);
-
- if (XDamageQueryVersion(xfi->display, &major, &minor) == 0)
- {
- fprintf(stderr, "XDamageQueryVersion failed\n");
- return;
- }
- else if (major < 1)
- {
- fprintf(stderr, "XDamageQueryVersion failed: major:%d minor:%d\n", major, minor);
- return;
- }
-
- xfi->xdamage_notify_event = damage_event + XDamageNotify;
- xfi->xdamage = XDamageCreate(xfi->display, xfi->root_window, XDamageReportDeltaRectangles);
-
- if (xfi->xdamage == None)
- {
- fprintf(stderr, "XDamageCreate failed\n");
- return;
- }
-
-#ifdef WITH_XFIXES
- xfi->xdamage_region = XFixesCreateRegion(xfi->display, NULL, 0);
-
- if (xfi->xdamage_region == None)
- {
- fprintf(stderr, "XFixesCreateRegion failed\n");
- XDamageDestroy(xfi->display, xfi->xdamage);
- xfi->xdamage = None;
- return;
- }
-#endif
-
- values.subwindow_mode = IncludeInferiors;
- xfi->xdamage_gc = XCreateGC(xfi->display, xfi->root_window, GCSubwindowMode, &values);
- XSetFunction(xfi->display, xfi->xdamage_gc, GXcopy);
-}
-
-#endif
-
-int xf_xshm_init(xfInfo* xfi)
-{
- Bool pixmaps;
- int major, minor;
-
- if (XShmQueryExtension(xfi->display) != False)
- {
- XShmQueryVersion(xfi->display, &major, &minor, &pixmaps);
-
- if (pixmaps != True)
- {
- fprintf(stderr, "XShmQueryVersion failed\n");
- return -1;
- }
- }
- else
- {
- fprintf(stderr, "XShmQueryExtension failed\n");
- return -1;
- }
-
- xfi->fb_shm_info.shmid = -1;
- xfi->fb_shm_info.shmaddr = (char*) -1;
-
- xfi->fb_image = XShmCreateImage(xfi->display, xfi->visual, xfi->depth,
- ZPixmap, NULL, &(xfi->fb_shm_info), xfi->width, xfi->height);
-
- if (!xfi->fb_image)
- {
- fprintf(stderr, "XShmCreateImage failed\n");
- return -1;
- }
-
- xfi->fb_shm_info.shmid = shmget(IPC_PRIVATE,
- xfi->fb_image->bytes_per_line * xfi->fb_image->height, IPC_CREAT | 0600);
-
- if (xfi->fb_shm_info.shmid == -1)
- {
- fprintf(stderr, "shmget failed\n");
- return -1;
- }
-
- xfi->fb_shm_info.readOnly = False;
- xfi->fb_shm_info.shmaddr = shmat(xfi->fb_shm_info.shmid, 0, 0);
- xfi->fb_image->data = xfi->fb_shm_info.shmaddr;
-
- if (xfi->fb_shm_info.shmaddr == ((char*) -1))
- {
- fprintf(stderr, "shmat failed\n");
- return -1;
- }
-
- XShmAttach(xfi->display, &(xfi->fb_shm_info));
- XSync(xfi->display, False);
-
- shmctl(xfi->fb_shm_info.shmid, IPC_RMID, 0);
-
- fprintf(stderr, "display: %p root_window: %p width: %d height: %d depth: %d\n",
- xfi->display, (void*) xfi->root_window, xfi->fb_image->width, xfi->fb_image->height, xfi->fb_image->depth);
-
- xfi->fb_pixmap = XShmCreatePixmap(xfi->display,
- xfi->root_window, xfi->fb_image->data, &(xfi->fb_shm_info),
- xfi->fb_image->width, xfi->fb_image->height, xfi->fb_image->depth);
-
- return 0;
-}
-
-void xf_info_free(xfInfo *info)
-{
- assert(NULL != info);
-
- if (info->display)
- XCloseDisplay(info->display);
-
- freerdp_clrconv_free(info->clrconv);
- free(info);
-}
-
-xfInfo* xf_info_init()
-{
- int i;
- xfInfo* xfi;
- int pf_count;
- int vi_count;
- XVisualInfo* vi;
- XVisualInfo* vis;
- XVisualInfo template;
- XPixmapFormatValues* pf;
- XPixmapFormatValues* pfs;
-
- xfi = (xfInfo*) malloc(sizeof(xfInfo));
- ZeroMemory(xfi, sizeof(xfInfo));
-
- /**
- * Recent X11 servers drop support for shared pixmaps
- * To see if your X11 server supports shared pixmaps, use:
- * xdpyinfo -ext MIT-SHM | grep "shared pixmaps"
- */
- xfi->use_xshm = TRUE;
-
- setenv("DISPLAY", ":0", 1); /* Set DISPLAY variable if not already set */
-
- if (!XInitThreads())
- fprintf(stderr, "warning: XInitThreads() failure\n");
-
- xfi->display = XOpenDisplay(NULL);
-
- if (!xfi->display)
- {
- fprintf(stderr, "failed to open display: %s\n", XDisplayName(NULL));
- exit(1);
- }
-
- xf_list_monitors(xfi);
-
- xfi->xfds = ConnectionNumber(xfi->display);
- xfi->number = DefaultScreen(xfi->display);
- xfi->screen = ScreenOfDisplay(xfi->display, xfi->number);
- xfi->depth = DefaultDepthOfScreen(xfi->screen);
- xfi->width = WidthOfScreen(xfi->screen);
- xfi->height = HeightOfScreen(xfi->screen);
- xfi->root_window = DefaultRootWindow(xfi->display);
-
- pfs = XListPixmapFormats(xfi->display, &pf_count);
-
- if (!pfs)
- {
- fprintf(stderr, "XListPixmapFormats failed\n");
- exit(1);
- }
-
- for (i = 0; i < pf_count; i++)
- {
- pf = pfs + i;
-
- if (pf->depth == xfi->depth)
- {
- xfi->bpp = pf->bits_per_pixel;
- xfi->scanline_pad = pf->scanline_pad;
- break;
- }
- }
- XFree(pfs);
-
- ZeroMemory(&template, sizeof(template));
- template.class = TrueColor;
- template.screen = xfi->number;
-
- vis = XGetVisualInfo(xfi->display, VisualClassMask | VisualScreenMask, &template, &vi_count);
-
- if (!vis)
- {
- fprintf(stderr, "XGetVisualInfo failed\n");
- exit(1);
- }
-
- for (i = 0; i < vi_count; i++)
- {
- vi = vis + i;
-
- if (vi->depth == xfi->depth)
- {
- xfi->visual = vi->visual;
- break;
- }
- }
- XFree(vis);
-
- xfi->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA | CLRCONV_INVERT);
-
- XSelectInput(xfi->display, xfi->root_window, SubstructureNotifyMask);
-
- if (xfi->use_xshm)
- {
- if (xf_xshm_init(xfi) < 0)
- xfi->use_xshm = FALSE;
- }
-
- if (xfi->use_xshm)
- printf("Using X Shared Memory Extension (XShm)\n");
-
-#ifdef WITH_XDAMAGE
- xf_xdamage_init(xfi);
-#endif
-
- xf_cursor_init(xfi);
-
- xfi->bytesPerPixel = 4;
- xfi->activePeerCount = 0;
-
- freerdp_keyboard_init(0);
-
- return xfi;
-}
-
-void xf_peer_context_new(freerdp_peer* client, xfPeerContext* context)
-{
- context->info = xf_info_init();
- context->rfx_context = rfx_context_new(TRUE);
- context->rfx_context->mode = RLGR3;
- context->rfx_context->width = context->info->width;
- context->rfx_context->height = context->info->height;
-
- rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
-
- context->s = Stream_New(NULL, 65536);
- Stream_Clear(context->s);
-
- context->updateReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- context->updateSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-}
-
-void xf_peer_context_free(freerdp_peer* client, xfPeerContext* context)
-{
- if (context)
- {
- xf_info_free(context->info);
-
- CloseHandle(context->updateReadyEvent);
- CloseHandle(context->updateSentEvent);
-
- Stream_Free(context->s, TRUE);
- rfx_context_free(context->rfx_context);
- }
-}
-
-void xf_peer_init(freerdp_peer* client)
-{
- xfInfo* xfi;
- xfPeerContext* xfp;
-
- client->ContextSize = sizeof(xfPeerContext);
- client->ContextNew = (psPeerContextNew) xf_peer_context_new;
- client->ContextFree = (psPeerContextFree) xf_peer_context_free;
- freerdp_peer_context_new(client);
-
- xfp = (xfPeerContext*) client->context;
-
- xfp->fps = 16;
- xfi = xfp->info;
-
- xfp->mutex = CreateMutex(NULL, FALSE, NULL);
-}
-
-void xf_peer_send_update(freerdp_peer* client)
-{
- rdpUpdate* update;
- SURFACE_BITS_COMMAND* cmd;
-
- update = client->update;
- cmd = &update->surface_bits_command;
-
- if (cmd->bitmapDataLength)
- update->SurfaceBits(update->context, cmd);
-}
-
-BOOL xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount)
-{
- int fds;
- HANDLE event;
- xfPeerContext* xfp = (xfPeerContext*) client->context;
-
- event = xfp->updateReadyEvent;
- fds = GetEventFileDescriptor(event);
- rfds[*rcount] = (void*) (long) fds;
- (*rcount)++;
-
- return TRUE;
-}
-
-BOOL xf_peer_check_fds(freerdp_peer* client)
-{
- xfInfo* xfi;
- xfPeerContext* xfp;
-
- xfp = (xfPeerContext*) client->context;
- xfi = xfp->info;
-
- if (WaitForSingleObject(xfp->updateReadyEvent, 0) == WAIT_OBJECT_0)
- {
- if (!xfp->activated)
- return TRUE;
-
- xf_peer_send_update(client);
-
- ResetEvent(xfp->updateReadyEvent);
- SetEvent(xfp->updateSentEvent);
- }
-
- return TRUE;
-}
-
-BOOL xf_peer_capabilities(freerdp_peer* client)
-{
- return TRUE;
-}
-
-BOOL xf_peer_post_connect(freerdp_peer* client)
-{
- xfInfo* xfi;
- xfPeerContext* xfp;
-
- xfp = (xfPeerContext*) client->context;
- xfi = (xfInfo*) xfp->info;
-
- /**
- * This callback is called when the entire connection sequence is done, i.e. we've received the
- * Font List PDU from the client and sent out the Font Map PDU.
- * The server may start sending graphics output and receiving keyboard/mouse input after this
- * callback returns.
- */
- fprintf(stderr, "Client %s is activated", client->hostname);
- if (client->settings->AutoLogonEnabled)
- {
- fprintf(stderr, " and wants to login automatically as %s\\%s",
- client->settings->Domain ? client->settings->Domain : "",
- client->settings->Username);
-
- /* A real server may perform OS login here if NLA is not executed previously. */
- }
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Client requested desktop: %dx%dx%d\n",
- client->settings->DesktopWidth, client->settings->DesktopHeight, client->settings->ColorDepth);
-
- if (!client->settings->RemoteFxCodec)
- {
- fprintf(stderr, "Client does not support RemoteFX\n");
- return FALSE;
- }
-
- /* A real server should tag the peer as activated here and start sending updates in main loop. */
-
- client->settings->DesktopWidth = xfi->width;
- client->settings->DesktopHeight = xfi->height;
-
- client->update->DesktopResize(client->update->context);
-
- /* Return FALSE here would stop the execution of the peer main loop. */
- return TRUE;
-}
-
-BOOL xf_peer_activate(freerdp_peer* client)
-{
- xfPeerContext* xfp = (xfPeerContext*) client->context;
-
- rfx_context_reset(xfp->rfx_context);
- xfp->activated = TRUE;
-
- xfp->info->activePeerCount++;
-
- xfp->monitorThread = CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE) xf_update_thread, (void*) client, 0, NULL);
-
- return TRUE;
-}
-
-const char* makecert_argv[4] =
-{
- "makecert",
- "-rdp",
- "-live",
- "-silent"
-};
-
-int makecert_argc = (sizeof(makecert_argv) / sizeof(char*));
-
-int xf_generate_certificate(rdpSettings* settings)
-{
- char* server_file_path;
- MAKECERT_CONTEXT* context;
-
- server_file_path = GetCombinedPath(settings->ConfigPath, "server");
-
- if (!PathFileExistsA(server_file_path))
- CreateDirectoryA(server_file_path, 0);
-
- settings->CertificateFile = GetCombinedPath(server_file_path, "server.crt");
- settings->PrivateKeyFile = GetCombinedPath(server_file_path, "server.key");
-
- if ((!PathFileExistsA(settings->CertificateFile)) ||
- (!PathFileExistsA(settings->PrivateKeyFile)))
- {
- context = makecert_context_new();
-
- makecert_context_process(context, makecert_argc, (char**) makecert_argv);
-
- makecert_context_set_output_file_name(context, "server");
-
- if (!PathFileExistsA(settings->CertificateFile))
- makecert_context_output_certificate_file(context, server_file_path);
-
- if (!PathFileExistsA(settings->PrivateKeyFile))
- makecert_context_output_private_key_file(context, server_file_path);
-
- makecert_context_free(context);
- }
-
- free(server_file_path);
-
- return 0;
-}
-
-static void* xf_peer_main_loop(void* arg)
-{
- int i;
- int fds;
- int max_fds;
- int rcount;
- void* rfds[32];
- fd_set rfds_set;
- rdpSettings* settings;
- xfPeerContext* xfp;
- struct timeval timeout;
- freerdp_peer* client = (freerdp_peer*) arg;
-
- assert(NULL != client);
-
- ZeroMemory(rfds, sizeof(rfds));
- ZeroMemory(&timeout, sizeof(struct timeval));
-
- fprintf(stderr, "We've got a client %s\n", client->hostname);
-
- xf_peer_init(client);
- xfp = (xfPeerContext*) client->context;
- settings = client->settings;
-
- xf_generate_certificate(settings);
-
- settings->RemoteFxCodec = TRUE;
- settings->ColorDepth = 32;
-
- settings->NlaSecurity = FALSE;
- settings->TlsSecurity = TRUE;
- settings->RdpSecurity = FALSE;
-
- client->Capabilities = xf_peer_capabilities;
- client->PostConnect = xf_peer_post_connect;
- client->Activate = xf_peer_activate;
-
- xf_input_register_callbacks(client->input);
-
- client->Initialize(client);
-
- while (1)
- {
- rcount = 0;
-
- if (client->GetFileDescriptor(client, rfds, &rcount) != TRUE)
- {
- fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
- break;
- }
-
- if (xf_peer_get_fds(client, rfds, &rcount) != TRUE)
- {
- fprintf(stderr, "Failed to get xfreerdp file descriptor\n");
- break;
- }
-
- max_fds = 0;
- FD_ZERO(&rfds_set);
-
- for (i = 0; i < rcount; i++)
- {
- fds = (int)(long)(rfds[i]);
-
- if (fds > max_fds)
- max_fds = fds;
-
- FD_SET(fds, &rfds_set);
- }
-
- if (max_fds == 0)
- break;
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 100;
-
- if (select(max_fds + 1, &rfds_set, NULL, NULL, &timeout) == -1)
- {
- /* these are not really errors */
- if (!((errno == EAGAIN) ||
- (errno == EWOULDBLOCK) ||
- (errno == EINPROGRESS) ||
- (errno == EINTR))) /* signal occurred */
- {
- fprintf(stderr, "select failed\n");
- break;
- }
- }
-
- if (client->CheckFileDescriptor(client) != TRUE)
- {
- fprintf(stderr, "Failed to check freerdp file descriptor\n");
- break;
- }
-
- if ((xf_peer_check_fds(client)) != TRUE)
- {
- fprintf(stderr, "Failed to check xfreerdp file descriptor\n");
- break;
- }
- }
-
- fprintf(stderr, "Client %s disconnected.\n", client->hostname);
-
- client->Disconnect(client);
-
- freerdp_peer_context_free(client);
- freerdp_peer_free(client);
-
- ExitThread(0);
-
- return NULL;
-}
-
-void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
-{
- HANDLE thread;
-
- thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_peer_main_loop, client, 0, NULL);
-}
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * X11 Peer
- *
- * Copyright 2011 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 __XF_PEER_H
-#define __XF_PEER_H
-
-#include <winpr/crt.h>
-#include <winpr/synch.h>
-#include <winpr/thread.h>
-#include <winpr/stream.h>
-#include <winpr/collections.h>
-
-#include <freerdp/gdi/gdi.h>
-#include <freerdp/gdi/dc.h>
-#include <freerdp/gdi/region.h>
-#include <freerdp/codec/rfx.h>
-#include <freerdp/listener.h>
-#include <freerdp/utils/stopwatch.h>
-
-typedef struct xf_peer_context xfPeerContext;
-
-#include "xfreerdp.h"
-
-#define PeerEvent_Base 0
-
-#define PeerEvent_Class (PeerEvent_Base + 1)
-
-#define PeerEvent_EncodeRegion 1
-
-struct xf_peer_context
-{
- rdpContext _p;
-
- int fps;
- wStream* s;
- xfInfo* info;
- HANDLE mutex;
- BOOL activated;
- HANDLE monitorThread;
- HANDLE updateReadyEvent;
- HANDLE updateSentEvent;
- RFX_CONTEXT* rfx_context;
-};
-
-void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);
-
-#endif /* __XF_PEER_H */
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Implementation
- * X11 Server Graphical Updates
- *
- * Copyright 2013 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 <X11/Xlib.h>
-
-#include <winpr/crt.h>
-#include <winpr/synch.h>
-#include <winpr/sysinfo.h>
-
-#include "xf_peer.h"
-#include "xf_encode.h"
-
-#include "xf_update.h"
-
-void* xf_update_thread(void* param)
-{
- xfInfo* xfi;
- HANDLE event;
- XEvent xevent;
- DWORD beg, end;
- DWORD diff, rate;
- xfPeerContext* xfp;
- freerdp_peer* client;
- int x, y, width, height;
- XDamageNotifyEvent* notify;
-
- client = (freerdp_peer*) param;
- xfp = (xfPeerContext*) client->context;
- xfi = xfp->info;
-
- rate = 1000 / xfp->fps;
-
- event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfi->xfds);
-
- while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
- {
- beg = GetTickCount();
-
- while (XPending(xfi->display) > 0)
- {
- ZeroMemory(&xevent, sizeof(xevent));
- XNextEvent(xfi->display, &xevent);
-
- if (xevent.type == xfi->xdamage_notify_event)
- {
- notify = (XDamageNotifyEvent*) &xevent;
-
- x = notify->area.x;
- y = notify->area.y;
- width = notify->area.width;
- height = notify->area.height;
-
- if (xf_update_encode(client, x, y, width, height) >= 0)
- {
- xf_xdamage_subtract_region(xfp, x, y, width, height);
-
- SetEvent(xfp->updateReadyEvent);
-
- WaitForSingleObject(xfp->updateSentEvent, INFINITE);
- ResetEvent(xfp->updateSentEvent);
- }
- }
-#ifdef WITH_XFIXES
- else if (xevent.type == xfi->xfixes_notify_event)
- {
- XFixesCursorImage* ci = XFixesGetCursorImage(xfi->display);
- XFree(ci);
- }
-#endif
- }
-
- end = GetTickCount();
- diff = end - beg;
-
- if (diff < rate)
- Sleep(rate - diff);
- }
-
- return NULL;
-}
--- /dev/null
+freerdp-shadow
+
--- /dev/null
+# FreeRDP: A Remote Desktop Protocol Implementation
+# FreeRDP Shadow Server cmake build script
+#
+# 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.
+
+set(MODULE_NAME "freerdp-shadow")
+set(MODULE_PREFIX "FREERDP_SERVER_SHADOW")
+
+if(WITH_X11)
+ set(XEXT_FEATURE_TYPE "RECOMMENDED")
+ set(XEXT_FEATURE_PURPOSE "X11 extension")
+ set(XEXT_FEATURE_DESCRIPTION "X11 core extensions")
+
+ set(XSHM_FEATURE_TYPE "RECOMMENDED")
+ set(XSHM_FEATURE_PURPOSE "X11 shared memory")
+ set(XSHM_FEATURE_DESCRIPTION "X11 shared memory extension")
+
+ set(XINERAMA_FEATURE_TYPE "RECOMMENDED")
+ set(XINERAMA_FEATURE_PURPOSE "multi-monitor")
+ set(XINERAMA_FEATURE_DESCRIPTION "X11 multi-monitor extension")
+
+ set(XTEST_FEATURE_TYPE "RECOMMENDED")
+ set(XTEST_FEATURE_PURPOSE "X11 input event injection")
+ set(XTEST_FEATURE_DESCRIPTION "X11 input event injection extension")
+
+ set(XCURSOR_FEATURE_TYPE "RECOMMENDED")
+ set(XCURSOR_FEATURE_PURPOSE "cursor")
+ set(XCURSOR_FEATURE_DESCRIPTION "X11 cursor extension")
+
+ set(XFIXES_FEATURE_TYPE "RECOMMENDED")
+ set(XFIXES_FEATURE_PURPOSE "X11 region")
+ set(XFIXES_FEATURE_DESCRIPTION "X11 region fix extension")
+
+ set(XRANDR_FEATURE_TYPE "RECOMMENDED")
+ set(XRANDR_FEATURE_PURPOSE "X11 resize, rotate and reflect")
+ set(XRANDR_FEATURE_DESCRIPTION "X11 resize, rotate and reflect extension")
+
+ set(XDAMAGE_FEATURE_TYPE "RECOMMENDED")
+ set(XDAMAGE_FEATURE_PURPOSE "X11 region damage")
+ set(XDAMAGE_FEATURE_DESCRIPTION "X11 region damage extension")
+
+ find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DESCRIPTION})
+ find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION})
+ find_feature(XTest ${XTEST_FEATURE_TYPE} ${XTEST_FEATURE_PURPOSE} ${XTEST_FEATURE_DESCRIPTION})
+ find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION})
+ find_feature(XRandR ${XRANDR_FEATURE_TYPE} ${XRANDR_FEATURE_PURPOSE} ${XRANDR_FEATURE_DESCRIPTION})
+ find_feature(Xdamage ${XDAMAGE_FEATURE_TYPE} ${XDAMAGE_FEATURE_PURPOSE} ${XDAMAGE_FEATURE_DESCRIPTION})
+ find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSOR_FEATURE_DESCRIPTION})
+ find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION})
+
+ if(WITH_X11)
+ add_definitions(-DWITH_X11)
+ include_directories(${X11_INCLUDE_DIRS})
+ list(APPEND ${MODULE_PREFIX}_X11_LIBS ${X11_LIBRARIES})
+ endif()
+
+ if(WITH_XSHM)
+ add_definitions(-DWITH_XSHM)
+ include_directories(${XSHM_INCLUDE_DIRS})
+ list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XSHM_LIBRARIES})
+ endif()
+
+ if(WITH_XEXT)
+ add_definitions(-DWITH_XEXT)
+ include_directories(${XEXT_INCLUDE_DIRS})
+ list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XEXT_LIBRARIES})
+ endif()
+
+ if(WITH_XINERAMA)
+ add_definitions(-DWITH_XINERAMA)
+ include_directories(${XINERAMA_INCLUDE_DIRS})
+ list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XINERAMA_LIBRARIES})
+ endif()
+
+ if(WITH_XCURSOR)
+ add_definitions(-DWITH_XCURSOR)
+ include_directories(${XCURSOR_INCLUDE_DIRS})
+ list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XCURSOR_LIBRARIES})
+ endif()
+
+ if(WITH_XDAMAGE)
+ add_definitions(-DWITH_XDAMAGE)
+ include_directories(${XDAMAGE_INCLUDE_DIRS})
+ list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XDAMAGE_LIBRARIES})
+ endif()
+
+ if(WITH_XFIXES)
+ add_definitions(-DWITH_XFIXES)
+ include_directories(${XFIXES_INCLUDE_DIRS})
+ list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XFIXES_LIBRARIES})
+ endif()
+
+ if(WITH_XTEST)
+ add_definitions(-DWITH_XTEST)
+ include_directories(${XTEST_INCLUDE_DIRS})
+ list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XTEST_LIBRARIES})
+ endif()
+
+ if(WITH_XRANDR)
+ add_definitions(-DWITH_XRANDR)
+ include_directories(${XRANDR_INCLUDE_DIRS})
+ list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XRANDR_LIBRARIES})
+ endif()
+endif()
+
+include_directories(${OPENSSL_INCLUDE_DIR})
+
+set(${MODULE_PREFIX}_SRCS
+ shadow_client.c
+ shadow_client.h
+ shadow_input.c
+ shadow_input.h
+ shadow_screen.c
+ shadow_screen.h
+ shadow_surface.c
+ shadow_surface.h
+ shadow_encoder.c
+ shadow_encoder.h
+ shadow_capture.c
+ shadow_capture.h
+ shadow_channels.c
+ shadow_channels.h
+ shadow_encomsp.c
+ shadow_encomsp.h
+ shadow_remdesk.c
+ shadow_remdesk.h
+ shadow_server.c
+ shadow.h)
+
+set(${MODULE_PREFIX}_WIN_SRCS
+ Win/win_rdp.c
+ Win/win_rdp.h
+ Win/win_wds.c
+ Win/win_wds.h
+ Win/win_dxgi.c
+ Win/win_dxgi.h
+ Win/win_shadow.c
+ Win/win_shadow.h)
+
+set(${MODULE_PREFIX}_X11_SRCS
+ X11/x11_shadow.c
+ X11/x11_shadow.h)
+
+set(${MODULE_PREFIX}_MAC_SRCS
+ Mac/mac_shadow.c
+ Mac/mac_shadow.h)
+
+if(WIN32)
+ set(WITH_SHADOW_WIN 1)
+elseif(X11_FOUND AND NOT APPLE)
+ set(WITH_SHADOW_X11 1)
+elseif(APPLE AND NOT IOS)
+ set(WITH_SHADOW_MAC 1)
+endif()
+
+if(WITH_SHADOW_WIN)
+ add_definitions(-DWITH_SHADOW_WIN)
+ list(APPEND ${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_WIN_SRCS})
+ list(APPEND ${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_WIN_LIBS})
+elseif(WITH_SHADOW_X11)
+ add_definitions(-DWITH_SHADOW_X11)
+ list(APPEND ${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_X11_SRCS})
+ list(APPEND ${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_X11_LIBS})
+elseif(WITH_SHADOW_MAC)
+ add_definitions(-DWITH_SHADOW_MAC)
+ list(APPEND ${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_MAC_SRCS})
+ list(APPEND ${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_MAC_LIBS})
+endif()
+
+add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
+
+set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "freerdp-shadow")
+
+list(APPEND ${MODULE_PREFIX}_LIBS freerdp-server)
+
+set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
+ MONOLITHIC ${MONOLITHIC_BUILD}
+ MODULE freerdp
+ MODULES freerdp-core freerdp-common freerdp-codec freerdp-primitives freerdp-utils freerdp-gdi freerdp-crypto freerdp-locale)
+
+list(APPEND ${MODULE_PREFIX}_LIBS freerdp-client)
+list(APPEND ${MODULE_PREFIX}_LIBS winpr-makecert-tool winpr)
+
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
+
+install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server)
+
+set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/shadow")
+
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ *
+ * Copyright 2011-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.
+ */
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/sysinfo.h>
+
+#include <freerdp/codec/color.h>
+#include <freerdp/codec/region.h>
+
+#include "../shadow_screen.h"
+#include "../shadow_surface.h"
+
+#include "mac_shadow.h"
+
+void mac_shadow_input_synchronize_event(macShadowSubsystem* subsystem, UINT32 flags)
+{
+
+}
+
+void mac_shadow_input_keyboard_event(macShadowSubsystem* subsystem, UINT16 flags, UINT16 code)
+{
+
+}
+
+void mac_shadow_input_unicode_keyboard_event(macShadowSubsystem* subsystem, UINT16 flags, UINT16 code)
+{
+
+}
+
+void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y)
+{
+
+}
+
+void mac_shadow_input_extended_mouse_event(macShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y)
+{
+
+}
+
+int mac_shadow_surface_copy(macShadowSubsystem* subsystem)
+{
+ return 1;
+}
+
+void* mac_shadow_subsystem_thread(macShadowSubsystem* subsystem)
+{
+ DWORD status;
+ DWORD nCount;
+ HANDLE events[32];
+ HANDLE StopEvent;
+
+ StopEvent = subsystem->server->StopEvent;
+
+ nCount = 0;
+ events[nCount++] = StopEvent;
+
+ while (1)
+ {
+ status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
+
+ if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
+ {
+ break;
+ }
+ }
+
+ ExitThread(0);
+ return NULL;
+}
+
+int mac_shadow_subsystem_init(macShadowSubsystem* subsystem)
+{
+ return 1;
+}
+
+int mac_shadow_subsystem_uninit(macShadowSubsystem* subsystem)
+{
+ if (!subsystem)
+ return -1;
+
+ return 1;
+}
+
+int mac_shadow_subsystem_start(macShadowSubsystem* subsystem)
+{
+ HANDLE thread;
+
+ if (!subsystem)
+ return -1;
+
+ thread = CreateThread(NULL, 0,
+ (LPTHREAD_START_ROUTINE) mac_shadow_subsystem_thread,
+ (void*) subsystem, 0, NULL);
+
+ return 1;
+}
+
+int mac_shadow_subsystem_stop(macShadowSubsystem* subsystem)
+{
+ if (!subsystem)
+ return -1;
+
+ return 1;
+}
+
+void mac_shadow_subsystem_free(macShadowSubsystem* subsystem)
+{
+ if (!subsystem)
+ return;
+
+ mac_shadow_subsystem_uninit(subsystem);
+
+ free(subsystem);
+}
+
+macShadowSubsystem* mac_shadow_subsystem_new(rdpShadowServer* server)
+{
+ macShadowSubsystem* subsystem;
+
+ subsystem = (macShadowSubsystem*) calloc(1, sizeof(macShadowSubsystem));
+
+ if (!subsystem)
+ return NULL;
+
+ subsystem->server = server;
+
+ subsystem->Init = (pfnShadowSubsystemInit) mac_shadow_subsystem_init;
+ subsystem->Uninit = (pfnShadowSubsystemInit) mac_shadow_subsystem_uninit;
+ subsystem->Start = (pfnShadowSubsystemStart) mac_shadow_subsystem_start;
+ subsystem->Stop = (pfnShadowSubsystemStop) mac_shadow_subsystem_stop;
+ subsystem->Free = (pfnShadowSubsystemFree) mac_shadow_subsystem_free;
+
+ subsystem->SurfaceCopy = (pfnShadowSurfaceCopy) mac_shadow_surface_copy;
+
+ subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) mac_shadow_input_synchronize_event;
+ subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) mac_shadow_input_keyboard_event;
+ subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) mac_shadow_input_unicode_keyboard_event;
+ subsystem->MouseEvent = (pfnShadowMouseEvent) mac_shadow_input_mouse_event;
+ subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent) mac_shadow_input_extended_mouse_event;
+
+ return subsystem;
+}
+
+rdpShadowSubsystem* Mac_ShadowCreateSubsystem(rdpShadowServer* server)
+{
+ return (rdpShadowSubsystem*) mac_shadow_subsystem_new(server);
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ *
+ * Copyright 2011-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_SHADOW_SERVER_MAC_H
+#define FREERDP_SHADOW_SERVER_MAC_H
+
+#include <freerdp/server/shadow.h>
+
+typedef struct mac_shadow_subsystem macShadowSubsystem;
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+#include <winpr/stream.h>
+#include <winpr/collections.h>
+
+struct mac_shadow_subsystem
+{
+ RDP_SHADOW_SUBSYSTEM_COMMON();
+
+
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_MAC_H */
--- /dev/null
+/**
+ * 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 <winpr/crt.h>
+#include <winpr/print.h>
+
+#include "win_dxgi.h"
+
+#ifdef WITH_DXGI_1_2
+
+static D3D_DRIVER_TYPE DriverTypes[] =
+{
+ D3D_DRIVER_TYPE_HARDWARE,
+ D3D_DRIVER_TYPE_WARP,
+ D3D_DRIVER_TYPE_REFERENCE,
+};
+
+static UINT NumDriverTypes = ARRAYSIZE(DriverTypes);
+
+static D3D_FEATURE_LEVEL FeatureLevels[] =
+{
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
+ D3D_FEATURE_LEVEL_9_1
+};
+
+static UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);
+
+static HMODULE d3d11_module = NULL;
+
+typedef HRESULT (WINAPI * fnD3D11CreateDevice)(
+ IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags,
+ CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion,
+ ID3D11Device** ppDevice, D3D_FEATURE_LEVEL* pFeatureLevel, ID3D11DeviceContext** ppImmediateContext);
+
+static fnD3D11CreateDevice pfnD3D11CreateDevice = NULL;
+
+#undef DEFINE_GUID
+#define INITGUID
+
+#include <initguid.h>
+
+/* d3d11.h GUIDs */
+
+DEFINE_GUID(IID_ID3D11DeviceChild,0x1841e5c8,0x16b0,0x489b,0xbc,0xc8,0x44,0xcf,0xb0,0xd5,0xde,0xae);
+DEFINE_GUID(IID_ID3D11DepthStencilState,0x03823efb,0x8d8f,0x4e1c,0x9a,0xa2,0xf6,0x4b,0xb2,0xcb,0xfd,0xf1);
+DEFINE_GUID(IID_ID3D11BlendState,0x75b68faa,0x347d,0x4159,0x8f,0x45,0xa0,0x64,0x0f,0x01,0xcd,0x9a);
+DEFINE_GUID(IID_ID3D11RasterizerState,0x9bb4ab81,0xab1a,0x4d8f,0xb5,0x06,0xfc,0x04,0x20,0x0b,0x6e,0xe7);
+DEFINE_GUID(IID_ID3D11Resource,0xdc8e63f3,0xd12b,0x4952,0xb4,0x7b,0x5e,0x45,0x02,0x6a,0x86,0x2d);
+DEFINE_GUID(IID_ID3D11Buffer,0x48570b85,0xd1ee,0x4fcd,0xa2,0x50,0xeb,0x35,0x07,0x22,0xb0,0x37);
+DEFINE_GUID(IID_ID3D11Texture1D,0xf8fb5c27,0xc6b3,0x4f75,0xa4,0xc8,0x43,0x9a,0xf2,0xef,0x56,0x4c);
+DEFINE_GUID(IID_ID3D11Texture2D,0x6f15aaf2,0xd208,0x4e89,0x9a,0xb4,0x48,0x95,0x35,0xd3,0x4f,0x9c);
+DEFINE_GUID(IID_ID3D11Texture3D,0x037e866e,0xf56d,0x4357,0xa8,0xaf,0x9d,0xab,0xbe,0x6e,0x25,0x0e);
+DEFINE_GUID(IID_ID3D11View,0x839d1216,0xbb2e,0x412b,0xb7,0xf4,0xa9,0xdb,0xeb,0xe0,0x8e,0xd1);
+DEFINE_GUID(IID_ID3D11ShaderResourceView,0xb0e06fe0,0x8192,0x4e1a,0xb1,0xca,0x36,0xd7,0x41,0x47,0x10,0xb2);
+DEFINE_GUID(IID_ID3D11RenderTargetView,0xdfdba067,0x0b8d,0x4865,0x87,0x5b,0xd7,0xb4,0x51,0x6c,0xc1,0x64);
+DEFINE_GUID(IID_ID3D11DepthStencilView,0x9fdac92a,0x1876,0x48c3,0xaf,0xad,0x25,0xb9,0x4f,0x84,0xa9,0xb6);
+DEFINE_GUID(IID_ID3D11UnorderedAccessView,0x28acf509,0x7f5c,0x48f6,0x86,0x11,0xf3,0x16,0x01,0x0a,0x63,0x80);
+DEFINE_GUID(IID_ID3D11VertexShader,0x3b301d64,0xd678,0x4289,0x88,0x97,0x22,0xf8,0x92,0x8b,0x72,0xf3);
+DEFINE_GUID(IID_ID3D11HullShader,0x8e5c6061,0x628a,0x4c8e,0x82,0x64,0xbb,0xe4,0x5c,0xb3,0xd5,0xdd);
+DEFINE_GUID(IID_ID3D11DomainShader,0xf582c508,0x0f36,0x490c,0x99,0x77,0x31,0xee,0xce,0x26,0x8c,0xfa);
+DEFINE_GUID(IID_ID3D11GeometryShader,0x38325b96,0xeffb,0x4022,0xba,0x02,0x2e,0x79,0x5b,0x70,0x27,0x5c);
+DEFINE_GUID(IID_ID3D11PixelShader,0xea82e40d,0x51dc,0x4f33,0x93,0xd4,0xdb,0x7c,0x91,0x25,0xae,0x8c);
+DEFINE_GUID(IID_ID3D11ComputeShader,0x4f5b196e,0xc2bd,0x495e,0xbd,0x01,0x1f,0xde,0xd3,0x8e,0x49,0x69);
+DEFINE_GUID(IID_ID3D11InputLayout,0xe4819ddc,0x4cf0,0x4025,0xbd,0x26,0x5d,0xe8,0x2a,0x3e,0x07,0xb7);
+DEFINE_GUID(IID_ID3D11SamplerState,0xda6fea51,0x564c,0x4487,0x98,0x10,0xf0,0xd0,0xf9,0xb4,0xe3,0xa5);
+DEFINE_GUID(IID_ID3D11Asynchronous,0x4b35d0cd,0x1e15,0x4258,0x9c,0x98,0x1b,0x13,0x33,0xf6,0xdd,0x3b);
+DEFINE_GUID(IID_ID3D11Query,0xd6c00747,0x87b7,0x425e,0xb8,0x4d,0x44,0xd1,0x08,0x56,0x0a,0xfd);
+DEFINE_GUID(IID_ID3D11Predicate,0x9eb576dd,0x9f77,0x4d86,0x81,0xaa,0x8b,0xab,0x5f,0xe4,0x90,0xe2);
+DEFINE_GUID(IID_ID3D11Counter,0x6e8c49fb,0xa371,0x4770,0xb4,0x40,0x29,0x08,0x60,0x22,0xb7,0x41);
+DEFINE_GUID(IID_ID3D11ClassInstance,0xa6cd7faa,0xb0b7,0x4a2f,0x94,0x36,0x86,0x62,0xa6,0x57,0x97,0xcb);
+DEFINE_GUID(IID_ID3D11ClassLinkage,0xddf57cba,0x9543,0x46e4,0xa1,0x2b,0xf2,0x07,0xa0,0xfe,0x7f,0xed);
+DEFINE_GUID(IID_ID3D11CommandList,0xa24bc4d1,0x769e,0x43f7,0x80,0x13,0x98,0xff,0x56,0x6c,0x18,0xe2);
+DEFINE_GUID(IID_ID3D11DeviceContext,0xc0bfa96c,0xe089,0x44fb,0x8e,0xaf,0x26,0xf8,0x79,0x61,0x90,0xda);
+DEFINE_GUID(IID_ID3D11VideoDecoder,0x3C9C5B51,0x995D,0x48d1,0x9B,0x8D,0xFA,0x5C,0xAE,0xDE,0xD6,0x5C);
+DEFINE_GUID(IID_ID3D11VideoProcessorEnumerator,0x31627037,0x53AB,0x4200,0x90,0x61,0x05,0xFA,0xA9,0xAB,0x45,0xF9);
+DEFINE_GUID(IID_ID3D11VideoProcessor,0x1D7B0652,0x185F,0x41c6,0x85,0xCE,0x0C,0x5B,0xE3,0xD4,0xAE,0x6C);
+DEFINE_GUID(IID_ID3D11AuthenticatedChannel,0x3015A308,0xDCBD,0x47aa,0xA7,0x47,0x19,0x24,0x86,0xD1,0x4D,0x4A);
+DEFINE_GUID(IID_ID3D11CryptoSession,0x9B32F9AD,0xBDCC,0x40a6,0xA3,0x9D,0xD5,0xC8,0x65,0x84,0x57,0x20);
+DEFINE_GUID(IID_ID3D11VideoDecoderOutputView,0xC2931AEA,0x2A85,0x4f20,0x86,0x0F,0xFB,0xA1,0xFD,0x25,0x6E,0x18);
+DEFINE_GUID(IID_ID3D11VideoProcessorInputView,0x11EC5A5F,0x51DC,0x4945,0xAB,0x34,0x6E,0x8C,0x21,0x30,0x0E,0xA5);
+DEFINE_GUID(IID_ID3D11VideoProcessorOutputView,0xA048285E,0x25A9,0x4527,0xBD,0x93,0xD6,0x8B,0x68,0xC4,0x42,0x54);
+DEFINE_GUID(IID_ID3D11VideoContext,0x61F21C45,0x3C0E,0x4a74,0x9C,0xEA,0x67,0x10,0x0D,0x9A,0xD5,0xE4);
+DEFINE_GUID(IID_ID3D11VideoDevice,0x10EC4D5B,0x975A,0x4689,0xB9,0xE4,0xD0,0xAA,0xC3,0x0F,0xE3,0x33);
+DEFINE_GUID(IID_ID3D11Device,0xdb6f6ddb,0xac77,0x4e88,0x82,0x53,0x81,0x9d,0xf9,0xbb,0xf1,0x40);
+
+/* dxgi.h GUIDs */
+
+DEFINE_GUID(IID_IDXGIObject, 0xaec22fb8, 0x76f3, 0x4639, 0x9b, 0xe0, 0x28, 0xeb, 0x43, 0xa6, 0x7a, 0x2e);
+DEFINE_GUID(IID_IDXGIDeviceSubObject, 0x3d3e0379, 0xf9de, 0x4d58, 0xbb, 0x6c, 0x18, 0xd6, 0x29, 0x92, 0xf1, 0xa6);
+DEFINE_GUID(IID_IDXGIResource, 0x035f3ab4, 0x482e, 0x4e50, 0xb4, 0x1f, 0x8a, 0x7f, 0x8b, 0xd8, 0x96, 0x0b);
+DEFINE_GUID(IID_IDXGIKeyedMutex, 0x9d8e1289, 0xd7b3, 0x465f, 0x81, 0x26, 0x25, 0x0e, 0x34, 0x9a, 0xf8, 0x5d);
+DEFINE_GUID(IID_IDXGISurface, 0xcafcb56c, 0x6ac3, 0x4889, 0xbf, 0x47, 0x9e, 0x23, 0xbb, 0xd2, 0x60, 0xec);
+DEFINE_GUID(IID_IDXGISurface1, 0x4AE63092, 0x6327, 0x4c1b, 0x80, 0xAE, 0xBF, 0xE1, 0x2E, 0xA3, 0x2B, 0x86);
+DEFINE_GUID(IID_IDXGIAdapter, 0x2411e7e1, 0x12ac, 0x4ccf, 0xbd, 0x14, 0x97, 0x98, 0xe8, 0x53, 0x4d, 0xc0);
+DEFINE_GUID(IID_IDXGIOutput, 0xae02eedb, 0xc735, 0x4690, 0x8d, 0x52, 0x5a, 0x8d, 0xc2, 0x02, 0x13, 0xaa);
+DEFINE_GUID(IID_IDXGISwapChain, 0x310d36a0, 0xd2e7, 0x4c0a, 0xaa, 0x04, 0x6a, 0x9d, 0x23, 0xb8, 0x88, 0x6a);
+DEFINE_GUID(IID_IDXGIFactory, 0x7b7166ec, 0x21c7, 0x44ae, 0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69);
+DEFINE_GUID(IID_IDXGIDevice, 0x54ec77fa, 0x1377, 0x44e6, 0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c);
+DEFINE_GUID(IID_IDXGIFactory1, 0x770aae78, 0xf26f, 0x4dba, 0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87);
+DEFINE_GUID(IID_IDXGIAdapter1, 0x29038f61, 0x3839, 0x4626, 0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a, 0x05);
+DEFINE_GUID(IID_IDXGIDevice1, 0x77db970f, 0x6276, 0x48ba, 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c);
+
+/* dxgi1_2.h GUIDs */
+
+DEFINE_GUID(IID_IDXGIDisplayControl, 0xea9dbf1a, 0xc88e, 0x4486, 0x85, 0x4a, 0x98, 0xaa, 0x01, 0x38, 0xf3, 0x0c);
+DEFINE_GUID(IID_IDXGIOutputDuplication, 0x191cfac3, 0xa341, 0x470d, 0xb2, 0x6e, 0xa8, 0x64, 0xf4, 0x28, 0x31, 0x9c);
+DEFINE_GUID(IID_IDXGISurface2, 0xaba496dd, 0xb617, 0x4cb8, 0xa8, 0x66, 0xbc, 0x44, 0xd7, 0xeb, 0x1f, 0xa2);
+DEFINE_GUID(IID_IDXGIResource1, 0x30961379, 0x4609, 0x4a41, 0x99, 0x8e, 0x54, 0xfe, 0x56, 0x7e, 0xe0, 0xc1);
+DEFINE_GUID(IID_IDXGIDevice2, 0x05008617, 0xfbfd, 0x4051, 0xa7, 0x90, 0x14, 0x48, 0x84, 0xb4, 0xf6, 0xa9);
+DEFINE_GUID(IID_IDXGISwapChain1, 0x790a45f7, 0x0d42, 0x4876, 0x98, 0x3a, 0x0a, 0x55, 0xcf, 0xe6, 0xf4, 0xaa);
+DEFINE_GUID(IID_IDXGIFactory2, 0x50c83a1c, 0xe072, 0x4c48, 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0);
+DEFINE_GUID(IID_IDXGIAdapter2, 0x0AA1AE0A, 0xFA0E, 0x4B84, 0x86, 0x44, 0xE0, 0x5F, 0xF8, 0xE5, 0xAC, 0xB5);
+DEFINE_GUID(IID_IDXGIOutput1, 0x00cddea8, 0x939b, 0x4b83, 0xa3, 0x40, 0xa6, 0x85, 0x22, 0x66, 0x66, 0xcc);
+
+const char* GetDxgiErrorString(HRESULT hr)
+{
+ switch (hr)
+ {
+ case DXGI_STATUS_OCCLUDED:
+ return "DXGI_STATUS_OCCLUDED";
+ case DXGI_STATUS_CLIPPED:
+ return "DXGI_STATUS_CLIPPED";
+ case DXGI_STATUS_NO_REDIRECTION:
+ return "DXGI_STATUS_NO_REDIRECTION";
+ case DXGI_STATUS_NO_DESKTOP_ACCESS:
+ return "DXGI_STATUS_NO_DESKTOP_ACCESS";
+ case DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE:
+ return "DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE";
+ case DXGI_STATUS_MODE_CHANGED:
+ return "DXGI_STATUS_MODE_CHANGED";
+ case DXGI_STATUS_MODE_CHANGE_IN_PROGRESS:
+ return "DXGI_STATUS_MODE_CHANGE_IN_PROGRESS";
+ case DXGI_ERROR_INVALID_CALL:
+ return "DXGI_ERROR_INVALID_CALL";
+ case DXGI_ERROR_NOT_FOUND:
+ return "DXGI_ERROR_NOT_FOUND";
+ case DXGI_ERROR_MORE_DATA:
+ return "DXGI_ERROR_MORE_DATA";
+ case DXGI_ERROR_UNSUPPORTED:
+ return "DXGI_ERROR_UNSUPPORTED";
+ case DXGI_ERROR_DEVICE_REMOVED:
+ return "DXGI_ERROR_DEVICE_REMOVED";
+ case DXGI_ERROR_DEVICE_HUNG:
+ return "DXGI_ERROR_DEVICE_HUNG";
+ case DXGI_ERROR_DEVICE_RESET:
+ return "DXGI_ERROR_DEVICE_RESET";
+ case DXGI_ERROR_WAS_STILL_DRAWING:
+ return "DXGI_ERROR_WAS_STILL_DRAWING";
+ case DXGI_ERROR_FRAME_STATISTICS_DISJOINT:
+ return "DXGI_ERROR_FRAME_STATISTICS_DISJOINT";
+ case DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE:
+ return "DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE";
+ case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
+ return "DXGI_ERROR_DRIVER_INTERNAL_ERROR";
+ case DXGI_ERROR_NONEXCLUSIVE:
+ return "DXGI_ERROR_NONEXCLUSIVE";
+ case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
+ return "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE";
+ case DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED:
+ return "DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED";
+ case DXGI_ERROR_REMOTE_OUTOFMEMORY:
+ return "DXGI_ERROR_REMOTE_OUTOFMEMORY";
+ case DXGI_ERROR_ACCESS_LOST:
+ return "DXGI_ERROR_ACCESS_LOST";
+ case DXGI_ERROR_WAIT_TIMEOUT:
+ return "DXGI_ERROR_WAIT_TIMEOUT";
+ case DXGI_ERROR_SESSION_DISCONNECTED:
+ return "DXGI_ERROR_SESSION_DISCONNECTED";
+ case DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE:
+ return "DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE";
+ case DXGI_ERROR_CANNOT_PROTECT_CONTENT:
+ return "DXGI_ERROR_CANNOT_PROTECT_CONTENT";
+ case DXGI_ERROR_ACCESS_DENIED:
+ return "DXGI_ERROR_ACCESS_DENIED";
+ case DXGI_ERROR_NAME_ALREADY_EXISTS:
+ return "DXGI_ERROR_NAME_ALREADY_EXISTS";
+ case DXGI_ERROR_SDK_COMPONENT_MISSING:
+ return "DXGI_ERROR_SDK_COMPONENT_MISSING";
+ case DXGI_STATUS_UNOCCLUDED:
+ return "DXGI_STATUS_UNOCCLUDED";
+ case DXGI_STATUS_DDA_WAS_STILL_DRAWING:
+ return "DXGI_STATUS_DDA_WAS_STILL_DRAWING";
+ case DXGI_ERROR_MODE_CHANGE_IN_PROGRESS:
+ return "DXGI_ERROR_MODE_CHANGE_IN_PROGRESS";
+ case DXGI_DDI_ERR_WASSTILLDRAWING:
+ return "DXGI_DDI_ERR_WASSTILLDRAWING";
+ case DXGI_DDI_ERR_UNSUPPORTED:
+ return "DXGI_DDI_ERR_UNSUPPORTED";
+ case DXGI_DDI_ERR_NONEXCLUSIVE:
+ return "DXGI_DDI_ERR_NONEXCLUSIVE";
+ case 0x80070005:
+ return "DXGI_ERROR_ACCESS_DENIED";
+ }
+
+ return "DXGI_ERROR_UNKNOWN";
+}
+
+static void win_shadow_d3d11_module_init()
+{
+ if (d3d11_module)
+ return;
+
+ d3d11_module = LoadLibraryA("d3d11.dll");
+
+ if (!d3d11_module)
+ return;
+
+ pfnD3D11CreateDevice = (fnD3D11CreateDevice) GetProcAddress(d3d11_module, "D3D11CreateDevice");
+}
+
+int win_shadow_dxgi_init_duplication(winShadowSubsystem* subsystem)
+{
+ HRESULT hr;
+ UINT dTop, i = 0;
+ IDXGIOutput* pOutput;
+ DXGI_OUTPUT_DESC outputDesc;
+ DXGI_OUTPUT_DESC* pOutputDesc;
+ D3D11_TEXTURE2D_DESC textureDesc;
+ IDXGIDevice* dxgiDevice = NULL;
+ IDXGIAdapter* dxgiAdapter = NULL;
+ IDXGIOutput* dxgiOutput = NULL;
+ IDXGIOutput1* dxgiOutput1 = NULL;
+
+ hr = subsystem->dxgiDevice->lpVtbl->QueryInterface(subsystem->dxgiDevice,
+ &IID_IDXGIDevice, (void**) &dxgiDevice);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "ID3D11Device::QueryInterface(IDXGIDevice) failure: %s (0x%04X)\n",
+ GetDxgiErrorString(hr), hr);
+ return -1;
+ }
+
+ hr = dxgiDevice->lpVtbl->GetParent(dxgiDevice, &IID_IDXGIAdapter, (void**) &dxgiAdapter);
+
+ if (dxgiDevice)
+ {
+ dxgiDevice->lpVtbl->Release(dxgiDevice);
+ dxgiDevice = NULL;
+ }
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IDXGIDevice::GetParent(IDXGIAdapter) failure: %s (0x%04X)\n",
+ GetDxgiErrorString(hr), hr);
+ return -1;
+ }
+
+ pOutput = NULL;
+ ZeroMemory(&outputDesc, sizeof(outputDesc));
+
+ while (dxgiAdapter->lpVtbl->EnumOutputs(dxgiAdapter, i, &pOutput) != DXGI_ERROR_NOT_FOUND)
+ {
+ pOutputDesc = &outputDesc;
+
+ hr = pOutput->lpVtbl->GetDesc(pOutput, pOutputDesc);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IDXGIOutput::GetDesc failure: %s (0x%04X)\n",
+ GetDxgiErrorString(hr), hr);
+ return -1;
+ }
+
+ if (pOutputDesc->AttachedToDesktop)
+ dTop = i;
+
+ pOutput->lpVtbl->Release(pOutput);
+ i++;
+ }
+
+ dTop = 0; /* screen id */
+
+ hr = dxgiAdapter->lpVtbl->EnumOutputs(dxgiAdapter, dTop, &dxgiOutput);
+
+ if (dxgiAdapter)
+ {
+ dxgiAdapter->lpVtbl->Release(dxgiAdapter);
+ dxgiAdapter = NULL;
+ }
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IDXGIAdapter::EnumOutputs failure: %s (0x%04X)\n",
+ GetDxgiErrorString(hr), hr);
+ return -1;
+ }
+
+ hr = dxgiOutput->lpVtbl->QueryInterface(dxgiOutput, &IID_IDXGIOutput1, (void**) &dxgiOutput1);
+
+ if (dxgiOutput)
+ {
+ dxgiOutput->lpVtbl->Release(dxgiOutput);
+ dxgiOutput = NULL;
+ }
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IDXGIOutput::QueryInterface(IDXGIOutput1) failure: %s (0x%04X)\n",
+ GetDxgiErrorString(hr), hr);
+ return -1;
+ }
+
+ hr = dxgiOutput1->lpVtbl->DuplicateOutput(dxgiOutput1, (IUnknown*) subsystem->dxgiDevice,
+ &(subsystem->dxgiOutputDuplication));
+
+ if (dxgiOutput1)
+ {
+ dxgiOutput1->lpVtbl->Release(dxgiOutput1);
+ dxgiOutput1 = NULL;
+ }
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IDXGIOutput1::DuplicateOutput failure: %s (0x%04X)\n",
+ GetDxgiErrorString(hr), hr);
+ return -1;
+ }
+
+ textureDesc.Width = subsystem->width;
+ textureDesc.Height = subsystem->height;
+ textureDesc.MipLevels = 1;
+ textureDesc.ArraySize = 1;
+ textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ textureDesc.SampleDesc.Count = 1;
+ textureDesc.SampleDesc.Quality = 0;
+ textureDesc.Usage = D3D11_USAGE_STAGING;
+ textureDesc.BindFlags = 0;
+ textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ textureDesc.MiscFlags = 0;
+
+ hr = subsystem->dxgiDevice->lpVtbl->CreateTexture2D(subsystem->dxgiDevice,
+ &textureDesc, NULL, &(subsystem->dxgiStage));
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "ID3D11Device::CreateTexture2D failure: %s (0x%04X)\n",
+ GetDxgiErrorString(hr), hr);
+ return -1;
+ }
+
+ return 1;
+}
+
+int win_shadow_dxgi_init(winShadowSubsystem* subsystem)
+{
+ UINT i = 0;
+ HRESULT hr;
+ int status;
+ UINT DriverTypeIndex;
+ IDXGIDevice* DxgiDevice = NULL;
+ IDXGIAdapter* DxgiAdapter = NULL;
+ IDXGIOutput* DxgiOutput = NULL;
+ IDXGIOutput1* DxgiOutput1 = NULL;
+
+ win_shadow_d3d11_module_init();
+
+ if (!pfnD3D11CreateDevice)
+ return -1;
+
+ for (DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex)
+ {
+ hr = pfnD3D11CreateDevice(NULL, DriverTypes[DriverTypeIndex], NULL, 0, FeatureLevels,
+ NumFeatureLevels, D3D11_SDK_VERSION, &(subsystem->dxgiDevice), &(subsystem->featureLevel),
+ &(subsystem->dxgiDeviceContext));
+
+ if (SUCCEEDED(hr))
+ break;
+ }
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "D3D11CreateDevice failure: 0x%04X\n", hr);
+ return -1;
+ }
+
+ status = win_shadow_dxgi_init_duplication(subsystem);
+
+ return status;
+}
+
+int win_shadow_dxgi_uninit(winShadowSubsystem* subsystem)
+{
+ if (subsystem->dxgiStage)
+ {
+ subsystem->dxgiStage->lpVtbl->Release(subsystem->dxgiStage);
+ subsystem->dxgiStage = NULL;
+ }
+
+ if (subsystem->dxgiDesktopImage)
+ {
+ subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage);
+ subsystem->dxgiDesktopImage = NULL;
+ }
+
+ if (subsystem->dxgiOutputDuplication)
+ {
+ subsystem->dxgiOutputDuplication->lpVtbl->Release(subsystem->dxgiOutputDuplication);
+ subsystem->dxgiOutputDuplication = NULL;
+ }
+
+ if (subsystem->dxgiDeviceContext)
+ {
+ subsystem->dxgiDeviceContext->lpVtbl->Release(subsystem->dxgiDeviceContext);
+ subsystem->dxgiDeviceContext = NULL;
+ }
+
+ if (subsystem->dxgiDevice)
+ {
+ subsystem->dxgiDevice->lpVtbl->Release(subsystem->dxgiDevice);
+ subsystem->dxgiDevice = NULL;
+ }
+
+ return 1;
+}
+
+int win_shadow_dxgi_fetch_frame_data(winShadowSubsystem* subsystem,
+ BYTE** ppDstData, int* pnDstStep, int x, int y, int width, int height)
+{
+ int status;
+ HRESULT hr;
+ D3D11_BOX Box;
+ DXGI_MAPPED_RECT mappedRect;
+
+ if ((width * height) < 1)
+ return 0;
+
+ Box.top = x;
+ Box.left = y;
+ Box.right = x + width;
+ Box.bottom = y + height;
+ Box.front = 0;
+ Box.back = 1;
+
+ subsystem->dxgiDeviceContext->lpVtbl->CopySubresourceRegion(subsystem->dxgiDeviceContext,
+ (ID3D11Resource*) subsystem->dxgiStage, 0, 0, 0, 0, (ID3D11Resource*) subsystem->dxgiDesktopImage, 0, &Box);
+
+ hr = subsystem->dxgiStage->lpVtbl->QueryInterface(subsystem->dxgiStage,
+ &IID_IDXGISurface, (void**) &(subsystem->dxgiSurface));
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "ID3D11Texture2D::QueryInterface(IDXGISurface) failure: %s 0x%04X\n",
+ GetDxgiErrorString(hr), hr);
+ return -1;
+ }
+
+ hr = subsystem->dxgiSurface->lpVtbl->Map(subsystem->dxgiSurface, &mappedRect, DXGI_MAP_READ);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IDXGISurface::Map failure: %s 0x%04X\n",
+ GetDxgiErrorString(hr), hr);
+
+ if (hr == DXGI_ERROR_DEVICE_REMOVED)
+ {
+ win_shadow_dxgi_uninit(subsystem);
+
+ status = win_shadow_dxgi_init(subsystem);
+
+ if (status < 0)
+ return -1;
+
+ return 0;
+ }
+
+ return -1;
+ }
+
+ subsystem->dxgiSurfaceMapped = TRUE;
+
+ *ppDstData = mappedRect.pBits;
+ *pnDstStep = mappedRect.Pitch;
+
+ return 1;
+}
+
+int win_shadow_dxgi_release_frame_data(winShadowSubsystem* subsystem)
+{
+ if (subsystem->dxgiSurface)
+ {
+ if (subsystem->dxgiSurfaceMapped)
+ {
+ subsystem->dxgiSurface->lpVtbl->Unmap(subsystem->dxgiSurface);
+ subsystem->dxgiSurfaceMapped = FALSE;
+ }
+
+ subsystem->dxgiSurface->lpVtbl->Release(subsystem->dxgiSurface);
+ subsystem->dxgiSurface = NULL;
+ }
+
+ if (subsystem->dxgiOutputDuplication)
+ {
+ if (subsystem->dxgiFrameAcquired)
+ {
+ subsystem->dxgiOutputDuplication->lpVtbl->ReleaseFrame(subsystem->dxgiOutputDuplication);
+ subsystem->dxgiFrameAcquired = FALSE;
+ }
+ }
+
+ subsystem->pendingFrames = 0;
+
+ return 1;
+}
+
+int win_shadow_dxgi_get_next_frame(winShadowSubsystem* subsystem)
+{
+ UINT i = 0;
+ int status;
+ HRESULT hr = 0;
+ UINT timeout = 15;
+ UINT DataBufferSize = 0;
+ BYTE* DataBuffer = NULL;
+
+ if (subsystem->dxgiFrameAcquired)
+ {
+ win_shadow_dxgi_release_frame_data(subsystem);
+ }
+
+ if (subsystem->dxgiDesktopImage)
+ {
+ subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage);
+ subsystem->dxgiDesktopImage = NULL;
+ }
+
+ hr = subsystem->dxgiOutputDuplication->lpVtbl->AcquireNextFrame(subsystem->dxgiOutputDuplication,
+ timeout, &(subsystem->dxgiFrameInfo), &(subsystem->dxgiResource));
+
+ if (SUCCEEDED(hr))
+ {
+ subsystem->dxgiFrameAcquired = TRUE;
+ subsystem->pendingFrames = subsystem->dxgiFrameInfo.AccumulatedFrames;
+ }
+
+ if (hr == DXGI_ERROR_WAIT_TIMEOUT)
+ return 0;
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IDXGIOutputDuplication::AcquireNextFrame failure: %s (0x%04X)\n",
+ GetDxgiErrorString(hr), hr);
+
+ if (hr == DXGI_ERROR_ACCESS_LOST)
+ {
+ win_shadow_dxgi_release_frame_data(subsystem);
+
+ if (subsystem->dxgiDesktopImage)
+ {
+ subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage);
+ subsystem->dxgiDesktopImage = NULL;
+ }
+
+ if (subsystem->dxgiOutputDuplication)
+ {
+ subsystem->dxgiOutputDuplication->lpVtbl->Release(subsystem->dxgiOutputDuplication);
+ subsystem->dxgiOutputDuplication = NULL;
+ }
+
+ status = win_shadow_dxgi_init_duplication(subsystem);
+
+ if (status < 0)
+ return -1;
+
+ return 0;
+ }
+ else if (hr == DXGI_ERROR_INVALID_CALL)
+ {
+ win_shadow_dxgi_uninit(subsystem);
+
+ status = win_shadow_dxgi_init(subsystem);
+
+ if (status < 0)
+ return -1;
+
+ return 0;
+ }
+
+ return -1;
+ }
+
+ hr = subsystem->dxgiResource->lpVtbl->QueryInterface(subsystem->dxgiResource,
+ &IID_ID3D11Texture2D, (void**) &(subsystem->dxgiDesktopImage));
+
+ if (subsystem->dxgiResource)
+ {
+ subsystem->dxgiResource->lpVtbl->Release(subsystem->dxgiResource);
+ subsystem->dxgiResource = NULL;
+ }
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IDXGIResource::QueryInterface(ID3D11Texture2D) failure: %s (0x%04X)\n",
+ GetDxgiErrorString(hr), hr);
+ return -1;
+ }
+
+ return 1;
+}
+
+int win_shadow_dxgi_get_invalid_region(winShadowSubsystem* subsystem)
+{
+ UINT i;
+ HRESULT hr;
+ POINT* pSrcPt;
+ RECT* pDstRect;
+ RECT* pDirtyRect;
+ UINT numMoveRects;
+ UINT numDirtyRects;
+ UINT UsedBufferSize;
+ RECTANGLE_16 invalidRect;
+ UINT MetadataBufferSize;
+ UINT MoveRectsBufferSize;
+ UINT DirtyRectsBufferSize;
+ RECT* pDirtyRectsBuffer;
+ DXGI_OUTDUPL_MOVE_RECT* pMoveRect;
+ DXGI_OUTDUPL_MOVE_RECT* pMoveRectBuffer;
+
+ if (subsystem->dxgiFrameInfo.AccumulatedFrames == 0)
+ return 0;
+
+ if (subsystem->dxgiFrameInfo.TotalMetadataBufferSize == 0)
+ return 0;
+
+ MetadataBufferSize = subsystem->dxgiFrameInfo.TotalMetadataBufferSize;
+
+ if (MetadataBufferSize > subsystem->MetadataBufferSize)
+ {
+ subsystem->MetadataBuffer = (BYTE*) realloc(subsystem->MetadataBuffer, MetadataBufferSize);
+
+ if (!subsystem->MetadataBuffer)
+ return -1;
+
+ subsystem->MetadataBufferSize = MetadataBufferSize;
+ }
+
+ /* GetFrameMoveRects */
+
+ UsedBufferSize = 0;
+
+ MoveRectsBufferSize = MetadataBufferSize - UsedBufferSize;
+ pMoveRectBuffer = (DXGI_OUTDUPL_MOVE_RECT*) &(subsystem->MetadataBuffer[UsedBufferSize]);
+
+ hr = subsystem->dxgiOutputDuplication->lpVtbl->GetFrameMoveRects(subsystem->dxgiOutputDuplication,
+ MoveRectsBufferSize, pMoveRectBuffer, &MoveRectsBufferSize);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IDXGIOutputDuplication::GetFrameMoveRects failure: %s (0x%04X) Size: %d Total %d Used: %d\n",
+ GetDxgiErrorString(hr), hr, MoveRectsBufferSize, MetadataBufferSize, UsedBufferSize);
+ return -1;
+ }
+
+ /* GetFrameDirtyRects */
+
+ UsedBufferSize += MoveRectsBufferSize;
+
+ DirtyRectsBufferSize = MetadataBufferSize - UsedBufferSize;
+ pDirtyRectsBuffer = (RECT*) &(subsystem->MetadataBuffer[UsedBufferSize]);
+
+ hr = subsystem->dxgiOutputDuplication->lpVtbl->GetFrameDirtyRects(subsystem->dxgiOutputDuplication,
+ DirtyRectsBufferSize, pDirtyRectsBuffer, &DirtyRectsBufferSize);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IDXGIOutputDuplication::GetFrameDirtyRects failure: %s (0x%04X) Size: %d Total %d Used: %d\n",
+ GetDxgiErrorString(hr), hr, DirtyRectsBufferSize, MetadataBufferSize, UsedBufferSize);
+ return -1;
+ }
+
+ numMoveRects = MoveRectsBufferSize / sizeof(DXGI_OUTDUPL_MOVE_RECT);
+
+ for (i = 0; i < numMoveRects; i++)
+ {
+ pMoveRect = &pMoveRectBuffer[i];
+ pSrcPt = &(pMoveRect->SourcePoint);
+ pDstRect = &(pMoveRect->DestinationRect);
+
+ invalidRect.left = (UINT16) pDstRect->left;
+ invalidRect.top = (UINT16) pDstRect->top;
+ invalidRect.right = (UINT16) pDstRect->right;
+ invalidRect.bottom = (UINT16) pDstRect->bottom;
+
+ region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
+ }
+
+ numDirtyRects = DirtyRectsBufferSize / sizeof(RECT);
+
+ for (i = 0; i < numDirtyRects; i++)
+ {
+ pDirtyRect = &pDirtyRectsBuffer[i];
+
+ invalidRect.left = (UINT16) pDirtyRect->left;
+ invalidRect.top = (UINT16) pDirtyRect->top;
+ invalidRect.right = (UINT16) pDirtyRect->right;
+ invalidRect.bottom = (UINT16) pDirtyRect->bottom;
+
+ region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
+ }
+
+ return 1;
+}
+
+#endif
--- /dev/null
+/**
+ * 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 FREERDP_SHADOW_SERVER_WIN_DXGI_H
+#define FREERDP_SHADOW_SERVER_WIN_DXGI_H
+
+#if _WIN32_WINNT >= 0x0602
+//#define WITH_DXGI_1_2 1
+#endif
+
+#ifdef WITH_DXGI_1_2
+
+#ifndef CINTERFACE
+#define CINTERFACE
+#endif
+
+#include <D3D11.h>
+#include <dxgi1_2.h>
+
+#endif
+
+#include "win_shadow.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WITH_DXGI_1_2
+
+int win_shadow_dxgi_init(winShadowSubsystem* subsystem);
+int win_shadow_dxgi_uninit(winShadowSubsystem* subsystem);
+
+int win_shadow_dxgi_fetch_frame_data(winShadowSubsystem* subsystem,
+ BYTE** ppDstData, int* pnDstStep, int x, int y, int width, int height);
+
+int win_shadow_dxgi_get_next_frame(winShadowSubsystem* subsystem);
+int win_shadow_dxgi_get_invalid_region(winShadowSubsystem* subsystem);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_WIN_DXGI_H */
--- /dev/null
+/**
+ * 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 <winpr/crt.h>
+#include <winpr/print.h>
+
+#include "win_rdp.h"
+
+void shw_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
+{
+ shwContext* shw = (shwContext*) context;
+
+ printf("OnChannelConnected: %s\n", e->name);
+}
+
+void shw_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
+{
+ shwContext* shw = (shwContext*) context;
+
+ printf("OnChannelDisconnected: %s\n", e->name);
+}
+
+void shw_begin_paint(rdpContext* context)
+{
+ shwContext* shw;
+ rdpGdi* gdi = context->gdi;
+
+ shw = (shwContext*) context;
+
+ gdi->primary->hdc->hwnd->invalid->null = 1;
+ gdi->primary->hdc->hwnd->ninvalid = 0;
+}
+
+void shw_end_paint(rdpContext* context)
+{
+ int index;
+ int ninvalid;
+ HGDI_RGN cinvalid;
+ RECTANGLE_16 invalidRect;
+ rdpGdi* gdi = context->gdi;
+ shwContext* shw = (shwContext*) context;
+ winShadowSubsystem* subsystem = shw->subsystem;
+
+ ninvalid = gdi->primary->hdc->hwnd->ninvalid;
+ cinvalid = gdi->primary->hdc->hwnd->cinvalid;
+
+ for (index = 0; index < ninvalid; index++)
+ {
+ invalidRect.left = cinvalid[index].x;
+ invalidRect.top = cinvalid[index].y;
+ invalidRect.right = cinvalid[index].x + cinvalid[index].w;
+ invalidRect.bottom = cinvalid[index].y + cinvalid[index].h;
+
+ region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
+ }
+
+ SetEvent(subsystem->RdpUpdateEnterEvent);
+ WaitForSingleObject(subsystem->RdpUpdateLeaveEvent, INFINITE);
+ ResetEvent(subsystem->RdpUpdateLeaveEvent);
+}
+
+void shw_desktop_resize(rdpContext* context)
+{
+
+}
+
+void shw_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surfaceFrameMarker)
+{
+ shwContext* shw = (shwContext*) context;
+}
+
+BOOL shw_authenticate(freerdp* instance, char** username, char** password, char** domain)
+{
+ return TRUE;
+}
+
+BOOL shw_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
+{
+ return TRUE;
+}
+
+int shw_verify_x509_certificate(freerdp* instance, BYTE* data, int length, const char* hostname, int port, DWORD flags)
+{
+ return 1;
+}
+
+void shw_OnConnectionResultEventHandler(rdpContext* context, ConnectionResultEventArgs* e)
+{
+ shwContext* shw = (shwContext*) context;
+ printf("OnConnectionResult: %d\n", e->result);
+}
+
+BOOL shw_pre_connect(freerdp* instance)
+{
+ shwContext* shw;
+ rdpContext* context = instance->context;
+
+ shw = (shwContext*) context;
+
+ PubSub_SubscribeConnectionResult(context->pubSub,
+ (pConnectionResultEventHandler) shw_OnConnectionResultEventHandler);
+
+ PubSub_SubscribeChannelConnected(context->pubSub,
+ (pChannelConnectedEventHandler) shw_OnChannelConnectedEventHandler);
+
+ PubSub_SubscribeChannelDisconnected(context->pubSub,
+ (pChannelDisconnectedEventHandler) shw_OnChannelDisconnectedEventHandler);
+
+ freerdp_client_load_addins(context->channels, instance->settings);
+
+ freerdp_channels_pre_connect(context->channels, instance);
+
+ return TRUE;
+}
+
+BOOL shw_post_connect(freerdp* instance)
+{
+ rdpGdi* gdi;
+ shwContext* shw;
+ rdpSettings* settings;
+
+ shw = (shwContext*) instance->context;
+ settings = instance->settings;
+
+ gdi_init(instance, CLRBUF_32BPP, NULL);
+ gdi = instance->context->gdi;
+
+ instance->update->BeginPaint = shw_begin_paint;
+ instance->update->EndPaint = shw_end_paint;
+ instance->update->DesktopResize = shw_desktop_resize;
+ instance->update->SurfaceFrameMarker = shw_surface_frame_marker;
+
+ freerdp_channels_post_connect(instance->context->channels, instance);
+
+ return TRUE;
+}
+
+void* shw_client_thread(void* arg)
+{
+ int index;
+ int rcount;
+ int wcount;
+ BOOL bSuccess;
+ void* rfds[32];
+ void* wfds[32];
+ int fds_count;
+ HANDLE fds[64];
+ shwContext* shw;
+ rdpContext* context;
+ rdpChannels* channels;
+ freerdp* instance = (freerdp*) arg;
+
+ ZeroMemory(rfds, sizeof(rfds));
+ ZeroMemory(wfds, sizeof(wfds));
+
+ context = (rdpContext*) instance->context;
+ shw = (shwContext*) context;
+
+ bSuccess = freerdp_connect(instance);
+
+ printf("freerdp_connect: %d\n", bSuccess);
+
+ if (!bSuccess)
+ {
+ ExitThread(0);
+ return NULL;
+ }
+
+ channels = instance->context->channels;
+
+ while (1)
+ {
+ rcount = 0;
+ wcount = 0;
+
+ if (!freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount))
+ {
+ fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
+ break;
+ }
+
+ if (!freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount))
+ {
+ fprintf(stderr, "Failed to get channels file descriptor\n");
+ break;
+ }
+
+ fds_count = 0;
+
+ for (index = 0; index < rcount; index++)
+ fds[fds_count++] = rfds[index];
+
+ for (index = 0; index < wcount; index++)
+ fds[fds_count++] = wfds[index];
+
+ if (MsgWaitForMultipleObjects(fds_count, fds, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED)
+ {
+ fprintf(stderr, "MsgWaitForMultipleObjects failure: 0x%08X", GetLastError());
+ break;
+ }
+
+ if (!freerdp_check_fds(instance))
+ {
+ fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
+ break;
+ }
+
+ if (freerdp_shall_disconnect(instance))
+ {
+ break;
+ }
+
+ if (!freerdp_channels_check_fds(channels, instance))
+ {
+ fprintf(stderr, "Failed to check channels file descriptor\n");
+ break;
+ }
+ }
+
+ freerdp_free(instance);
+
+ ExitThread(0);
+ return NULL;
+}
+
+/**
+ * Client Interface
+ */
+
+void shw_freerdp_client_global_init(void)
+{
+
+}
+
+void shw_freerdp_client_global_uninit(void)
+{
+
+}
+
+int shw_freerdp_client_start(rdpContext* context)
+{
+ shwContext* shw;
+ freerdp* instance = context->instance;
+
+ shw = (shwContext*) context;
+
+ shw->thread = CreateThread(NULL, 0,
+ (LPTHREAD_START_ROUTINE) shw_client_thread,
+ instance, 0, NULL);
+
+ return 0;
+}
+
+int shw_freerdp_client_stop(rdpContext* context)
+{
+ shwContext* shw = (shwContext*) context;
+
+ SetEvent(shw->StopEvent);
+
+ return 0;
+}
+
+int shw_freerdp_client_new(freerdp* instance, rdpContext* context)
+{
+ shwContext* shw;
+ rdpSettings* settings;
+
+ shw = (shwContext*) instance->context;
+
+ instance->PreConnect = shw_pre_connect;
+ instance->PostConnect = shw_post_connect;
+ instance->Authenticate = shw_authenticate;
+ instance->VerifyCertificate = shw_verify_certificate;
+ instance->VerifyX509Certificate = shw_verify_x509_certificate;
+
+ context->channels = freerdp_channels_new();
+
+ shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ settings = instance->settings;
+ shw->settings = instance->context->settings;
+
+ settings->AsyncTransport = FALSE;
+ settings->AsyncChannels = FALSE;
+ settings->AsyncUpdate = FALSE;
+ settings->AsyncInput = FALSE;
+
+ settings->IgnoreCertificate = TRUE;
+ settings->ExternalCertificateManagement = TRUE;
+
+ settings->RdpSecurity = TRUE;
+ settings->TlsSecurity = TRUE;
+ settings->NlaSecurity = FALSE;
+
+ settings->BitmapCacheEnabled = FALSE;
+ settings->BitmapCacheV3Enabled = FALSE;
+ settings->OffscreenSupportLevel = FALSE;
+ settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE;
+ settings->BrushSupportLevel = FALSE;
+
+ ZeroMemory(settings->OrderSupport, 32);
+
+ settings->FrameMarkerCommandEnabled = TRUE;
+ settings->SurfaceFrameMarkerEnabled = TRUE;
+ settings->AltSecFrameMarkerSupport = TRUE;
+
+ settings->ColorDepth = 32;
+ settings->NSCodec = TRUE;
+ settings->RemoteFxCodec = TRUE;
+ settings->FastPathInput = TRUE;
+ settings->FastPathOutput = TRUE;
+ settings->LargePointerFlag = TRUE;
+
+ settings->CompressionEnabled = FALSE;
+
+ settings->AutoReconnectionEnabled = FALSE;
+ settings->NetworkAutoDetect = FALSE;
+ settings->SupportHeartbeatPdu = FALSE;
+ settings->SupportMultitransport = FALSE;
+ settings->ConnectionType = CONNECTION_TYPE_LAN;
+
+ settings->AllowFontSmoothing = TRUE;
+ settings->AllowDesktopComposition = TRUE;
+ settings->DisableWallpaper = FALSE;
+ settings->DisableFullWindowDrag = TRUE;
+ settings->DisableMenuAnims = TRUE;
+ settings->DisableThemes = FALSE;
+
+ settings->DeviceRedirection = TRUE;
+ settings->RedirectClipboard = TRUE;
+ settings->SupportDynamicChannels = TRUE;
+
+ return 0;
+}
+
+void shw_freerdp_client_free(freerdp* instance, rdpContext* context)
+{
+ shwContext* shw = (shwContext*) instance->context;
+}
+
+int shw_RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
+{
+ pEntryPoints->Version = 1;
+ pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
+
+ pEntryPoints->settings = NULL;
+
+ pEntryPoints->ContextSize = sizeof(shwContext);
+ pEntryPoints->GlobalInit = shw_freerdp_client_global_init;
+ pEntryPoints->GlobalUninit = shw_freerdp_client_global_uninit;
+ pEntryPoints->ClientNew = shw_freerdp_client_new;
+ pEntryPoints->ClientFree = shw_freerdp_client_free;
+ pEntryPoints->ClientStart = shw_freerdp_client_start;
+ pEntryPoints->ClientStop = shw_freerdp_client_stop;
+
+ return 0;
+}
+
+int win_shadow_rdp_init(winShadowSubsystem* subsystem)
+{
+ rdpContext* context;
+ RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
+
+ ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS));
+ clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS);
+ clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
+
+ shw_RdpClientEntry(&clientEntryPoints);
+
+ context = freerdp_client_context_new(&clientEntryPoints);
+
+ subsystem->shw = (shwContext*) context;
+ subsystem->shw->settings = context->settings;
+ subsystem->shw->subsystem = subsystem;
+
+ subsystem->RdpUpdateEnterEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ subsystem->RdpUpdateLeaveEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ return 1;
+}
+
+int win_shadow_rdp_start(winShadowSubsystem* subsystem)
+{
+ int status;
+ shwContext* shw = subsystem->shw;
+ rdpContext* context = (rdpContext*) shw;
+
+ status = freerdp_client_start(context);
+
+ return status;
+}
+
+int win_shadow_rdp_stop(winShadowSubsystem* subsystem)
+{
+ int status;
+ shwContext* shw = subsystem->shw;
+ rdpContext* context = (rdpContext*) shw;
+
+ status = freerdp_client_stop(context);
+
+ return status;
+}
+
+int win_shadow_rdp_uninit(winShadowSubsystem* subsystem)
+{
+ win_shadow_rdp_stop(subsystem);
+
+ return 1;
+}
--- /dev/null
+/**
+ * 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 FREERDP_SHADOW_SERVER_WIN_RDP_H
+#define FREERDP_SHADOW_SERVER_WIN_RDP_H
+
+#include <freerdp/addin.h>
+#include <freerdp/gdi/gdi.h>
+#include <freerdp/client/cmdline.h>
+#include <freerdp/channels/channels.h>
+
+typedef struct shw_context shwContext;
+
+#include "win_shadow.h"
+
+struct shw_context
+{
+ rdpContext context;
+ DEFINE_RDP_CLIENT_COMMON();
+
+ HANDLE StopEvent;
+ freerdp* instance;
+ rdpSettings* settings;
+ winShadowSubsystem* subsystem;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int win_shadow_rdp_init(winShadowSubsystem* subsystem);
+int win_shadow_rdp_uninit(winShadowSubsystem* subsystem);
+
+int win_shadow_rdp_start(winShadowSubsystem* subsystem);
+int win_shadow_rdp_stop(winShadowSubsystem* subsystem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_WIN_RDP_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ *
+ * Copyright 2011-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.
+ */
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/sysinfo.h>
+
+#include <freerdp/codec/color.h>
+#include <freerdp/codec/region.h>
+
+#include "../shadow_screen.h"
+#include "../shadow_surface.h"
+#include "../shadow_capture.h"
+
+#include "win_shadow.h"
+
+void win_shadow_input_synchronize_event(winShadowSubsystem* subsystem, UINT32 flags)
+{
+
+}
+
+void win_shadow_input_keyboard_event(winShadowSubsystem* subsystem, UINT16 flags, UINT16 code)
+{
+ INPUT event;
+
+ event.type = INPUT_KEYBOARD;
+ event.ki.wVk = 0;
+ event.ki.wScan = code;
+ event.ki.dwFlags = KEYEVENTF_SCANCODE;
+ event.ki.dwExtraInfo = 0;
+ event.ki.time = 0;
+
+ if (flags & KBD_FLAGS_RELEASE)
+ event.ki.dwFlags |= KEYEVENTF_KEYUP;
+
+ if (flags & KBD_FLAGS_EXTENDED)
+ event.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
+
+ SendInput(1, &event, sizeof(INPUT));
+}
+
+void win_shadow_input_unicode_keyboard_event(winShadowSubsystem* subsystem, UINT16 flags, UINT16 code)
+{
+ INPUT event;
+
+ event.type = INPUT_KEYBOARD;
+ event.ki.wVk = 0;
+ event.ki.wScan = code;
+ event.ki.dwFlags = KEYEVENTF_UNICODE;
+ event.ki.dwExtraInfo = 0;
+ event.ki.time = 0;
+
+ if (flags & KBD_FLAGS_RELEASE)
+ event.ki.dwFlags |= KEYEVENTF_KEYUP;
+
+ SendInput(1, &event, sizeof(INPUT));
+}
+
+void win_shadow_input_mouse_event(winShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y)
+{
+ INPUT event;
+ float width;
+ float height;
+
+ ZeroMemory(&event, sizeof(INPUT));
+
+ event.type = INPUT_MOUSE;
+
+ if (flags & PTR_FLAGS_WHEEL)
+ {
+ event.mi.dwFlags = MOUSEEVENTF_WHEEL;
+ event.mi.mouseData = flags & WheelRotationMask;
+
+ if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
+ event.mi.mouseData *= -1;
+
+ SendInput(1, &event, sizeof(INPUT));
+ }
+ else
+ {
+ width = (float) GetSystemMetrics(SM_CXSCREEN);
+ height = (float) GetSystemMetrics(SM_CYSCREEN);
+
+ event.mi.dx = (LONG) ((float) x * (65535.0f / width));
+ event.mi.dy = (LONG) ((float) y * (65535.0f / height));
+ event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE;
+
+ if (flags & PTR_FLAGS_MOVE)
+ {
+ event.mi.dwFlags |= MOUSEEVENTF_MOVE;
+ SendInput(1, &event, sizeof(INPUT));
+ }
+
+ event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE;
+
+ if (flags & PTR_FLAGS_BUTTON1)
+ {
+ if (flags & PTR_FLAGS_DOWN)
+ event.mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
+ else
+ event.mi.dwFlags |= MOUSEEVENTF_LEFTUP;
+
+ SendInput(1, &event, sizeof(INPUT));
+ }
+ else if (flags & PTR_FLAGS_BUTTON2)
+ {
+ if (flags & PTR_FLAGS_DOWN)
+ event.mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
+ else
+ event.mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
+
+ SendInput(1, &event, sizeof(INPUT));
+ }
+ else if (flags & PTR_FLAGS_BUTTON3)
+ {
+ if (flags & PTR_FLAGS_DOWN)
+ event.mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
+ else
+ event.mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
+
+ SendInput(1, &event, sizeof(INPUT));
+ }
+ }
+}
+
+void win_shadow_input_extended_mouse_event(winShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y)
+{
+ INPUT event;
+ float width;
+ float height;
+
+ ZeroMemory(&event, sizeof(INPUT));
+
+ if ((flags & PTR_XFLAGS_BUTTON1) || (flags & PTR_XFLAGS_BUTTON2))
+ {
+ event.type = INPUT_MOUSE;
+
+ if (flags & PTR_FLAGS_MOVE)
+ {
+ width = (float) GetSystemMetrics(SM_CXSCREEN);
+ height = (float) GetSystemMetrics(SM_CYSCREEN);
+
+ event.mi.dx = (LONG)((float) x * (65535.0f / width));
+ event.mi.dy = (LONG)((float) y * (65535.0f / height));
+ event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
+
+ SendInput(1, &event, sizeof(INPUT));
+ }
+
+ event.mi.dx = event.mi.dy = event.mi.dwFlags = 0;
+
+ if (flags & PTR_XFLAGS_DOWN)
+ event.mi.dwFlags |= MOUSEEVENTF_XDOWN;
+ else
+ event.mi.dwFlags |= MOUSEEVENTF_XUP;
+
+ if (flags & PTR_XFLAGS_BUTTON1)
+ event.mi.mouseData = XBUTTON1;
+ else if (flags & PTR_XFLAGS_BUTTON2)
+ event.mi.mouseData = XBUTTON2;
+
+ SendInput(1, &event, sizeof(INPUT));
+ }
+}
+
+
+int win_shadow_invalidate_region(winShadowSubsystem* subsystem, int x, int y, int width, int height)
+{
+ rdpShadowServer* server;
+ rdpShadowScreen* screen;
+ RECTANGLE_16 invalidRect;
+
+ server = subsystem->server;
+ screen = server->screen;
+
+ invalidRect.left = x;
+ invalidRect.top = y;
+ invalidRect.right = x + width;
+ invalidRect.bottom = y + height;
+
+ EnterCriticalSection(&(screen->lock));
+ region16_union_rect(&(screen->invalidRegion), &(screen->invalidRegion), &invalidRect);
+ LeaveCriticalSection(&(screen->lock));
+
+ return 1;
+}
+
+int win_shadow_surface_copy(winShadowSubsystem* subsystem)
+{
+ int x, y;
+ int width;
+ int height;
+ int count;
+ int status = 1;
+ int nDstStep = 0;
+ BYTE* pDstData = NULL;
+ rdpShadowServer* server;
+ rdpShadowSurface* surface;
+ RECTANGLE_16 surfaceRect;
+ RECTANGLE_16 invalidRect;
+ const RECTANGLE_16* extents;
+
+ server = subsystem->server;
+ surface = server->surface;
+
+ if (ArrayList_Count(server->clients) < 1)
+ {
+ region16_clear(&(subsystem->invalidRegion));
+ return 1;
+ }
+
+ surfaceRect.left = surface->x;
+ surfaceRect.top = surface->y;
+ surfaceRect.right = surface->x + surface->width;
+ surfaceRect.bottom = surface->y + surface->height;
+
+ region16_intersect_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &surfaceRect);
+
+ if (region16_is_empty(&(subsystem->invalidRegion)))
+ return 1;
+
+ extents = region16_extents(&(subsystem->invalidRegion));
+ CopyMemory(&invalidRect, extents, sizeof(RECTANGLE_16));
+
+ shadow_capture_align_clip_rect(&invalidRect, &surfaceRect);
+
+ x = invalidRect.left;
+ y = invalidRect.top;
+ width = invalidRect.right - invalidRect.left;
+ height = invalidRect.bottom - invalidRect.top;
+
+ if (0)
+ {
+ x = 0;
+ y = 0;
+ width = surface->width;
+ height = surface->height;
+ }
+
+ printf("SurfaceCopy x: %d y: %d width: %d height: %d right: %d bottom: %d\n",
+ x, y, width, height, x + width, y + height);
+
+#if defined(WITH_WDS_API)
+ {
+ rdpGdi* gdi;
+ shwContext* shw;
+ rdpContext* context;
+
+ shw = subsystem->shw;
+ context = (rdpContext*) shw;
+ gdi = context->gdi;
+
+ pDstData = gdi->primary_buffer;
+ nDstStep = gdi->width * 4;
+ }
+#elif defined(WITH_DXGI_1_2)
+ status = win_shadow_dxgi_fetch_frame_data(subsystem, &pDstData, &nDstStep, x, y, width, height);
+#endif
+
+ if (status <= 0)
+ return status;
+
+ freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
+ surface->scanline, x - surface->x, y - surface->y, width, height,
+ pDstData, PIXEL_FORMAT_XRGB32, nDstStep, 0, 0);
+
+ ArrayList_Lock(server->clients);
+
+ count = ArrayList_Count(server->clients);
+
+ InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);
+
+ SetEvent(subsystem->updateEvent);
+
+ EnterSynchronizationBarrier(&(subsystem->barrier), 0);
+ ResetEvent(subsystem->updateEvent);
+
+ DeleteSynchronizationBarrier(&(subsystem->barrier));
+
+ ArrayList_Unlock(server->clients);
+
+ region16_clear(&(subsystem->invalidRegion));
+
+ return 1;
+}
+
+#if defined(WITH_WDS_API)
+
+void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
+{
+ DWORD status;
+ DWORD nCount;
+ HANDLE events[32];
+ HANDLE StopEvent;
+
+ StopEvent = subsystem->server->StopEvent;
+
+ nCount = 0;
+ events[nCount++] = StopEvent;
+ events[nCount++] = subsystem->RdpUpdateEnterEvent;
+
+ while (1)
+ {
+ status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
+
+ if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
+ {
+ break;
+ }
+
+ if (WaitForSingleObject(subsystem->RdpUpdateEnterEvent, 0) == WAIT_OBJECT_0)
+ {
+ win_shadow_surface_copy(subsystem);
+ ResetEvent(subsystem->RdpUpdateEnterEvent);
+ SetEvent(subsystem->RdpUpdateLeaveEvent);
+ }
+ }
+
+ ExitThread(0);
+ return NULL;
+}
+
+#elif defined(WITH_DXGI_1_2)
+
+void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
+{
+ int fps;
+ DWORD status;
+ DWORD nCount;
+ UINT64 cTime;
+ DWORD dwTimeout;
+ DWORD dwInterval;
+ UINT64 frameTime;
+ HANDLE events[32];
+ HANDLE StopEvent;
+
+ StopEvent = subsystem->server->StopEvent;
+
+ nCount = 0;
+ events[nCount++] = StopEvent;
+
+ fps = 16;
+ dwInterval = 1000 / fps;
+ frameTime = GetTickCount64() + dwInterval;
+
+ while (1)
+ {
+ dwTimeout = INFINITE;
+
+ cTime = GetTickCount64();
+ dwTimeout = (DWORD) ((cTime > frameTime) ? 0 : frameTime - cTime);
+
+ status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout);
+
+ if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
+ {
+ break;
+ }
+
+ if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
+ {
+ int dxgi_status;
+
+ dxgi_status = win_shadow_dxgi_get_next_frame(subsystem);
+
+ if (dxgi_status > 0)
+ dxgi_status = win_shadow_dxgi_get_invalid_region(subsystem);
+
+ if (dxgi_status > 0)
+ win_shadow_surface_copy(subsystem);
+
+ dwInterval = 1000 / fps;
+ frameTime += dwInterval;
+ }
+ }
+
+ ExitThread(0);
+ return NULL;
+}
+
+#endif
+
+int win_shadow_subsystem_init(winShadowSubsystem* subsystem)
+{
+ HDC hdc;
+ int status;
+ DWORD iDevNum = 0;
+ MONITOR_DEF* virtualScreen;
+ DISPLAY_DEVICE DisplayDevice;
+
+ ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
+ DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
+
+ if (!EnumDisplayDevices(NULL, iDevNum, &DisplayDevice, 0))
+ return -1;
+
+ hdc = CreateDC(DisplayDevice.DeviceName, NULL, NULL, NULL);
+
+ subsystem->width = GetDeviceCaps(hdc, HORZRES);
+ subsystem->height = GetDeviceCaps(hdc, VERTRES);
+ subsystem->bpp = GetDeviceCaps(hdc, BITSPIXEL);
+
+ DeleteDC(hdc);
+
+#if defined(WITH_WDS_API)
+ status = win_shadow_wds_init(subsystem);
+#elif defined(WITH_DXGI_1_2)
+ status = win_shadow_dxgi_init(subsystem);
+#endif
+
+ virtualScreen = &(subsystem->virtualScreen);
+
+ virtualScreen->left = 0;
+ virtualScreen->top = 0;
+ virtualScreen->right = subsystem->width;
+ virtualScreen->bottom = subsystem->height;
+ virtualScreen->flags = 1;
+
+ if (subsystem->monitorCount < 1)
+ {
+ subsystem->monitorCount = 1;
+ subsystem->monitors[0].left = virtualScreen->left;
+ subsystem->monitors[0].top = virtualScreen->top;
+ subsystem->monitors[0].right = virtualScreen->right;
+ subsystem->monitors[0].bottom = virtualScreen->bottom;
+ subsystem->monitors[0].flags = 1;
+ }
+
+ printf("width: %d height: %d\n", subsystem->width, subsystem->height);
+
+ return 1;
+}
+
+int win_shadow_subsystem_uninit(winShadowSubsystem* subsystem)
+{
+ if (!subsystem)
+ return -1;
+
+#if defined(WITH_WDS_API)
+ win_shadow_wds_uninit(subsystem);
+#elif defined(WITH_DXGI_1_2)
+ win_shadow_dxgi_uninit(subsystem);
+#endif
+
+ return 1;
+}
+
+int win_shadow_subsystem_start(winShadowSubsystem* subsystem)
+{
+ HANDLE thread;
+
+ if (!subsystem)
+ return -1;
+
+ thread = CreateThread(NULL, 0,
+ (LPTHREAD_START_ROUTINE) win_shadow_subsystem_thread,
+ (void*) subsystem, 0, NULL);
+
+ return 1;
+}
+
+int win_shadow_subsystem_stop(winShadowSubsystem* subsystem)
+{
+ if (!subsystem)
+ return -1;
+
+ return 1;
+}
+
+void win_shadow_subsystem_free(winShadowSubsystem* subsystem)
+{
+ if (!subsystem)
+ return;
+
+ win_shadow_subsystem_uninit(subsystem);
+
+ region16_uninit(&(subsystem->invalidRegion));
+
+ CloseHandle(subsystem->updateEvent);
+
+ free(subsystem);
+}
+
+winShadowSubsystem* win_shadow_subsystem_new(rdpShadowServer* server)
+{
+ winShadowSubsystem* subsystem;
+
+ subsystem = (winShadowSubsystem*) calloc(1, sizeof(winShadowSubsystem));
+
+ if (!subsystem)
+ return NULL;
+
+ subsystem->server = server;
+
+ subsystem->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ region16_init(&(subsystem->invalidRegion));
+
+ subsystem->Init = (pfnShadowSubsystemInit) win_shadow_subsystem_init;
+ subsystem->Uninit = (pfnShadowSubsystemInit) win_shadow_subsystem_uninit;
+ subsystem->Start = (pfnShadowSubsystemStart) win_shadow_subsystem_start;
+ subsystem->Stop = (pfnShadowSubsystemStop) win_shadow_subsystem_stop;
+ subsystem->Free = (pfnShadowSubsystemFree) win_shadow_subsystem_free;
+
+ subsystem->SurfaceCopy = (pfnShadowSurfaceCopy) win_shadow_surface_copy;
+
+ subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) win_shadow_input_synchronize_event;
+ subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) win_shadow_input_keyboard_event;
+ subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) win_shadow_input_unicode_keyboard_event;
+ subsystem->MouseEvent = (pfnShadowMouseEvent) win_shadow_input_mouse_event;
+ subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent) win_shadow_input_extended_mouse_event;
+
+ return subsystem;
+}
+
+rdpShadowSubsystem* Win_ShadowCreateSubsystem(rdpShadowServer* server)
+{
+ return (rdpShadowSubsystem*) win_shadow_subsystem_new(server);
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ *
+ * Copyright 2011-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_SHADOW_SERVER_WIN_H
+#define FREERDP_SHADOW_SERVER_WIN_H
+
+#include <freerdp/assistance.h>
+
+#include <freerdp/server/shadow.h>
+
+typedef struct win_shadow_subsystem winShadowSubsystem;
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+#include <winpr/stream.h>
+#include <winpr/collections.h>
+
+#include "win_rdp.h"
+#include "win_wds.h"
+#include "win_dxgi.h"
+
+struct win_shadow_subsystem
+{
+ RDP_SHADOW_SUBSYSTEM_COMMON();
+
+ int bpp;
+ int width;
+ int height;
+
+#ifdef WITH_WDS_API
+ HWND hWnd;
+ shwContext* shw;
+ HANDLE RdpUpdateEnterEvent;
+ HANDLE RdpUpdateLeaveEvent;
+ rdpAssistanceFile* pAssistanceFile;
+ _IRDPSessionEvents* pSessionEvents;
+ IRDPSRAPISharingSession* pSharingSession;
+ IRDPSRAPIInvitation* pInvitation;
+ IRDPSRAPIInvitationManager* pInvitationMgr;
+ IRDPSRAPISessionProperties* pSessionProperties;
+ IRDPSRAPIVirtualChannelManager* pVirtualChannelMgr;
+ IRDPSRAPIApplicationFilter* pApplicationFilter;
+ IRDPSRAPIAttendeeManager* pAttendeeMgr;
+#endif
+
+#ifdef WITH_DXGI_1_2
+ UINT pendingFrames;
+ BYTE* MetadataBuffer;
+ UINT MetadataBufferSize;
+ BOOL dxgiSurfaceMapped;
+ BOOL dxgiFrameAcquired;
+ ID3D11Device* dxgiDevice;
+ IDXGISurface* dxgiSurface;
+ ID3D11Texture2D* dxgiStage;
+ IDXGIResource* dxgiResource;
+ D3D_FEATURE_LEVEL featureLevel;
+ ID3D11Texture2D* dxgiDesktopImage;
+ DXGI_OUTDUPL_FRAME_INFO dxgiFrameInfo;
+ ID3D11DeviceContext* dxgiDeviceContext;
+ IDXGIOutputDuplication* dxgiOutputDuplication;
+#endif
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_WIN_H */
--- /dev/null
+/**
+ * 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 <winpr/crt.h>
+#include <winpr/print.h>
+
+#include "win_rdp.h"
+
+#include "win_wds.h"
+
+/**
+ * Windows Desktop Sharing API:
+ * http://blogs.msdn.com/b/rds/archive/2007/03/08/windows-desktop-sharing-api.aspx
+ *
+ * Windows Desktop Sharing Interfaces:
+ * http://msdn.microsoft.com/en-us/library/aa373871%28v=vs.85%29.aspx
+ *
+ * Offer Remote Assistance Sample C:
+ * http://msdn.microsoft.com/en-us/library/ms811079.aspx#remoteassistanceapi_topic2b
+ *
+ * Remote Assistance in XP: Programmatically establish an RDP session:
+ * http://www.codeproject.com/Articles/29939/Remote-Assistance-in-XP-Programmatically-establish
+ */
+
+#undef DEFINE_GUID
+#define INITGUID
+
+#include <initguid.h>
+
+DEFINE_GUID(CLSID_RDPSession,0x9B78F0E6,0x3E05,0x4A5B,0xB2,0xE8,0xE7,0x43,0xA8,0x95,0x6B,0x65);
+DEFINE_GUID(DIID__IRDPSessionEvents,0x98a97042,0x6698,0x40e9,0x8e,0xfd,0xb3,0x20,0x09,0x90,0x00,0x4b);
+DEFINE_GUID(IID_IRDPSRAPISharingSession,0xeeb20886,0xe470,0x4cf6,0x84,0x2b,0x27,0x39,0xc0,0xec,0x5c,0xfb);
+DEFINE_GUID(IID_IRDPSRAPIAttendee,0xec0671b3,0x1b78,0x4b80,0xa4,0x64,0x91,0x32,0x24,0x75,0x43,0xe3);
+DEFINE_GUID(IID_IRDPSRAPIAttendeeManager,0xba3a37e8,0x33da,0x4749,0x8d,0xa0,0x07,0xfa,0x34,0xda,0x79,0x44);
+DEFINE_GUID(IID_IRDPSRAPISessionProperties,0x339b24f2,0x9bc0,0x4f16,0x9a,0xac,0xf1,0x65,0x43,0x3d,0x13,0xd4);
+DEFINE_GUID(CLSID_RDPSRAPIApplicationFilter,0xe35ace89,0xc7e8,0x427e,0xa4,0xf9,0xb9,0xda,0x07,0x28,0x26,0xbd);
+DEFINE_GUID(CLSID_RDPSRAPIInvitationManager,0x53d9c9db,0x75ab,0x4271,0x94,0x8a,0x4c,0x4e,0xb3,0x6a,0x8f,0x2b);
+
+static ULONG Shadow_IRDPSessionEvents_RefCount = 0;
+
+const char* GetRDPSessionEventString(DISPID id)
+{
+ switch (id)
+ {
+ case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_CONNECTED:
+ return "OnAttendeeConnected";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_DISCONNECTED:
+ return "OnAttendeeDisconnected";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_UPDATE:
+ return "OnAttendeeUpdate";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_ERROR:
+ return "OnError";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTED:
+ return "OnConnectionEstablished";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIEWER_DISCONNECTED:
+ return "OnConnectionTerminated";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIEWER_AUTHENTICATED:
+ return "OnConnectionAuthenticated";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTFAILED:
+ return "OnConnectionFailed";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_CTRLLEVEL_CHANGE_REQUEST:
+ return "OnControlLevelChangeRequest";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_PAUSED:
+ return "OnGraphicsStreamPaused";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_RESUMED:
+ return "OnGraphicsStreamResumed";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_JOIN:
+ return "OnChannelJoin";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_LEAVE:
+ return "OnChannelLeave";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_DATARECEIVED:
+ return "OnChannelDataReceived";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_SENDCOMPLETED:
+ return "OnChannelDataSent";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_OPEN:
+ return "OnApplicationOpen";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_CLOSE:
+ return "OnApplicationClose";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_UPDATE:
+ return "OnApplicationUpdate";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_WINDOW_OPEN:
+ return "OnWindowOpen";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_WINDOW_CLOSE:
+ return "OnWindowClose";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_WINDOW_UPDATE:
+ return "OnWindowUpdate";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_APPFILTER_UPDATE:
+ return "OnAppFilterUpdate";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_SHARED_RECT_CHANGED:
+ return "OnSharedRectChanged";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_FOCUSRELEASED:
+ return "OnFocusReleased";
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_SHARED_DESKTOP_SETTINGS_CHANGED:
+ return "OnSharedDesktopSettingsChanged";
+ break;
+
+ case DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED:
+ return "OnViewingSizeChanged";
+ break;
+ }
+
+ return "OnUnknown";
+}
+
+static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_QueryInterface(
+ __RPC__in _IRDPSessionEvents * This,
+ /* [in] */ __RPC__in REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject)
+{
+ *ppvObject = NULL;
+
+ if (IsEqualIID(riid, &DIID__IRDPSessionEvents) ||
+ IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown))
+ {
+ *ppvObject = This;
+ }
+
+ if (!(*ppvObject))
+ return E_NOINTERFACE;
+
+ This->lpVtbl->AddRef(This);
+
+ return S_OK;
+}
+
+static ULONG STDMETHODCALLTYPE Shadow_IRDPSessionEvents_AddRef(
+ __RPC__in _IRDPSessionEvents * This)
+{
+ Shadow_IRDPSessionEvents_RefCount++;
+ return Shadow_IRDPSessionEvents_RefCount;
+}
+
+static ULONG STDMETHODCALLTYPE Shadow_IRDPSessionEvents_Release(
+ __RPC__in _IRDPSessionEvents * This)
+{
+ if (!Shadow_IRDPSessionEvents_RefCount)
+ return 0;
+
+ Shadow_IRDPSessionEvents_RefCount--;
+
+ return Shadow_IRDPSessionEvents_RefCount;
+}
+
+static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_GetTypeInfoCount(
+ __RPC__in _IRDPSessionEvents * This,
+ /* [out] */ __RPC__out UINT *pctinfo)
+{
+ printf("Shadow_IRDPSessionEvents_GetTypeInfoCount\n");
+ *pctinfo = 1;
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_GetTypeInfo(
+ __RPC__in _IRDPSessionEvents * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo)
+{
+ printf("Shadow_IRDPSessionEvents_GetTypeInfo\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_GetIDsOfNames(
+ __RPC__in _IRDPSessionEvents * This,
+ /* [in] */ __RPC__in REFIID riid,
+ /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
+ /* [range][in] */ __RPC__in_range(0,16384) UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId)
+{
+ printf("Shadow_IRDPSessionEvents_GetIDsOfNames\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_Invoke(
+ _IRDPSessionEvents * This,
+ /* [annotation][in] */
+ _In_ DISPID dispIdMember,
+ /* [annotation][in] */
+ _In_ REFIID riid,
+ /* [annotation][in] */
+ _In_ LCID lcid,
+ /* [annotation][in] */
+ _In_ WORD wFlags,
+ /* [annotation][out][in] */
+ _In_ DISPPARAMS *pDispParams,
+ /* [annotation][out] */
+ _Out_opt_ VARIANT *pVarResult,
+ /* [annotation][out] */
+ _Out_opt_ EXCEPINFO *pExcepInfo,
+ /* [annotation][out] */
+ _Out_opt_ UINT *puArgErr)
+{
+ HRESULT hr;
+ VARIANT vr;
+ UINT uArgErr;
+
+ printf("%s (%d)\n", GetRDPSessionEventString(dispIdMember), dispIdMember);
+
+ switch (dispIdMember)
+ {
+ case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_CONNECTED:
+ {
+ int level;
+ IDispatch* pDispatch;
+ IRDPSRAPIAttendee* pAttendee;
+
+ vr.vt = VT_DISPATCH;
+ vr.pdispVal = NULL;
+
+ hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &vr, &uArgErr);
+
+ if (FAILED(hr))
+ {
+ printf("%s DispGetParam(0, VT_DISPATCH) failure: 0x%08X\n",
+ GetRDPSessionEventString(dispIdMember), hr);
+ return hr;
+ }
+
+ pDispatch = vr.pdispVal;
+
+ hr = pDispatch->lpVtbl->QueryInterface(pDispatch, &IID_IRDPSRAPIAttendee, (void**) &pAttendee);
+
+ if (FAILED(hr))
+ {
+ printf("%s IDispatch::QueryInterface(IRDPSRAPIAttendee) failure: 0x%08X\n",
+ GetRDPSessionEventString(dispIdMember), hr);
+ return hr;
+ }
+
+ level = CTRL_LEVEL_VIEW;
+ //level = CTRL_LEVEL_INTERACTIVE;
+
+ hr = pAttendee->lpVtbl->put_ControlLevel(pAttendee, level);
+
+ if (FAILED(hr))
+ {
+ printf("%s IRDPSRAPIAttendee::put_ControlLevel() failure: 0x%08X\n",
+ GetRDPSessionEventString(dispIdMember), hr);
+ return hr;
+ }
+
+ pAttendee->lpVtbl->Release(pAttendee);
+ }
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_DISCONNECTED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_UPDATE:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_ERROR:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIEWER_DISCONNECTED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIEWER_AUTHENTICATED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTFAILED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_CTRLLEVEL_CHANGE_REQUEST:
+ {
+ int level;
+ IDispatch* pDispatch;
+ IRDPSRAPIAttendee* pAttendee;
+
+ vr.vt = VT_INT;
+ vr.pdispVal = NULL;
+
+ hr = DispGetParam(pDispParams, 1, VT_INT, &vr, &uArgErr);
+
+ if (FAILED(hr))
+ {
+ printf("%s DispGetParam(1, VT_INT) failure: 0x%08X\n",
+ GetRDPSessionEventString(dispIdMember), hr);
+ return hr;
+ }
+
+ level = vr.intVal;
+
+ vr.vt = VT_DISPATCH;
+ vr.pdispVal = NULL;
+
+ hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &vr, &uArgErr);
+
+ if (FAILED(hr))
+ {
+ printf("%s DispGetParam(0, VT_DISPATCH) failure: 0x%08X\n",
+ GetRDPSessionEventString(dispIdMember), hr);
+ return hr;
+ }
+
+ pDispatch = vr.pdispVal;
+
+ hr = pDispatch->lpVtbl->QueryInterface(pDispatch, &IID_IRDPSRAPIAttendee, (void**) &pAttendee);
+
+ if (FAILED(hr))
+ {
+ printf("%s IDispatch::QueryInterface(IRDPSRAPIAttendee) failure: 0x%08X\n",
+ GetRDPSessionEventString(dispIdMember), hr);
+ return hr;
+ }
+
+ hr = pAttendee->lpVtbl->put_ControlLevel(pAttendee, level);
+
+ if (FAILED(hr))
+ {
+ printf("%s IRDPSRAPIAttendee::put_ControlLevel() failure: 0x%08X\n",
+ GetRDPSessionEventString(dispIdMember), hr);
+ return hr;
+ }
+
+ pAttendee->lpVtbl->Release(pAttendee);
+ }
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_PAUSED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_RESUMED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_JOIN:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_LEAVE:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_DATARECEIVED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_SENDCOMPLETED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_OPEN:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_CLOSE:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_UPDATE:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_WINDOW_OPEN:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_WINDOW_CLOSE:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_WINDOW_UPDATE:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_APPFILTER_UPDATE:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_SHARED_RECT_CHANGED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_FOCUSRELEASED:
+ break;
+
+ case DISPID_RDPSRAPI_EVENT_ON_SHARED_DESKTOP_SETTINGS_CHANGED:
+ break;
+
+ case DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED:
+ break;
+ }
+
+ return S_OK;
+}
+
+static _IRDPSessionEventsVtbl Shadow_IRDPSessionEventsVtbl =
+{
+ /* IUnknown */
+ Shadow_IRDPSessionEvents_QueryInterface,
+ Shadow_IRDPSessionEvents_AddRef,
+ Shadow_IRDPSessionEvents_Release,
+
+ /* IDispatch */
+ Shadow_IRDPSessionEvents_GetTypeInfoCount,
+ Shadow_IRDPSessionEvents_GetTypeInfo,
+ Shadow_IRDPSessionEvents_GetIDsOfNames,
+ Shadow_IRDPSessionEvents_Invoke
+};
+
+static _IRDPSessionEvents Shadow_IRDPSessionEvents =
+{
+ &Shadow_IRDPSessionEventsVtbl
+};
+
+static LRESULT CALLBACK ShadowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_CLOSE:
+ DestroyWindow(hwnd);
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+
+ default:
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+ break;
+ }
+
+ return 0;
+}
+
+int win_shadow_wds_wnd_init(winShadowSubsystem* subsystem)
+{
+ HMODULE hModule;
+ HINSTANCE hInstance;
+ WNDCLASSEX wndClassEx;
+
+ hModule = GetModuleHandle(NULL);
+
+ ZeroMemory(&wndClassEx, sizeof(WNDCLASSEX));
+ wndClassEx.cbSize = sizeof(WNDCLASSEX);
+ wndClassEx.style = 0;
+ wndClassEx.lpfnWndProc = ShadowWndProc;
+ wndClassEx.cbClsExtra = 0;
+ wndClassEx.cbWndExtra = 0;
+ wndClassEx.hInstance = hModule;
+ wndClassEx.hIcon = NULL;
+ wndClassEx.hCursor = NULL;
+ wndClassEx.hbrBackground = NULL;
+ wndClassEx.lpszMenuName = _T("ShadowWndMenu");
+ wndClassEx.lpszClassName = _T("ShadowWndClass");
+ wndClassEx.hIconSm = NULL;
+
+ if (!RegisterClassEx(&wndClassEx))
+ {
+ printf("RegisterClassEx failure\n");
+ return -1;
+ }
+
+ hInstance = wndClassEx.hInstance;
+
+ subsystem->hWnd = CreateWindowEx(0, wndClassEx.lpszClassName,
+ 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hInstance, NULL);
+
+ if (!subsystem->hWnd)
+ {
+ printf("CreateWindowEx failure\n");
+ return -1;
+ }
+
+ return 1;
+}
+
+int win_shadow_wds_init(winShadowSubsystem* subsystem)
+{
+ int status;
+ HRESULT hr;
+ DWORD dwCookie;
+ long left, top;
+ long right, bottom;
+ long width, height;
+ IUnknown* pUnknown;
+ rdpSettings* settings;
+ BSTR bstrAuthString;
+ BSTR bstrGroupName;
+ BSTR bstrPassword;
+ BSTR bstrConnectionString;
+ BSTR bstrPropertyName;
+ VARIANT varPropertyValue;
+ rdpAssistanceFile* file;
+ IConnectionPoint* pCP;
+ IConnectionPointContainer* pCPC;
+
+ win_shadow_wds_wnd_init(subsystem);
+
+ hr = OleInitialize(NULL);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "OleInitialize() failure\n");
+ return -1;
+ }
+
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "CoInitialize() failure\n");
+ return -1;
+ }
+
+ hr = CoCreateInstance(&CLSID_RDPSession, NULL, CLSCTX_ALL,
+ &IID_IRDPSRAPISharingSession, (void**) &(subsystem->pSharingSession));
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "CoCreateInstance(IRDPSRAPISharingSession) failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ pUnknown = (IUnknown*) subsystem->pSharingSession;
+ hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IConnectionPointContainer, (void**) &pCPC);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "QueryInterface(IID_IConnectionPointContainer) failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ pCPC->lpVtbl->FindConnectionPoint(pCPC, &DIID__IRDPSessionEvents, &pCP);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IConnectionPointContainer::FindConnectionPoint(_IRDPSessionEvents) failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ dwCookie = 0;
+ subsystem->pSessionEvents = &Shadow_IRDPSessionEvents;
+ subsystem->pSessionEvents->lpVtbl->AddRef(subsystem->pSessionEvents);
+
+ hr = pCP->lpVtbl->Advise(pCP, (IUnknown*) subsystem->pSessionEvents, &dwCookie);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IConnectionPoint::Advise(Shadow_IRDPSessionEvents) failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ hr = subsystem->pSharingSession->lpVtbl->put_ColorDepth(subsystem->pSharingSession, 32);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISharingSession::put_ColorDepth() failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ hr = subsystem->pSharingSession->lpVtbl->GetDesktopSharedRect(subsystem->pSharingSession,
+ &left, &top, &right, &bottom);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISharingSession::GetDesktopSharedRect() failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ width = right - left;
+ height = bottom - top;
+
+ printf("GetDesktopSharedRect(): left: %d top: %d right: %d bottom: %d width: %d height: %d\n",
+ left, top, right, bottom, width, height);
+
+ hr = subsystem->pSharingSession->lpVtbl->get_VirtualChannelManager(subsystem->pSharingSession,
+ &(subsystem->pVirtualChannelMgr));
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISharingSession::get_VirtualChannelManager() failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ hr = subsystem->pSharingSession->lpVtbl->get_ApplicationFilter(subsystem->pSharingSession,
+ &(subsystem->pApplicationFilter));
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISharingSession::get_ApplicationFilter() failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ hr = subsystem->pSharingSession->lpVtbl->get_Attendees(subsystem->pSharingSession,
+ &(subsystem->pAttendeeMgr));
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISharingSession::get_Attendees() failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ hr = subsystem->pSharingSession->lpVtbl->get_Properties(subsystem->pSharingSession, &(subsystem->pSessionProperties));
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISharingSession::get_Properties() failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ bstrPropertyName = SysAllocString(L"PortId");
+ varPropertyValue.vt = VT_I4;
+ varPropertyValue.intVal = 40000;
+
+ hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties,
+ bstrPropertyName, varPropertyValue);
+
+ SysFreeString(bstrPropertyName);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISessionProperties::put_Property(PortId) failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ bstrPropertyName = SysAllocString(L"DrvConAttach");
+ varPropertyValue.vt = VT_BOOL;
+ varPropertyValue.boolVal = VARIANT_TRUE;
+
+ hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties,
+ bstrPropertyName, varPropertyValue);
+
+ SysFreeString(bstrPropertyName);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISessionProperties::put_Property(DrvConAttach) failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ bstrPropertyName = SysAllocString(L"PortProtocol");
+ varPropertyValue.vt = VT_I4;
+
+ //varPropertyValue.intVal = 0; // AF_UNSPEC
+ varPropertyValue.intVal = 2; // AF_INET
+ //varPropertyValue.intVal = 23; // AF_INET6
+
+ hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties,
+ bstrPropertyName, varPropertyValue);
+
+ SysFreeString(bstrPropertyName);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISessionProperties::put_Property(PortProtocol) failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ hr = subsystem->pSharingSession->lpVtbl->Open(subsystem->pSharingSession);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISharingSession::Open() failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ hr = subsystem->pSharingSession->lpVtbl->get_Invitations(subsystem->pSharingSession,
+ &(subsystem->pInvitationMgr));
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPISharingSession::get_Invitations() failure\n");
+ return -1;
+ }
+
+ bstrAuthString = SysAllocString(L"Shadow");
+ bstrGroupName = SysAllocString(L"ShadowGroup");
+ bstrPassword = SysAllocString(L"Shadow123!");
+
+ hr = subsystem->pInvitationMgr->lpVtbl->CreateInvitation(subsystem->pInvitationMgr, bstrAuthString,
+ bstrGroupName, bstrPassword, 5, &(subsystem->pInvitation));
+
+ SysFreeString(bstrAuthString);
+ SysFreeString(bstrGroupName);
+ SysFreeString(bstrPassword);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPIInvitationManager::CreateInvitation() failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ subsystem->pInvitation->lpVtbl->get_ConnectionString(subsystem->pInvitation, &bstrConnectionString);
+
+ if (FAILED(hr))
+ {
+ fprintf(stderr, "IRDPSRAPIInvitation::get_ConnectionString() failure: 0x%08X\n", hr);
+ return -1;
+ }
+
+ file = subsystem->pAssistanceFile = freerdp_assistance_file_new();
+
+ ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) bstrConnectionString,
+ ((UINT32*) bstrConnectionString)[-1], &(file->ConnectionString2), 0, NULL, NULL);
+
+ status = freerdp_assistance_parse_connection_string2(file);
+
+ if (status < 0)
+ return -1;
+
+ printf("ConnectionString: %s\n", file->ConnectionString2);
+
+ if (0)
+ {
+ FILE* fp;
+ size_t size;
+
+ fp = fopen("inv.xml", "w+b");
+
+ if (fp)
+ {
+ size = strlen(file->ConnectionString2);
+ fwrite(file->ConnectionString2, 1, size, fp);
+ fwrite("\r\n", 1, 2, fp);
+ fclose(fp);
+ }
+ }
+
+ status = win_shadow_rdp_init(subsystem);
+
+ if (status < 0)
+ {
+ printf("win_shadow_rdp_init() failure: %d\n", status);
+ return status;
+ }
+
+ settings = subsystem->shw->settings;
+
+ freerdp_set_param_bool(settings, FreeRDP_RemoteAssistanceMode, TRUE);
+
+ freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceSessionId, file->RASessionId);
+
+ freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceRCTicket, file->ConnectionString2);
+
+ freerdp_set_param_string(settings, FreeRDP_Domain, "RDP");
+ freerdp_set_param_string(settings, FreeRDP_Username, "Shadow");
+ freerdp_set_param_string(settings, FreeRDP_RemoteAssistancePassword, "Shadow123!");
+ freerdp_set_param_bool(settings, FreeRDP_AutoLogonEnabled, TRUE);
+
+ freerdp_set_param_string(settings, FreeRDP_ServerHostname, file->MachineAddress);
+ freerdp_set_param_uint32(settings, FreeRDP_ServerPort, file->MachinePort);
+
+ freerdp_set_param_uint32(settings, FreeRDP_DesktopWidth, width);
+ freerdp_set_param_uint32(settings, FreeRDP_DesktopHeight, height);
+
+ status = win_shadow_rdp_start(subsystem);
+
+ if (status < 0)
+ {
+ printf("win_shadow_rdp_start() failure: %d\n", status);
+ return status;
+ }
+
+ return 1;
+}
+
+int win_shadow_wds_uninit(winShadowSubsystem* subsystem)
+{
+ if (subsystem->pSharingSession)
+ {
+ subsystem->pSharingSession->lpVtbl->Close(subsystem->pSharingSession);
+ subsystem->pSharingSession->lpVtbl->Release(subsystem->pSharingSession);
+ subsystem->pSharingSession = NULL;
+ }
+
+ if (subsystem->pVirtualChannelMgr)
+ {
+ subsystem->pVirtualChannelMgr->lpVtbl->Release(subsystem->pVirtualChannelMgr);
+ subsystem->pVirtualChannelMgr = NULL;
+ }
+
+ if (subsystem->pApplicationFilter)
+ {
+ subsystem->pApplicationFilter->lpVtbl->Release(subsystem->pApplicationFilter);
+ subsystem->pApplicationFilter = NULL;
+ }
+
+ if (subsystem->pAttendeeMgr)
+ {
+ subsystem->pAttendeeMgr->lpVtbl->Release(subsystem->pAttendeeMgr);
+ subsystem->pAttendeeMgr = NULL;
+ }
+
+ if (subsystem->pSessionProperties)
+ {
+ subsystem->pSessionProperties->lpVtbl->Release(subsystem->pSessionProperties);
+ subsystem->pSessionProperties = NULL;
+ }
+
+ if (subsystem->pInvitationMgr)
+ {
+ subsystem->pInvitationMgr->lpVtbl->Release(subsystem->pInvitationMgr);
+ subsystem->pInvitationMgr = NULL;
+ }
+
+ if (subsystem->pInvitation)
+ {
+ subsystem->pInvitation->lpVtbl->Release(subsystem->pInvitation);
+ subsystem->pInvitation = NULL;
+ }
+
+ if (subsystem->pAssistanceFile)
+ {
+ freerdp_assistance_file_free(subsystem->pAssistanceFile);
+ subsystem->pAssistanceFile = NULL;
+ }
+
+ if (subsystem->hWnd)
+ {
+ DestroyWindow(subsystem->hWnd);
+ subsystem->hWnd = NULL;
+ }
+
+ if (subsystem->shw)
+ {
+ win_shadow_rdp_uninit(subsystem);
+ subsystem->shw = NULL;
+ }
+
+ return 1;
+}
--- /dev/null
+/**
+ * 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 FREERDP_SHADOW_SERVER_WIN_WDS_H
+#define FREERDP_SHADOW_SERVER_WIN_WDS_H
+
+#define WITH_WDS_API 1
+
+#ifndef CINTERFACE
+#define CINTERFACE
+#endif
+
+#include <rdpencomapi.h>
+
+#ifndef DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED
+#define DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED 340
+#endif
+
+#include "win_shadow.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int win_shadow_wds_init(winShadowSubsystem* subsystem);
+int win_shadow_wds_uninit(winShadowSubsystem* subsystem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_WIN_WDS_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ *
+ * Copyright 2011-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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/select.h>
+#include <sys/signal.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/sysinfo.h>
+
+#include <freerdp/codec/color.h>
+#include <freerdp/codec/region.h>
+
+#include "../shadow_screen.h"
+#include "../shadow_capture.h"
+#include "../shadow_surface.h"
+
+#include "x11_shadow.h"
+
+void x11_shadow_input_synchronize_event(x11ShadowSubsystem* subsystem, UINT32 flags)
+{
+
+}
+
+void x11_shadow_input_keyboard_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 code)
+{
+#ifdef WITH_XTEST
+ DWORD vkcode;
+ DWORD keycode;
+ BOOL extended = FALSE;
+
+ if (flags & KBD_FLAGS_EXTENDED)
+ extended = TRUE;
+
+ if (extended)
+ code |= KBDEXT;
+
+ vkcode = GetVirtualKeyCodeFromVirtualScanCode(code, 4);
+ keycode = GetKeycodeFromVirtualKeyCode(vkcode, KEYCODE_TYPE_EVDEV);
+
+ if (keycode != 0)
+ {
+ XTestGrabControl(subsystem->display, True);
+
+ if (flags & KBD_FLAGS_DOWN)
+ XTestFakeKeyEvent(subsystem->display, keycode, True, 0);
+ else if (flags & KBD_FLAGS_RELEASE)
+ XTestFakeKeyEvent(subsystem->display, keycode, False, 0);
+
+ XTestGrabControl(subsystem->display, False);
+ }
+#endif
+}
+
+void x11_shadow_input_unicode_keyboard_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 code)
+{
+
+}
+
+void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y)
+{
+#ifdef WITH_XTEST
+ int button = 0;
+ BOOL down = FALSE;
+
+ XTestGrabControl(subsystem->display, True);
+
+ if (flags & PTR_FLAGS_WHEEL)
+ {
+ BOOL negative = FALSE;
+
+ if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
+ negative = TRUE;
+
+ button = (negative) ? 5 : 4;
+
+ XTestFakeButtonEvent(subsystem->display, button, True, 0);
+ XTestFakeButtonEvent(subsystem->display, button, False, 0);
+ }
+ else
+ {
+ if (flags & PTR_FLAGS_MOVE)
+ XTestFakeMotionEvent(subsystem->display, 0, x, y, 0);
+
+ if (flags & PTR_FLAGS_BUTTON1)
+ button = 1;
+ else if (flags & PTR_FLAGS_BUTTON2)
+ button = 3;
+ else if (flags & PTR_FLAGS_BUTTON3)
+ button = 2;
+
+ if (flags & PTR_FLAGS_DOWN)
+ down = TRUE;
+
+ if (button != 0)
+ XTestFakeButtonEvent(subsystem->display, button, down, 0);
+ }
+
+ XTestGrabControl(subsystem->display, False);
+#endif
+}
+
+void x11_shadow_input_extended_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y)
+{
+#ifdef WITH_XTEST
+ int button = 0;
+ BOOL down = FALSE;
+
+ XTestGrabControl(subsystem->display, True);
+ XTestFakeMotionEvent(subsystem->display, 0, x, y, CurrentTime);
+
+ if (flags & PTR_XFLAGS_BUTTON1)
+ button = 8;
+ else if (flags & PTR_XFLAGS_BUTTON2)
+ button = 9;
+
+ if (flags & PTR_XFLAGS_DOWN)
+ down = TRUE;
+
+ if (button != 0)
+ XTestFakeButtonEvent(subsystem->display, button, down, 0);
+
+ XTestGrabControl(subsystem->display, False);
+#endif
+}
+
+void x11_shadow_validate_region(x11ShadowSubsystem* subsystem, int x, int y, int width, int height)
+{
+ XRectangle region;
+
+ if (!subsystem->use_xfixes || !subsystem->use_xdamage)
+ return;
+
+ region.x = x;
+ region.y = y;
+ region.width = width;
+ region.height = height;
+
+#ifdef WITH_XFIXES
+ XFixesSetRegion(subsystem->display, subsystem->xdamage_region, ®ion, 1);
+ XDamageSubtract(subsystem->display, subsystem->xdamage, subsystem->xdamage_region, None);
+#endif
+}
+
+int x11_shadow_invalidate_region(x11ShadowSubsystem* subsystem, int x, int y, int width, int height)
+{
+ rdpShadowServer* server;
+ RECTANGLE_16 invalidRect;
+
+ server = subsystem->server;
+
+ invalidRect.left = x;
+ invalidRect.top = y;
+ invalidRect.right = x + width;
+ invalidRect.bottom = y + height;
+
+ region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
+
+ return 1;
+}
+
+int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
+{
+ int count;
+ int status;
+ int x, y;
+ int width, height;
+ XImage* image;
+ rdpShadowScreen* screen;
+ rdpShadowServer* server;
+ rdpShadowSurface* surface;
+ RECTANGLE_16 invalidRect;
+
+ server = subsystem->server;
+ surface = server->surface;
+ screen = server->screen;
+
+ if (subsystem->use_xshm)
+ {
+ XLockDisplay(subsystem->display);
+
+ XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap,
+ subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0);
+
+ XSync(subsystem->display, False);
+
+ XUnlockDisplay(subsystem->display);
+
+ image = subsystem->fb_image;
+
+ status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
+ (BYTE*) image->data, image->bytes_per_line, &invalidRect);
+
+ if (status > 0)
+ {
+ x = invalidRect.left;
+ y = invalidRect.top;
+ width = invalidRect.right - invalidRect.left;
+ height = invalidRect.bottom - invalidRect.top;
+
+ freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
+ surface->scanline, x - surface->x, y - surface->y, width, height,
+ (BYTE*) image->data, PIXEL_FORMAT_XRGB32,
+ image->bytes_per_line, x, y);
+
+ region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
+
+ count = ArrayList_Count(server->clients);
+
+ InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);
+
+ SetEvent(subsystem->updateEvent);
+
+ EnterSynchronizationBarrier(&(subsystem->barrier), 0);
+
+ DeleteSynchronizationBarrier(&(subsystem->barrier));
+
+ ResetEvent(subsystem->updateEvent);
+
+ region16_clear(&(subsystem->invalidRegion));
+ }
+ }
+ else
+ {
+ XLockDisplay(subsystem->display);
+
+ image = XGetImage(subsystem->display, subsystem->root_window,
+ 0, 0, subsystem->width, subsystem->height, AllPlanes, ZPixmap);
+
+ XUnlockDisplay(subsystem->display);
+
+ status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
+ (BYTE*) image->data, image->bytes_per_line, &invalidRect);
+
+ if (status > 0)
+ {
+ x = invalidRect.left;
+ y = invalidRect.top;
+ width = invalidRect.right - invalidRect.left;
+ height = invalidRect.bottom - invalidRect.top;
+
+ freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
+ surface->scanline, x - surface->x, y - surface->y, width, height,
+ (BYTE*) image->data, PIXEL_FORMAT_XRGB32,
+ image->bytes_per_line, x, y);
+
+ region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
+
+ count = ArrayList_Count(server->clients);
+
+ InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);
+
+ SetEvent(subsystem->updateEvent);
+
+ EnterSynchronizationBarrier(&(subsystem->barrier), 0);
+
+ DeleteSynchronizationBarrier(&(subsystem->barrier));
+
+ ResetEvent(subsystem->updateEvent);
+
+ region16_clear(&(subsystem->invalidRegion));
+ }
+
+ XDestroyImage(image);
+ }
+
+ return 1;
+}
+
+void* x11_shadow_subsystem_thread(x11ShadowSubsystem* subsystem)
+{
+ int fps;
+ DWORD status;
+ DWORD nCount;
+ UINT64 cTime;
+ DWORD dwTimeout;
+ DWORD dwInterval;
+ UINT64 frameTime;
+ HANDLE events[32];
+ HANDLE StopEvent;
+
+ StopEvent = subsystem->server->StopEvent;
+
+ nCount = 0;
+ events[nCount++] = StopEvent;
+ events[nCount++] = subsystem->event;
+
+ fps = 16;
+ dwInterval = 1000 / fps;
+ frameTime = GetTickCount64() + dwInterval;
+
+ while (1)
+ {
+ cTime = GetTickCount64();
+ dwTimeout = (cTime > frameTime) ? 0 : frameTime - cTime;
+
+ status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout);
+
+ if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
+ {
+ break;
+ }
+
+ if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
+ {
+ x11_shadow_screen_grab(subsystem);
+
+ dwInterval = 1000 / fps;
+ frameTime += dwInterval;
+ }
+ }
+
+ ExitThread(0);
+ return NULL;
+}
+
+int x11_shadow_xfixes_init(x11ShadowSubsystem* subsystem)
+{
+#ifdef WITH_XFIXES
+ int xfixes_event;
+ int xfixes_error;
+ int major, minor;
+
+ if (!XFixesQueryExtension(subsystem->display, &xfixes_event, &xfixes_error))
+ return -1;
+
+ if (!XFixesQueryVersion(subsystem->display, &major, &minor))
+ return -1;
+
+ subsystem->xfixes_notify_event = xfixes_event + XFixesCursorNotify;
+
+ XFixesSelectCursorInput(subsystem->display, DefaultRootWindow(subsystem->display), XFixesDisplayCursorNotifyMask);
+
+ return 1;
+#else
+ return -1;
+#endif
+}
+
+int x11_shadow_xinerama_init(x11ShadowSubsystem* subsystem)
+{
+#ifdef WITH_XINERAMA
+ int index;
+ int numMonitors;
+ int major, minor;
+ int xinerama_event;
+ int xinerama_error;
+ MONITOR_DEF* monitor;
+ XineramaScreenInfo* screen;
+ XineramaScreenInfo* screens;
+
+ if (!XineramaQueryExtension(subsystem->display, &xinerama_event, &xinerama_error))
+ return -1;
+
+ if (!XDamageQueryVersion(subsystem->display, &major, &minor))
+ return -1;
+
+ if (!XineramaIsActive(subsystem->display))
+ return -1;
+
+ screens = XineramaQueryScreens(subsystem->display, &numMonitors);
+
+ if (numMonitors > 16)
+ numMonitors = 16;
+
+ if (!screens || (numMonitors < 1))
+ return -1;
+
+ subsystem->monitorCount = numMonitors;
+
+ for (index = 0; index < numMonitors; index++)
+ {
+ screen = &screens[index];
+ monitor = &(subsystem->monitors[index]);
+
+ monitor->left = screen->x_org;
+ monitor->top = screen->y_org;
+ monitor->right = monitor->left + screen->width;
+ monitor->bottom = monitor->top + screen->height;
+ monitor->flags = (index == 0) ? 1 : 0;
+ }
+
+ XFree(screens);
+#endif
+
+ return 1;
+}
+
+int x11_shadow_xdamage_init(x11ShadowSubsystem* subsystem)
+{
+#ifdef WITH_XDAMAGE
+ int major, minor;
+ int damage_event;
+ int damage_error;
+
+ if (!subsystem->use_xfixes)
+ return -1;
+
+ if (!XDamageQueryExtension(subsystem->display, &damage_event, &damage_error))
+ return -1;
+
+ if (!XDamageQueryVersion(subsystem->display, &major, &minor))
+ return -1;
+
+ if (major < 1)
+ return -1;
+
+ subsystem->xdamage_notify_event = damage_event + XDamageNotify;
+ subsystem->xdamage = XDamageCreate(subsystem->display, subsystem->root_window, XDamageReportDeltaRectangles);
+
+ if (!subsystem->xdamage)
+ return -1;
+
+#ifdef WITH_XFIXES
+ subsystem->xdamage_region = XFixesCreateRegion(subsystem->display, NULL, 0);
+
+ if (!subsystem->xdamage_region)
+ return -1;
+#endif
+
+ return 1;
+#else
+ return -1;
+#endif
+}
+
+int x11_shadow_xshm_init(x11ShadowSubsystem* subsystem)
+{
+ Bool pixmaps;
+ int major, minor;
+ XGCValues values;
+
+ if (!XShmQueryExtension(subsystem->display))
+ return -1;
+
+ if (!XShmQueryVersion(subsystem->display, &major, &minor, &pixmaps))
+ return -1;
+
+ if (!pixmaps)
+ return -1;
+
+ subsystem->fb_shm_info.shmid = -1;
+ subsystem->fb_shm_info.shmaddr = (char*) -1;
+ subsystem->fb_shm_info.readOnly = False;
+
+ subsystem->fb_image = XShmCreateImage(subsystem->display, subsystem->visual, subsystem->depth,
+ ZPixmap, NULL, &(subsystem->fb_shm_info), subsystem->width, subsystem->height);
+
+ if (!subsystem->fb_image)
+ {
+ fprintf(stderr, "XShmCreateImage failed\n");
+ return -1;
+ }
+
+ subsystem->fb_shm_info.shmid = shmget(IPC_PRIVATE,
+ subsystem->fb_image->bytes_per_line * subsystem->fb_image->height, IPC_CREAT | 0600);
+
+ if (subsystem->fb_shm_info.shmid == -1)
+ {
+ fprintf(stderr, "shmget failed\n");
+ return -1;
+ }
+
+ subsystem->fb_shm_info.shmaddr = shmat(subsystem->fb_shm_info.shmid, 0, 0);
+ subsystem->fb_image->data = subsystem->fb_shm_info.shmaddr;
+
+ if (subsystem->fb_shm_info.shmaddr == ((char*) -1))
+ {
+ fprintf(stderr, "shmat failed\n");
+ return -1;
+ }
+
+ if (!XShmAttach(subsystem->display, &(subsystem->fb_shm_info)))
+ return -1;
+
+ XSync(subsystem->display, False);
+
+ shmctl(subsystem->fb_shm_info.shmid, IPC_RMID, 0);
+
+ subsystem->fb_pixmap = XShmCreatePixmap(subsystem->display,
+ subsystem->root_window, subsystem->fb_image->data, &(subsystem->fb_shm_info),
+ subsystem->fb_image->width, subsystem->fb_image->height, subsystem->fb_image->depth);
+
+ XSync(subsystem->display, False);
+
+ if (!subsystem->fb_pixmap)
+ return -1;
+
+ values.subwindow_mode = IncludeInferiors;
+ values.graphics_exposures = False;
+
+ subsystem->xshm_gc = XCreateGC(subsystem->display, subsystem->root_window,
+ GCSubwindowMode | GCGraphicsExposures, &values);
+
+ XSetFunction(subsystem->display, subsystem->xshm_gc, GXcopy);
+ XSync(subsystem->display, False);
+
+ return 1;
+}
+
+int x11_shadow_subsystem_init(x11ShadowSubsystem* subsystem)
+{
+ int i;
+ int pf_count;
+ int vi_count;
+ int nextensions;
+ char** extensions;
+ XVisualInfo* vi;
+ XVisualInfo* vis;
+ XVisualInfo template;
+ XPixmapFormatValues* pf;
+ XPixmapFormatValues* pfs;
+ MONITOR_DEF* virtualScreen;
+
+ /**
+ * To see if your X11 server supports shared pixmaps, use:
+ * xdpyinfo -ext MIT-SHM | grep "shared pixmaps"
+ */
+
+ if (!getenv("DISPLAY"))
+ {
+ /* Set DISPLAY variable if not already set */
+ setenv("DISPLAY", ":0", 1);
+ }
+
+ if (!XInitThreads())
+ return -1;
+
+ subsystem->display = XOpenDisplay(NULL);
+
+ if (!subsystem->display)
+ {
+ fprintf(stderr, "failed to open display: %s\n", XDisplayName(NULL));
+ return -1;
+ }
+
+ extensions = XListExtensions(subsystem->display, &nextensions);
+
+ if (!extensions || (nextensions < 0))
+ return -1;
+
+ for (i = 0; i < nextensions; i++)
+ {
+ if (strcmp(extensions[i], "Composite") == 0)
+ subsystem->composite = TRUE;
+ }
+
+ XFreeExtensionList(extensions);
+
+ if (subsystem->composite)
+ subsystem->use_xdamage = FALSE;
+
+ if (!subsystem->use_xdamage)
+ subsystem->use_xfixes = FALSE;
+
+ subsystem->xfds = ConnectionNumber(subsystem->display);
+ subsystem->number = DefaultScreen(subsystem->display);
+ subsystem->screen = ScreenOfDisplay(subsystem->display, subsystem->number);
+ subsystem->depth = DefaultDepthOfScreen(subsystem->screen);
+ subsystem->width = WidthOfScreen(subsystem->screen);
+ subsystem->height = HeightOfScreen(subsystem->screen);
+ subsystem->root_window = DefaultRootWindow(subsystem->display);
+
+ pfs = XListPixmapFormats(subsystem->display, &pf_count);
+
+ if (!pfs)
+ {
+ fprintf(stderr, "XListPixmapFormats failed\n");
+ return -1;
+ }
+
+ for (i = 0; i < pf_count; i++)
+ {
+ pf = pfs + i;
+
+ if (pf->depth == subsystem->depth)
+ {
+ subsystem->bpp = pf->bits_per_pixel;
+ subsystem->scanline_pad = pf->scanline_pad;
+ break;
+ }
+ }
+ XFree(pfs);
+
+ ZeroMemory(&template, sizeof(template));
+ template.class = TrueColor;
+ template.screen = subsystem->number;
+
+ vis = XGetVisualInfo(subsystem->display, VisualClassMask | VisualScreenMask, &template, &vi_count);
+
+ if (!vis)
+ {
+ fprintf(stderr, "XGetVisualInfo failed\n");
+ return -1;
+ }
+
+ for (i = 0; i < vi_count; i++)
+ {
+ vi = vis + i;
+
+ if (vi->depth == subsystem->depth)
+ {
+ subsystem->visual = vi->visual;
+ break;
+ }
+ }
+ XFree(vis);
+
+ XSelectInput(subsystem->display, subsystem->root_window, SubstructureNotifyMask);
+
+ if (subsystem->use_xfixes)
+ {
+ if (x11_shadow_xfixes_init(subsystem) < 0)
+ subsystem->use_xfixes = FALSE;
+ }
+
+ if (subsystem->use_xinerama)
+ {
+ if (x11_shadow_xinerama_init(subsystem) < 0)
+ subsystem->use_xinerama = FALSE;
+ }
+
+ if (subsystem->use_xshm)
+ {
+ if (x11_shadow_xshm_init(subsystem) < 0)
+ subsystem->use_xshm = FALSE;
+ }
+
+ if (subsystem->use_xdamage)
+ {
+ if (x11_shadow_xdamage_init(subsystem) < 0)
+ subsystem->use_xdamage = FALSE;
+ }
+
+ subsystem->event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, subsystem->xfds);
+
+ virtualScreen = &(subsystem->virtualScreen);
+
+ virtualScreen->left = 0;
+ virtualScreen->top = 0;
+ virtualScreen->right = subsystem->width;
+ virtualScreen->bottom = subsystem->height;
+ virtualScreen->flags = 1;
+
+ if (subsystem->monitorCount < 1)
+ {
+ subsystem->monitorCount = 1;
+ subsystem->monitors[0].left = virtualScreen->left;
+ subsystem->monitors[0].top = virtualScreen->top;
+ subsystem->monitors[0].right = virtualScreen->right;
+ subsystem->monitors[0].bottom = virtualScreen->bottom;
+ subsystem->monitors[0].flags = 1;
+ }
+
+ printf("X11 Extensions: XFixes: %d Xinerama: %d XDamage: %d XShm: %d\n",
+ subsystem->use_xfixes, subsystem->use_xinerama, subsystem->use_xdamage, subsystem->use_xshm);
+
+ return 1;
+}
+
+int x11_shadow_subsystem_uninit(x11ShadowSubsystem* subsystem)
+{
+ if (!subsystem)
+ return -1;
+
+ if (subsystem->display)
+ {
+ XCloseDisplay(subsystem->display);
+ subsystem->display = NULL;
+ }
+
+ if (subsystem->event)
+ {
+ CloseHandle(subsystem->event);
+ subsystem->event = NULL;
+ }
+
+ return 1;
+}
+
+int x11_shadow_subsystem_start(x11ShadowSubsystem* subsystem)
+{
+ HANDLE thread;
+
+ if (!subsystem)
+ return -1;
+
+ thread = CreateThread(NULL, 0,
+ (LPTHREAD_START_ROUTINE) x11_shadow_subsystem_thread,
+ (void*) subsystem, 0, NULL);
+
+ return 1;
+}
+
+int x11_shadow_subsystem_stop(x11ShadowSubsystem* subsystem)
+{
+ if (!subsystem)
+ return -1;
+
+ return 1;
+}
+
+void x11_shadow_subsystem_free(x11ShadowSubsystem* subsystem)
+{
+ if (!subsystem)
+ return;
+
+ x11_shadow_subsystem_uninit(subsystem);
+
+ region16_uninit(&(subsystem->invalidRegion));
+
+ CloseHandle(subsystem->updateEvent);
+
+ free(subsystem);
+}
+
+x11ShadowSubsystem* x11_shadow_subsystem_new(rdpShadowServer* server)
+{
+ x11ShadowSubsystem* subsystem;
+
+ subsystem = (x11ShadowSubsystem*) calloc(1, sizeof(x11ShadowSubsystem));
+
+ if (!subsystem)
+ return NULL;
+
+ subsystem->server = server;
+
+ subsystem->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ region16_init(&(subsystem->invalidRegion));
+
+ subsystem->Init = (pfnShadowSubsystemInit) x11_shadow_subsystem_init;
+ subsystem->Uninit = (pfnShadowSubsystemInit) x11_shadow_subsystem_uninit;
+ subsystem->Start = (pfnShadowSubsystemStart) x11_shadow_subsystem_start;
+ subsystem->Stop = (pfnShadowSubsystemStop) x11_shadow_subsystem_stop;
+ subsystem->Free = (pfnShadowSubsystemFree) x11_shadow_subsystem_free;
+
+ subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) x11_shadow_input_synchronize_event;
+ subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) x11_shadow_input_keyboard_event;
+ subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) x11_shadow_input_unicode_keyboard_event;
+ subsystem->MouseEvent = (pfnShadowMouseEvent) x11_shadow_input_mouse_event;
+ subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent) x11_shadow_input_extended_mouse_event;
+
+ subsystem->composite = FALSE;
+ subsystem->use_xshm = TRUE;
+ subsystem->use_xfixes = TRUE;
+ subsystem->use_xdamage = FALSE;
+ subsystem->use_xinerama = TRUE;
+
+ return subsystem;
+}
+
+rdpShadowSubsystem* X11_ShadowCreateSubsystem(rdpShadowServer* server)
+{
+ return (rdpShadowSubsystem*) x11_shadow_subsystem_new(server);
+}
/**
* FreeRDP: A Remote Desktop Protocol Implementation
- * FreeRDP X11 Server
*
- * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2011-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.
* limitations under the License.
*/
-#ifndef __XFREERDP_H
-#define __XFREERDP_H
+#ifndef FREERDP_SHADOW_SERVER_X11_H
+#define FREERDP_SHADOW_SERVER_X11_H
-#include "xf_interface.h"
+#include <freerdp/server/shadow.h>
-#include <freerdp/api.h>
-#include <freerdp/freerdp.h>
-#include <freerdp/listener.h>
-#include <freerdp/codec/color.h>
+typedef struct x11_shadow_subsystem x11ShadowSubsystem;
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+#include <winpr/stream.h>
+#include <winpr/collections.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xdamage.h>
#endif
-struct xf_info
+#ifdef WITH_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+
+struct x11_shadow_subsystem
{
+ RDP_SHADOW_SUBSYSTEM_COMMON();
+
+ HANDLE thread;
+
int bpp;
int xfds;
int depth;
Visual* visual;
Display* display;
int scanline_pad;
- int bytesPerPixel;
- HCLRCONV clrconv;
+ BOOL composite;
+
BOOL use_xshm;
- int activePeerCount;
+ BOOL use_xfixes;
+ BOOL use_xdamage;
+ BOOL use_xinerama;
XImage* fb_image;
Pixmap fb_pixmap;
XShmSegmentInfo fb_shm_info;
#ifdef WITH_XDAMAGE
- GC xdamage_gc;
+ GC xshm_gc;
Damage xdamage;
int xdamage_notify_event;
XserverRegion xdamage_region;
#endif
};
-struct xf_server
-{
- DWORD port;
- HANDLE thread;
- freerdp_listener* listener;
-};
+#ifdef __cplusplus
+extern "C" {
+#endif
-void* xf_server_thread(void* param);
-#endif /* __XFREERDP_H */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_X11_H */
/**
* FreeRDP: A Remote Desktop Protocol Implementation
- * X11 RemoteFX Encoder
*
- * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * 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.
* limitations under the License.
*/
-#ifndef __XF_ENCODE_H
-#define __XF_ENCODE_H
+#ifndef FREERDP_SHADOW_SERVER_H
+#define FREERDP_SHADOW_SERVER_H
-#include "xfreerdp.h"
+#include <freerdp/server/shadow.h>
-#include "xf_peer.h"
+#include "shadow_client.h"
+#include "shadow_input.h"
+#include "shadow_screen.h"
+#include "shadow_surface.h"
+#include "shadow_encoder.h"
+#include "shadow_capture.h"
+#include "shadow_channels.h"
-XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height);
-void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height);
-int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_H */
-#endif /* __XF_ENCODE_H */
--- /dev/null
+/**
+ * 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 <winpr/crt.h>
+#include <winpr/print.h>
+
+#include "shadow_surface.h"
+
+#include "shadow_capture.h"
+
+int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip)
+{
+ int dx, dy;
+
+ dx = (rect->left % 16);
+
+ if (dx != 0)
+ {
+ rect->left -= dx;
+ rect->right += dx;
+ }
+
+ dx = (rect->right % 16);
+
+ if (dx != 0)
+ {
+ rect->right += (16 - dx);
+ }
+
+ dy = (rect->top % 16);
+
+ if (dy != 0)
+ {
+ rect->top -= dy;
+ rect->bottom += dy;
+ }
+
+ dy = (rect->bottom % 16);
+
+ if (dy != 0)
+ {
+ rect->bottom += (16 - dy);
+ }
+
+ if (rect->left < clip->left)
+ rect->left = clip->left;
+
+ if (rect->top < clip->top)
+ rect->top = clip->top;
+
+ if (rect->right > clip->right)
+ rect->right = clip->right;
+
+ if (rect->bottom > clip->bottom)
+ rect->bottom = clip->bottom;
+
+ return 1;
+}
+
+int shadow_capture_compare(BYTE* pData1, int nStep1, int nWidth, int nHeight, BYTE* pData2, int nStep2, RECTANGLE_16* rect)
+{
+ BOOL equal;
+ BOOL allEqual;
+ int tw, th;
+ int tx, ty, k;
+ int nrow, ncol;
+ int l, t, r, b;
+ BYTE *p1, *p2;
+ BOOL rows[1024];
+ BOOL cols[1024];
+ BOOL grid[1024][1024];
+
+ allEqual = TRUE;
+ FillMemory(rows, sizeof(rows), 0xFF);
+ FillMemory(cols, sizeof(cols), 0xFF);
+ FillMemory(grid, sizeof(grid), 0xFF);
+ ZeroMemory(rect, sizeof(RECTANGLE_16));
+
+ nrow = (nHeight + 15) / 16;
+ ncol = (nWidth + 15) / 16;
+
+ l = ncol + 1;
+ r = -1;
+
+ t = nrow + 1;
+ b = -1;
+
+ for (ty = 0; ty < nrow; ty++)
+ {
+ th = ((ty + 1) == nrow) ? (nHeight % 16) : 16;
+
+ if (!th)
+ th = 16;
+
+ for (tx = 0; tx < ncol; tx++)
+ {
+ equal = TRUE;
+
+ tw = ((tx + 1) == ncol) ? (nWidth % 16) : 16;
+
+ if (!tw)
+ tw = 16;
+
+ p1 = &pData1[(ty * 16 * nStep1) + (tx * 16 * 4)];
+ p2 = &pData2[(ty * 16 * nStep2) + (tx * 16 * 4)];
+
+ for (k = 0; k < th; k++)
+ {
+ if (memcmp(p1, p2, tw * 4) != 0)
+ {
+ equal = FALSE;
+ break;
+ }
+
+ p1 += nStep1;
+ p2 += nStep2;
+ }
+
+ if (!equal)
+ {
+ grid[ty][tx] = FALSE;
+ rows[ty] = FALSE;
+ cols[tx] = FALSE;
+
+ if (l > tx)
+ l = tx;
+
+ if (r < tx)
+ r = tx;
+ }
+ }
+
+ if (!rows[ty])
+ {
+ allEqual = FALSE;
+
+ if (t > ty)
+ t = ty;
+
+ if (b < ty)
+ b = ty;
+ }
+ }
+
+ if (allEqual)
+ return 0;
+
+ rect->left = l * 16;
+ rect->top = t * 16;
+ rect->right = (r + 1) * 16;
+ rect->bottom = (b + 1) * 16;
+
+ if (rect->right > nWidth)
+ rect->right = nWidth;
+
+ if (rect->bottom > nHeight)
+ rect->bottom = nHeight;
+
+ if (0)
+ {
+ printf("\n");
+
+ for (tx = 0; tx < ncol; tx++)
+ printf("-");
+ printf("\n");
+
+ for (tx = 0; tx < ncol; tx++)
+ printf("%s", cols[tx] ? "O" : "X");
+ printf("\n");
+
+ for (tx = 0; tx < ncol; tx++)
+ printf("-");
+ printf("\n");
+
+ for (ty = 0; ty < nrow; ty++)
+ {
+ for (tx = 0; tx < ncol; tx++)
+ {
+ printf("%s", grid[ty][tx] ? "O" : "X");
+ }
+
+ printf("|%s|\n", rows[ty] ? "O" : "X");
+ }
+
+ printf("left: %d top: %d right: %d bottom: %d ncol: %d nrow: %d\n",
+ l, t, r, b, ncol, nrow);
+ }
+
+ return 1;
+}
+
+rdpShadowCapture* shadow_capture_new(rdpShadowServer* server)
+{
+ rdpShadowCapture* capture;
+
+ capture = (rdpShadowCapture*) calloc(1, sizeof(rdpShadowCapture));
+
+ if (!capture)
+ return NULL;
+
+ capture->server = server;
+
+ if (!InitializeCriticalSectionAndSpinCount(&(capture->lock), 4000))
+ return NULL;
+
+ return capture;
+}
+
+void shadow_capture_free(rdpShadowCapture* capture)
+{
+ if (!capture)
+ return;
+
+ DeleteCriticalSection(&(capture->lock));
+
+ free(capture);
+}
+
--- /dev/null
+/**
+ * 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 FREERDP_SHADOW_SERVER_CAPTURE_H
+#define FREERDP_SHADOW_SERVER_CAPTURE_H
+
+#include <freerdp/server/shadow.h>
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+
+struct rdp_shadow_capture
+{
+ rdpShadowServer* server;
+
+ int width;
+ int height;
+
+ CRITICAL_SECTION lock;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip);
+int shadow_capture_compare(BYTE* pData1, int nStep1, int nWidth, int nHeight, BYTE* pData2, int nStep2, RECTANGLE_16* rect);
+
+rdpShadowCapture* shadow_capture_new(rdpShadowServer* server);
+void shadow_capture_free(rdpShadowCapture* capture);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_CAPTURE_H */
/**
* FreeRDP: A Remote Desktop Protocol Implementation
- * FreeRDP X11 Server
*
- * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * 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.
#include "config.h"
#endif
-#include "xf_interface.h"
+#include "shadow.h"
-int main(int argc, char* argv[])
-{
- HANDLE thread;
- xfServer* server;
- DWORD dwExitCode;
-
- freerdp_server_global_init();
-
- server = freerdp_server_new(argc, argv);
-
- if (!server)
- return 0;
-
- freerdp_server_start(server);
+#include "shadow_channels.h"
- thread = freerdp_server_get_thread(server);
-
- WaitForSingleObject(thread, INFINITE);
-
- GetExitCodeThread(thread, &dwExitCode);
-
- freerdp_server_free(server);
+int shadow_client_channels_post_connect(rdpShadowClient* client)
+{
+ if (WTSVirtualChannelManagerIsChannelJoined(client->vcm, ENCOMSP_SVC_CHANNEL_NAME))
+ {
+ shadow_client_encomsp_init(client);
+ }
- freerdp_server_global_uninit();
+ if (WTSVirtualChannelManagerIsChannelJoined(client->vcm, REMDESK_SVC_CHANNEL_NAME))
+ {
+ shadow_client_remdesk_init(client);
+ }
- return 0;
+ return 1;
}
--- /dev/null
+/**
+ * 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 FREERDP_SHADOW_SERVER_CHANNELS_H
+#define FREERDP_SHADOW_SERVER_CHANNELS_H
+
+#include <freerdp/server/shadow.h>
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+
+#include "shadow_encomsp.h"
+#include "shadow_remdesk.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int shadow_client_channels_post_connect(rdpShadowClient* client);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_CHANNELS_H */
--- /dev/null
+/**
+ * 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 <winpr/crt.h>
+#include <winpr/file.h>
+#include <winpr/path.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+#include <winpr/sysinfo.h>
+
+#include "shadow.h"
+
+void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
+{
+ rdpSettings* settings;
+ rdpShadowServer* server;
+
+ server = (rdpShadowServer*) peer->ContextExtra;
+ client->server = server;
+
+ settings = peer->settings;
+
+ settings->ColorDepth = 32;
+ settings->NSCodec = TRUE;
+ settings->RemoteFxCodec = TRUE;
+ settings->BitmapCacheV3Enabled = TRUE;
+ settings->FrameMarkerCommandEnabled = TRUE;
+ settings->SurfaceFrameMarkerEnabled = TRUE;
+
+ settings->RdpSecurity = TRUE;
+ settings->TlsSecurity = TRUE;
+ settings->NlaSecurity = FALSE;
+
+ settings->CertificateFile = _strdup(server->CertificateFile);
+ settings->PrivateKeyFile = _strdup(server->PrivateKeyFile);
+
+ settings->RdpKeyFile = _strdup(settings->PrivateKeyFile);
+
+ client->inLobby = TRUE;
+ client->mayView = server->mayView;
+ client->mayInteract = server->mayInteract;
+
+ InitializeCriticalSectionAndSpinCount(&(client->lock), 4000);
+
+ region16_init(&(client->invalidRegion));
+
+ client->vcm = WTSOpenServerA((LPSTR) peer->context);
+
+ client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ client->encoder = shadow_encoder_new(server);
+
+ ArrayList_Add(server->clients, (void*) client);
+}
+
+void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client)
+{
+ rdpShadowServer* server = client->server;
+
+ ArrayList_Remove(server->clients, (void*) client);
+
+ DeleteCriticalSection(&(client->lock));
+
+ region16_uninit(&(client->invalidRegion));
+
+ WTSCloseServer((HANDLE) client->vcm);
+
+ CloseHandle(client->StopEvent);
+
+ if (client->lobby)
+ {
+ shadow_surface_free(client->lobby);
+ client->lobby = NULL;
+ }
+
+ if (client->encoder)
+ {
+ shadow_encoder_free(client->encoder);
+ client->encoder = NULL;
+ }
+}
+
+BOOL shadow_client_capabilities(freerdp_peer* peer)
+{
+ return TRUE;
+}
+
+BOOL shadow_client_post_connect(freerdp_peer* peer)
+{
+ int width, height;
+ rdpSettings* settings;
+ rdpShadowClient* client;
+ rdpShadowSurface* lobby;
+ RECTANGLE_16 invalidRect;
+
+ client = (rdpShadowClient*) peer->context;
+ settings = peer->settings;
+
+ settings->DesktopWidth = client->server->screen->width;
+ settings->DesktopHeight = client->server->screen->height;
+
+ if (settings->ColorDepth == 24)
+ settings->ColorDepth = 16; /* disable 24bpp */
+
+ fprintf(stderr, "Client from %s is activated (%dx%d@%d)\n",
+ peer->hostname, settings->DesktopWidth, settings->DesktopHeight, settings->ColorDepth);
+
+ peer->update->DesktopResize(peer->update->context);
+
+ shadow_client_channels_post_connect(client);
+
+ width = settings->DesktopWidth;
+ height = settings->DesktopHeight;
+
+ invalidRect.left = 0;
+ invalidRect.top = 0;
+ invalidRect.right = width;
+ invalidRect.bottom = height;
+
+ region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &invalidRect);
+
+ lobby = client->lobby = shadow_surface_new(client->server, 0, 0, width, height);
+
+ if (!client->lobby)
+ return FALSE;
+
+ freerdp_image_fill(lobby->data, PIXEL_FORMAT_XRGB32, lobby->scanline,
+ 0, 0, lobby->width, lobby->height, 0x3BB9FF);
+
+ region16_union_rect(&(lobby->invalidRegion), &(lobby->invalidRegion), &invalidRect);
+
+ return TRUE;
+}
+
+BOOL shadow_client_activate(freerdp_peer* peer)
+{
+ rdpShadowClient* client;
+
+ client = (rdpShadowClient*) peer->context;
+
+ client->activated = TRUE;
+ client->inLobby = client->mayView ? FALSE : TRUE;
+
+ shadow_encoder_reset(client->encoder);
+
+ return TRUE;
+}
+
+void shadow_client_surface_frame_acknowledge(rdpShadowClient* client, UINT32 frameId)
+{
+ SURFACE_FRAME* frame;
+ wListDictionary* frameList;
+
+ frameList = client->encoder->frameList;
+ frame = (SURFACE_FRAME*) ListDictionary_GetItemValue(frameList, (void*) (size_t) frameId);
+
+ if (frame)
+ {
+ ListDictionary_Remove(frameList, (void*) (size_t) frameId);
+ free(frame);
+ }
+}
+
+void shadow_client_suppress_output(rdpShadowClient* client, BYTE allow, RECTANGLE_16* area)
+{
+
+}
+
+int shadow_client_send_surface_frame_marker(rdpShadowClient* client, UINT32 action, UINT32 id)
+{
+ SURFACE_FRAME_MARKER surfaceFrameMarker;
+ rdpContext* context = (rdpContext*) client;
+ rdpUpdate* update = context->update;
+
+ surfaceFrameMarker.frameAction = action;
+ surfaceFrameMarker.frameId = id;
+
+ IFCALL(update->SurfaceFrameMarker, context, &surfaceFrameMarker);
+
+ return 1;
+}
+
+int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* surface, int nXSrc, int nYSrc, int nWidth, int nHeight)
+{
+ int i;
+ wStream* s;
+ int nSrcStep;
+ BYTE* pSrcData;
+ int numMessages;
+ UINT32 frameId = 0;
+ rdpUpdate* update;
+ rdpContext* context;
+ rdpSettings* settings;
+ rdpShadowServer* server;
+ rdpShadowEncoder* encoder;
+ SURFACE_BITS_COMMAND cmd;
+
+ context = (rdpContext*) client;
+ update = context->update;
+ settings = context->settings;
+
+ server = client->server;
+ encoder = client->encoder;
+
+ pSrcData = surface->data;
+ nSrcStep = surface->scanline;
+
+ if (encoder->frameAck)
+ {
+ frameId = (UINT32) shadow_encoder_create_frame_id(encoder);
+ shadow_client_send_surface_frame_marker(client, SURFACECMD_FRAMEACTION_BEGIN, frameId);
+ }
+
+ if (settings->RemoteFxCodec)
+ {
+ RFX_RECT rect;
+ RFX_MESSAGE* messages;
+
+ s = encoder->bs;
+
+ rect.x = nXSrc;
+ rect.y = nYSrc;
+ rect.width = nWidth;
+ rect.height = nHeight;
+
+ messages = rfx_encode_messages(encoder->rfx, &rect, 1, pSrcData,
+ surface->width, surface->height, nSrcStep, &numMessages,
+ settings->MultifragMaxRequestSize);
+
+ cmd.codecID = settings->RemoteFxCodecId;
+
+ cmd.destLeft = 0;
+ cmd.destTop = 0;
+ cmd.destRight = surface->width;
+ cmd.destBottom = surface->height;
+
+ cmd.bpp = 32;
+ cmd.width = surface->width;
+ cmd.height = surface->height;
+
+ for (i = 0; i < numMessages; i++)
+ {
+ Stream_SetPosition(s, 0);
+ rfx_write_message(encoder->rfx, s, &messages[i]);
+ rfx_message_free(encoder->rfx, &messages[i]);
+
+ cmd.bitmapDataLength = Stream_GetPosition(s);
+ cmd.bitmapData = Stream_Buffer(s);
+
+ IFCALL(update->SurfaceBits, update->context, &cmd);
+ }
+
+ free(messages);
+ }
+ else if (settings->NSCodec)
+ {
+ NSC_MESSAGE* messages;
+
+ s = encoder->bs;
+
+ messages = nsc_encode_messages(encoder->nsc, pSrcData,
+ nXSrc, nYSrc, nWidth, nHeight, nSrcStep,
+ &numMessages, settings->MultifragMaxRequestSize);
+
+ cmd.bpp = 32;
+ cmd.codecID = settings->NSCodecId;
+
+ for (i = 0; i < numMessages; i++)
+ {
+ Stream_SetPosition(s, 0);
+
+ nsc_write_message(encoder->nsc, s, &messages[i]);
+ nsc_message_free(encoder->nsc, &messages[i]);
+
+ cmd.destLeft = messages[i].x;
+ cmd.destTop = messages[i].y;
+ cmd.destRight = messages[i].x + messages[i].width;
+ cmd.destBottom = messages[i].y + messages[i].height;
+ cmd.width = messages[i].width;
+ cmd.height = messages[i].height;
+
+ cmd.bitmapDataLength = Stream_GetPosition(s);
+ cmd.bitmapData = Stream_Buffer(s);
+
+ IFCALL(update->SurfaceBits, update->context, &cmd);
+ }
+
+ free(messages);
+ }
+
+ if (encoder->frameAck)
+ {
+ shadow_client_send_surface_frame_marker(client, SURFACECMD_FRAMEACTION_END, frameId);
+ }
+
+ return 1;
+}
+
+int shadow_client_send_bitmap_update(rdpShadowClient* client, rdpShadowSurface* surface, int nXSrc, int nYSrc, int nWidth, int nHeight)
+{
+ BYTE* data;
+ BYTE* buffer;
+ int i, j, k;
+ wStream* s;
+ wStream* ts;
+ int e, lines;
+ int rows, cols;
+ int nSrcStep;
+ BYTE* pSrcData;
+ rdpUpdate* update;
+ rdpContext* context;
+ rdpSettings* settings;
+ int MaxRegionWidth;
+ int MaxRegionHeight;
+ BITMAP_DATA* bitmapData;
+ BITMAP_UPDATE bitmapUpdate;
+ rdpShadowServer* server;
+ rdpShadowEncoder* encoder;
+
+ context = (rdpContext*) client;
+ update = context->update;
+ settings = context->settings;
+
+ server = client->server;
+ encoder = client->encoder;
+
+ pSrcData = surface->data;
+ nSrcStep = surface->scanline;
+
+ MaxRegionWidth = 64 * 4;
+ MaxRegionHeight = 64 * 1;
+
+ if ((nXSrc % 4) != 0)
+ {
+ nWidth += (nXSrc % 4);
+ nXSrc -= (nXSrc % 4);
+ }
+
+ if ((nYSrc % 4) != 0)
+ {
+ nHeight += (nYSrc % 4);
+ nYSrc -= (nYSrc % 4);
+ }
+
+ if ((nWidth * nHeight) > (MaxRegionWidth * MaxRegionHeight))
+ {
+ int nXSrcSub;
+ int nYSrcSub;
+ int nWidthSub;
+ int nHeightSub;
+ rows = (nWidth + (MaxRegionWidth - (nWidth % MaxRegionWidth))) / MaxRegionWidth;
+ cols = (nHeight + (MaxRegionHeight - (nHeight % MaxRegionHeight))) / MaxRegionHeight;
+
+ for (i = 0; i < rows; i++)
+ {
+ for (j = 0; j < cols; j++)
+ {
+ nXSrcSub = nXSrc + (i * MaxRegionWidth);
+ nYSrcSub = nYSrc + (j * MaxRegionHeight);
+
+ nWidthSub = (i < (rows - 1)) ? MaxRegionWidth : nWidth - (i * MaxRegionWidth);
+ nHeightSub = (j < (cols - 1)) ? MaxRegionHeight : nHeight - (j * MaxRegionHeight);
+
+ if ((nWidthSub * nHeightSub) > 0)
+ {
+ shadow_client_send_bitmap_update(client, surface, nXSrcSub, nYSrcSub, nWidthSub, nHeightSub);
+ }
+ }
+ }
+
+ return 1;
+ }
+
+ rows = (nWidth + (64 - (nWidth % 64))) / 64;
+ cols = (nHeight + (64 - (nHeight % 64))) / 64;
+
+ k = 0;
+ bitmapUpdate.count = bitmapUpdate.number = rows * cols;
+ bitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * bitmapUpdate.number);
+ bitmapUpdate.rectangles = bitmapData;
+
+ if (!bitmapData)
+ return -1;
+
+ if ((nWidth % 4) != 0)
+ {
+ nXSrc -= (nWidth % 4);
+ nWidth += (nWidth % 4);
+ }
+
+ if ((nHeight % 4) != 0)
+ {
+ nYSrc -= (nHeight % 4);
+ nHeight += (nHeight % 4);
+ }
+
+ for (i = 0; i < rows; i++)
+ {
+ for (j = 0; j < cols; j++)
+ {
+ nWidth = (i < (rows - 1)) ? 64 : nWidth - (i * 64);
+ nHeight = (j < (cols - 1)) ? 64 : nHeight - (j * 64);
+
+ bitmapData[k].bitsPerPixel = 16;
+ bitmapData[k].width = nWidth;
+ bitmapData[k].height = nHeight;
+ bitmapData[k].destLeft = nXSrc + (i * 64);
+ bitmapData[k].destTop = nYSrc + (j * 64);
+ bitmapData[k].destRight = bitmapData[k].destLeft + nWidth - 1;
+ bitmapData[k].destBottom = bitmapData[k].destTop + nHeight - 1;
+ bitmapData[k].compressed = TRUE;
+
+ if (((nWidth * nHeight) > 0) && (nWidth >= 4) && (nHeight >= 4))
+ {
+ UINT32 srcFormat = PIXEL_FORMAT_RGB32;
+
+ e = nWidth % 4;
+
+ if (e != 0)
+ e = 4 - e;
+
+ s = encoder->bs;
+ ts = encoder->bts;
+
+ Stream_SetPosition(s, 0);
+ Stream_SetPosition(ts, 0);
+
+ data = surface->data;
+ data = &data[(bitmapData[k].destTop * nSrcStep) +
+ (bitmapData[k].destLeft * 4)];
+
+ srcFormat = PIXEL_FORMAT_RGB32;
+
+ if (settings->ColorDepth > 24)
+ {
+ int dstSize;
+
+ buffer = encoder->grid[k];
+
+ buffer = freerdp_bitmap_compress_planar(encoder->planar,
+ data, srcFormat, nWidth, nHeight, nSrcStep, buffer, &dstSize);
+
+ bitmapData[k].bitmapDataStream = buffer;
+ bitmapData[k].bitmapLength = dstSize;
+
+ bitmapData[k].bitsPerPixel = 32;
+ bitmapData[k].cbScanWidth = nWidth * 4;
+ bitmapData[k].cbUncompressedSize = nWidth * nHeight * 4;
+ }
+ else
+ {
+ int bytesPerPixel = 2;
+ UINT32 dstFormat = PIXEL_FORMAT_RGB16;
+
+ if (settings->ColorDepth == 15)
+ {
+ bytesPerPixel = 2;
+ dstFormat = PIXEL_FORMAT_RGB15;
+ }
+ else if (settings->ColorDepth == 24)
+ {
+ bytesPerPixel = 3;
+ dstFormat = PIXEL_FORMAT_XRGB32;
+ }
+
+ buffer = encoder->grid[k];
+
+ freerdp_image_copy(buffer, dstFormat, -1, 0, 0, nWidth, nHeight,
+ data, srcFormat, nSrcStep, 0, 0);
+
+ lines = freerdp_bitmap_compress((char*) buffer, nWidth, nHeight, s,
+ settings->ColorDepth, 64 * 64 * 4, nHeight - 1, ts, e);
+
+ Stream_SealLength(s);
+
+ bitmapData[k].bitmapDataStream = Stream_Buffer(s);
+ bitmapData[k].bitmapLength = Stream_Length(s);
+
+ buffer = encoder->grid[k];
+ CopyMemory(buffer, bitmapData[k].bitmapDataStream, bitmapData[k].bitmapLength);
+ bitmapData[k].bitmapDataStream = buffer;
+
+ bitmapData[k].bitsPerPixel = settings->ColorDepth;
+ bitmapData[k].cbScanWidth = nWidth * bytesPerPixel;
+ bitmapData[k].cbUncompressedSize = nWidth * nHeight * bytesPerPixel;
+ }
+
+ bitmapData[k].cbCompFirstRowSize = 0;
+ bitmapData[k].cbCompMainBodySize = bitmapData[k].bitmapLength;
+
+ k++;
+ }
+ }
+ }
+
+ bitmapUpdate.count = bitmapUpdate.number = k;
+
+ IFCALL(update->BitmapUpdate, context, &bitmapUpdate);
+
+ free(bitmapData);
+
+ return 1;
+}
+
+int shadow_client_send_surface_update(rdpShadowClient* client)
+{
+ int status = -1;
+ int nXSrc, nYSrc;
+ int nWidth, nHeight;
+ rdpContext* context;
+ rdpSettings* settings;
+ rdpShadowServer* server;
+ rdpShadowSurface* surface;
+ rdpShadowEncoder* encoder;
+ REGION16 invalidRegion;
+ RECTANGLE_16 surfaceRect;
+ const RECTANGLE_16* extents;
+
+ context = (rdpContext*) client;
+ settings = context->settings;
+ server = client->server;
+ encoder = client->encoder;
+
+ surface = client->inLobby ? client->lobby : server->surface;
+
+ EnterCriticalSection(&(client->lock));
+
+ region16_init(&invalidRegion);
+ region16_copy(&invalidRegion, &(client->invalidRegion));
+ region16_clear(&(client->invalidRegion));
+
+ LeaveCriticalSection(&(client->lock));
+
+ surfaceRect.left = surface->x;
+ surfaceRect.top = surface->y;
+ surfaceRect.right = surface->x + surface->width;
+ surfaceRect.bottom = surface->y + surface->height;
+
+ region16_intersect_rect(&invalidRegion, &invalidRegion, &surfaceRect);
+
+ if (region16_is_empty(&invalidRegion))
+ {
+ region16_uninit(&invalidRegion);
+ return 1;
+ }
+
+ extents = region16_extents(&invalidRegion);
+
+ nXSrc = extents->left - surface->x;
+ nYSrc = extents->top - surface->y;
+ nWidth = extents->right - extents->left;
+ nHeight = extents->bottom - extents->top;
+
+ //printf("shadow_client_send_surface_update: x: %d y: %d width: %d height: %d right: %d bottom: %d\n",
+ // nXSrc, nYSrc, nWidth, nHeight, nXSrc + nWidth, nYSrc + nHeight);
+
+ if (settings->RemoteFxCodec || settings->NSCodec)
+ {
+ if (settings->RemoteFxCodec)
+ shadow_encoder_prepare(encoder, SHADOW_CODEC_REMOTEFX);
+ else if (settings->NSCodec)
+ shadow_encoder_prepare(encoder, SHADOW_CODEC_NSCODEC);
+
+ status = shadow_client_send_surface_bits(client, surface, nXSrc, nYSrc, nWidth, nHeight);
+ }
+ else
+ {
+ shadow_encoder_prepare(encoder, SHADOW_CODEC_BITMAP);
+
+ status = shadow_client_send_bitmap_update(client, surface, nXSrc, nYSrc, nWidth, nHeight);
+ }
+
+ region16_uninit(&invalidRegion);
+
+ return status;
+}
+
+int shadow_client_surface_update(rdpShadowClient* client, REGION16* region)
+{
+ int index;
+ int numRects = 0;
+ const RECTANGLE_16* rects;
+
+ EnterCriticalSection(&(client->lock));
+
+ rects = region16_rects(region, &numRects);
+
+ for (index = 0; index < numRects; index++)
+ {
+ region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &rects[index]);
+ }
+
+ LeaveCriticalSection(&(client->lock));
+
+ return 1;
+}
+
+void* shadow_client_thread(rdpShadowClient* client)
+{
+ DWORD status;
+ DWORD nCount;
+ HANDLE events[32];
+ HANDLE StopEvent;
+ HANDLE ClientEvent;
+ HANDLE ChannelEvent;
+ HANDLE UpdateEvent;
+ freerdp_peer* peer;
+ rdpSettings* settings;
+ rdpShadowServer* server;
+ rdpShadowScreen* screen;
+ rdpShadowEncoder* encoder;
+ rdpShadowSubsystem* subsystem;
+
+ server = client->server;
+ screen = server->screen;
+ encoder = client->encoder;
+ subsystem = server->subsystem;
+
+ peer = ((rdpContext*) client)->peer;
+ settings = peer->settings;
+
+ peer->Capabilities = shadow_client_capabilities;
+ peer->PostConnect = shadow_client_post_connect;
+ peer->Activate = shadow_client_activate;
+
+ shadow_input_register_callbacks(peer->input);
+
+ peer->Initialize(peer);
+
+ peer->update->SurfaceFrameAcknowledge = (pSurfaceFrameAcknowledge)
+ shadow_client_surface_frame_acknowledge;
+ peer->update->SuppressOutput = (pSuppressOutput) shadow_client_suppress_output;
+
+ StopEvent = client->StopEvent;
+ UpdateEvent = subsystem->updateEvent;
+ ClientEvent = peer->GetEventHandle(peer);
+ ChannelEvent = WTSVirtualChannelManagerGetEventHandle(client->vcm);
+
+ while (1)
+ {
+ nCount = 0;
+ events[nCount++] = StopEvent;
+ events[nCount++] = UpdateEvent;
+ events[nCount++] = ClientEvent;
+ events[nCount++] = ChannelEvent;
+
+ status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
+
+ if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
+ {
+ if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0)
+ {
+ EnterSynchronizationBarrier(&(subsystem->barrier), 0);
+ }
+
+ break;
+ }
+
+ if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0)
+ {
+ if (client->activated)
+ {
+ int index;
+ int numRects = 0;
+ const RECTANGLE_16* rects;
+
+ rects = region16_rects(&(subsystem->invalidRegion), &numRects);
+
+ for (index = 0; index < numRects; index++)
+ {
+ region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &rects[index]);
+ }
+
+ shadow_client_send_surface_update(client);
+ }
+
+ EnterSynchronizationBarrier(&(subsystem->barrier), 0);
+
+ while (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0);
+ }
+
+ if (WaitForSingleObject(ClientEvent, 0) == WAIT_OBJECT_0)
+ {
+ if (!peer->CheckFileDescriptor(peer))
+ {
+ fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
+ break;
+ }
+ }
+
+ if (WaitForSingleObject(ChannelEvent, 0) == WAIT_OBJECT_0)
+ {
+ if (WTSVirtualChannelManagerCheckFileDescriptor(client->vcm) != TRUE)
+ {
+ fprintf(stderr, "WTSVirtualChannelManagerCheckFileDescriptor failure\n");
+ break;
+ }
+ }
+ }
+
+ peer->Disconnect(peer);
+
+ freerdp_peer_context_free(peer);
+ freerdp_peer_free(peer);
+
+ ExitThread(0);
+
+ return NULL;
+}
+
+void shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer)
+{
+ rdpShadowClient* client;
+ rdpShadowServer* server;
+
+ server = (rdpShadowServer*) listener->info;
+
+ peer->ContextExtra = (void*) server;
+ peer->ContextSize = sizeof(rdpShadowClient);
+ peer->ContextNew = (psPeerContextNew) shadow_client_context_new;
+ peer->ContextFree = (psPeerContextFree) shadow_client_context_free;
+ freerdp_peer_context_new(peer);
+
+ client = (rdpShadowClient*) peer->context;
+
+ client->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
+ shadow_client_thread, client, 0, NULL);
+}
--- /dev/null
+/**
+ * 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 FREERDP_SHADOW_SERVER_CLIENT_H
+#define FREERDP_SHADOW_SERVER_CLIENT_H
+
+#include <freerdp/server/shadow.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int shadow_client_surface_update(rdpShadowClient* client, REGION16* region);
+void shadow_client_accepted(freerdp_listener* instance, freerdp_peer* client);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_CLIENT_H */
--- /dev/null
+/**
+ * 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 "shadow.h"
+
+#include "shadow_encoder.h"
+
+int shadow_encoder_create_frame_id(rdpShadowEncoder* encoder)
+{
+ UINT32 frameId;
+ int inFlightFrames;
+ SURFACE_FRAME* frame;
+
+ inFlightFrames = ListDictionary_Count(encoder->frameList);
+
+ if (inFlightFrames > encoder->frameAck)
+ {
+ encoder->fps = (100 / (inFlightFrames + 1) * encoder->maxFps) / 100;
+ }
+ else
+ {
+ encoder->fps += 2;
+
+ if (encoder->fps > encoder->maxFps)
+ encoder->fps = encoder->maxFps;
+ }
+
+ if (encoder->fps < 1)
+ encoder->fps = 1;
+
+ frame = (SURFACE_FRAME*) malloc(sizeof(SURFACE_FRAME));
+
+ if (!frame)
+ return -1;
+
+ frameId = frame->frameId = ++encoder->frameId;
+ ListDictionary_Add(encoder->frameList, (void*) (size_t) frame->frameId, frame);
+
+ return (int) frame->frameId;
+}
+
+int shadow_encoder_init_grid(rdpShadowEncoder* encoder)
+{
+ int i, j, k;
+ int tileSize;
+ int tileCount;
+
+ encoder->gridWidth = ((encoder->width + (encoder->maxTileWidth - 1)) / encoder->maxTileWidth);
+ encoder->gridHeight = ((encoder->height + (encoder->maxTileHeight - 1)) / encoder->maxTileHeight);
+
+ tileSize = encoder->maxTileWidth * encoder->maxTileHeight * 4;
+ tileCount = encoder->gridWidth * encoder->gridHeight;
+
+ encoder->gridBuffer = (BYTE*) malloc(tileSize * tileCount);
+
+ if (!encoder->gridBuffer)
+ return -1;
+
+ encoder->grid = (BYTE**) malloc(tileCount * sizeof(BYTE*));
+
+ if (!encoder->grid)
+ return -1;
+
+ for (i = 0; i < encoder->gridHeight; i++)
+ {
+ for (j = 0; j < encoder->gridWidth; j++)
+ {
+ k = (i * encoder->gridHeight) + j;
+ encoder->grid[k] = &(encoder->gridBuffer[k * tileSize]);
+ }
+ }
+
+ return 0;
+}
+
+int shadow_encoder_uninit_grid(rdpShadowEncoder* encoder)
+{
+ if (encoder->gridBuffer)
+ {
+ free(encoder->gridBuffer);
+ encoder->gridBuffer = NULL;
+ }
+
+ if (encoder->grid)
+ {
+ free(encoder->grid);
+ encoder->grid = NULL;
+ }
+
+ encoder->gridWidth = 0;
+ encoder->gridHeight = 0;
+
+ return 0;
+}
+
+int shadow_encoder_init_rfx(rdpShadowEncoder* encoder)
+{
+ if (!encoder->rfx)
+ encoder->rfx = rfx_context_new(TRUE);
+
+ if (!encoder->rfx)
+ return -1;
+
+ encoder->rfx->mode = RLGR3;
+ encoder->rfx->width = encoder->width;
+ encoder->rfx->height = encoder->height;
+
+ rfx_context_set_pixel_format(encoder->rfx, RDP_PIXEL_FORMAT_B8G8R8A8);
+
+ if (!encoder->frameList)
+ {
+ encoder->fps = 16;
+ encoder->maxFps = 32;
+ encoder->frameId = 0;
+ encoder->frameAck = TRUE;
+ encoder->frameList = ListDictionary_New(TRUE);
+ }
+
+ encoder->codecs |= SHADOW_CODEC_REMOTEFX;
+
+ return 1;
+}
+
+int shadow_encoder_init_nsc(rdpShadowEncoder* encoder)
+{
+ if (!encoder->nsc)
+ encoder->nsc = nsc_context_new();
+
+ if (!encoder->nsc)
+ return -1;
+
+ nsc_context_set_pixel_format(encoder->nsc, RDP_PIXEL_FORMAT_B8G8R8A8);
+
+ if (!encoder->frameList)
+ {
+ encoder->fps = 16;
+ encoder->maxFps = 32;
+ encoder->frameId = 0;
+ encoder->frameAck = TRUE;
+ encoder->frameList = ListDictionary_New(TRUE);
+ }
+
+ encoder->codecs |= SHADOW_CODEC_NSCODEC;
+
+ return 1;
+}
+
+int shadow_encoder_init_bitmap(rdpShadowEncoder* encoder)
+{
+ DWORD planarFlags;
+
+ planarFlags = PLANAR_FORMAT_HEADER_NA;
+ planarFlags |= PLANAR_FORMAT_HEADER_RLE;
+
+ if (!encoder->planar)
+ {
+ encoder->planar = freerdp_bitmap_planar_context_new(planarFlags,
+ encoder->maxTileWidth, encoder->maxTileHeight);
+ }
+
+ if (!encoder->planar)
+ return -1;
+
+ if (!encoder->bts)
+ encoder->bts = Stream_New(NULL, encoder->maxTileWidth * encoder->maxTileHeight * 4);
+
+ if (!encoder->bts)
+ return -1;
+
+ encoder->codecs |= SHADOW_CODEC_BITMAP;
+
+ return 1;
+}
+
+int shadow_encoder_init(rdpShadowEncoder* encoder)
+{
+ encoder->maxTileWidth = 64;
+ encoder->maxTileHeight = 64;
+
+ shadow_encoder_init_grid(encoder);
+
+ if (!encoder->bs)
+ encoder->bs = Stream_New(NULL, encoder->maxTileWidth * encoder->maxTileHeight * 4);
+
+ if (!encoder->bs)
+ return -1;
+
+ return 1;
+}
+
+int shadow_encoder_uninit_rfx(rdpShadowEncoder* encoder)
+{
+ if (encoder->rfx)
+ {
+ rfx_context_free(encoder->rfx);
+ encoder->rfx = NULL;
+ }
+
+ if (encoder->frameList)
+ {
+ ListDictionary_Free(encoder->frameList);
+ encoder->frameList = NULL;
+ }
+
+ encoder->codecs &= ~SHADOW_CODEC_REMOTEFX;
+
+ return 1;
+}
+
+int shadow_encoder_uninit_nsc(rdpShadowEncoder* encoder)
+{
+ if (encoder->nsc)
+ {
+ nsc_context_free(encoder->nsc);
+ encoder->nsc = NULL;
+ }
+
+ if (encoder->frameList)
+ {
+ ListDictionary_Free(encoder->frameList);
+ encoder->frameList = NULL;
+ }
+
+ encoder->codecs &= ~SHADOW_CODEC_NSCODEC;
+
+ return 1;
+}
+
+int shadow_encoder_uninit_bitmap(rdpShadowEncoder* encoder)
+{
+ if (encoder->planar)
+ {
+ freerdp_bitmap_planar_context_free(encoder->planar);
+ encoder->planar = NULL;
+ }
+
+ if (encoder->bts)
+ {
+ Stream_Free(encoder->bts, TRUE);
+ encoder->bts = NULL;
+ }
+
+ encoder->codecs &= ~SHADOW_CODEC_BITMAP;
+
+ return 1;
+}
+
+int shadow_encoder_uninit(rdpShadowEncoder* encoder)
+{
+ shadow_encoder_uninit_grid(encoder);
+
+ if (encoder->bs)
+ {
+ Stream_Free(encoder->bs, TRUE);
+ encoder->bs = NULL;
+ }
+
+ if (encoder->codecs & SHADOW_CODEC_REMOTEFX)
+ {
+ shadow_encoder_uninit_rfx(encoder);
+ }
+
+ if (encoder->codecs & SHADOW_CODEC_NSCODEC)
+ {
+ shadow_encoder_uninit_nsc(encoder);
+ }
+
+ if (encoder->codecs & SHADOW_CODEC_BITMAP)
+ {
+ shadow_encoder_uninit_bitmap(encoder);
+ }
+
+ return 1;
+}
+
+int shadow_encoder_reset(rdpShadowEncoder* encoder)
+{
+ int status;
+ UINT32 codecs = encoder->codecs;
+
+ status = shadow_encoder_uninit(encoder);
+
+ if (status < 0)
+ return -1;
+
+ status = shadow_encoder_init(encoder);
+
+ if (status < 0)
+ return -1;
+
+ status = shadow_encoder_prepare(encoder, codecs);
+
+ if (status < 0)
+ return -1;
+
+ return 1;
+}
+
+int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs)
+{
+ int status;
+
+ if ((codecs & SHADOW_CODEC_REMOTEFX) && !(encoder->codecs & SHADOW_CODEC_REMOTEFX))
+ {
+ status = shadow_encoder_init_rfx(encoder);
+
+ if (status < 0)
+ return -1;
+ }
+
+ if ((codecs & SHADOW_CODEC_NSCODEC) && !(encoder->codecs & SHADOW_CODEC_NSCODEC))
+ {
+ status = shadow_encoder_init_nsc(encoder);
+
+ if (status < 0)
+ return -1;
+ }
+
+ if ((codecs & SHADOW_CODEC_BITMAP) && !(encoder->codecs & SHADOW_CODEC_BITMAP))
+ {
+ status = shadow_encoder_init_bitmap(encoder);
+
+ if (status < 0)
+ return -1;
+ }
+
+ return 1;
+}
+
+rdpShadowEncoder* shadow_encoder_new(rdpShadowServer* server)
+{
+ rdpShadowEncoder* encoder;
+
+ encoder = (rdpShadowEncoder*) calloc(1, sizeof(rdpShadowEncoder));
+
+ if (!encoder)
+ return NULL;
+
+ encoder->server = server;
+
+ encoder->fps = 16;
+ encoder->maxFps = 32;
+
+ encoder->width = server->screen->width;
+ encoder->height = server->screen->height;
+
+ if (shadow_encoder_init(encoder) < 0)
+ return NULL;
+
+ return encoder;
+}
+
+void shadow_encoder_free(rdpShadowEncoder* encoder)
+{
+ if (!encoder)
+ return;
+
+ shadow_encoder_uninit(encoder);
+
+ free(encoder);
+}
--- /dev/null
+/**
+ * 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 FREERDP_SHADOW_SERVER_ENCODER_H
+#define FREERDP_SHADOW_SERVER_ENCODER_H
+
+#include <winpr/crt.h>
+#include <winpr/stream.h>
+
+#include <freerdp/freerdp.h>
+#include <freerdp/codec/rfx.h>
+#include <freerdp/codec/nsc.h>
+#include <freerdp/codec/bitmap.h>
+
+#include <freerdp/server/shadow.h>
+
+#define SHADOW_CODEC_REMOTEFX 1
+#define SHADOW_CODEC_NSCODEC 2
+#define SHADOW_CODEC_BITMAP 4
+
+struct rdp_shadow_encoder
+{
+ rdpShadowServer* server;
+
+ int width;
+ int height;
+ UINT32 codecs;
+
+ BYTE** grid;
+ int gridWidth;
+ int gridHeight;
+ BYTE* gridBuffer;
+ int maxTileWidth;
+ int maxTileHeight;
+
+ wStream* bs;
+ wStream* bts;
+
+ RFX_CONTEXT* rfx;
+ NSC_CONTEXT* nsc;
+ BITMAP_PLANAR_CONTEXT* planar;
+
+ int fps;
+ int maxFps;
+ BOOL frameAck;
+ UINT32 frameId;
+ wListDictionary* frameList;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int shadow_encoder_reset(rdpShadowEncoder* encoder);
+int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs);
+int shadow_encoder_create_frame_id(rdpShadowEncoder* encoder);
+
+rdpShadowEncoder* shadow_encoder_new(rdpShadowServer* server);
+void shadow_encoder_free(rdpShadowEncoder* encoder);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_ENCODER_H */
--- /dev/null
+/**
+ * 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 "shadow.h"
+
+#include "shadow_encomsp.h"
+
+static int encomsp_change_participant_control_level(EncomspServerContext* context,
+ ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu)
+{
+ BOOL inLobby;
+ BOOL mayView;
+ BOOL mayInteract;
+ rdpShadowClient* client = (rdpShadowClient*) context->custom;
+
+ printf("ChangeParticipantControlLevel: ParticipantId: %d Flags: 0x%04X\n",
+ pdu->ParticipantId, pdu->Flags);
+
+ mayView = (pdu->Flags & ENCOMSP_MAY_VIEW) ? TRUE : FALSE;
+ mayInteract = (pdu->Flags & ENCOMSP_MAY_INTERACT) ? TRUE : FALSE;
+
+ if (mayInteract && !mayView)
+ mayView = TRUE; /* may interact implies may view */
+
+ if (mayInteract)
+ {
+ if (!client->mayInteract)
+ {
+ /* request interact + view */
+ client->mayInteract = TRUE;
+ client->mayView = TRUE;
+ }
+ }
+ else if (mayView)
+ {
+ if (client->mayInteract)
+ {
+ /* release interact */
+ client->mayInteract = FALSE;
+ }
+ else if (!client->mayView)
+ {
+ /* request view */
+ client->mayView = TRUE;
+ }
+ }
+ else
+ {
+ if (client->mayInteract)
+ {
+ /* release interact + view */
+ client->mayView = FALSE;
+ client->mayInteract = FALSE;
+ }
+ else if (client->mayView)
+ {
+ /* release view */
+ client->mayView = FALSE;
+ client->mayInteract = FALSE;
+ }
+ }
+
+ inLobby = client->mayView ? FALSE : TRUE;
+
+ if (inLobby != client->inLobby)
+ {
+ shadow_encoder_reset(client->encoder);
+ client->inLobby = inLobby;
+ }
+
+ return 1;
+}
+
+int shadow_client_encomsp_init(rdpShadowClient* client)
+{
+ EncomspServerContext* encomsp;
+
+ encomsp = client->encomsp = encomsp_server_context_new(client->vcm);
+
+ encomsp->custom = (void*) client;
+
+ encomsp->ChangeParticipantControlLevel = encomsp_change_participant_control_level;
+
+ if (client->encomsp)
+ client->encomsp->Start(client->encomsp);
+
+ return 1;
+}
+
/**
* FreeRDP: A Remote Desktop Protocol Implementation
- * X11 Server Cursor
*
- * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * 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.
* limitations under the License.
*/
-#ifndef XFREERDP_SERVER_CURSOR_H
-#define XFREERDP_SERVER_CURSOR_H
+#ifndef FREERDP_SHADOW_SERVER_ENCOMSP_H
+#define FREERDP_SHADOW_SERVER_ENCOMSP_H
-#include "xfreerdp.h"
+#include <freerdp/server/shadow.h>
-int xf_cursor_init(xfInfo* xfi);
+#include <winpr/crt.h>
+#include <winpr/synch.h>
-#endif /* XFREERDP_SERVER_CURSOR_H */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int shadow_client_encomsp_init(rdpShadowClient* client);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_ENCOMSP_H */
--- /dev/null
+/**
+ * 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 "shadow.h"
+
+void shadow_input_synchronize_event(rdpInput* input, UINT32 flags)
+{
+ rdpShadowClient* client = (rdpShadowClient*) input->context;
+ rdpShadowSubsystem* subsystem = client->server->subsystem;
+
+ if (!client->mayInteract)
+ return;
+
+ if (subsystem->SynchronizeEvent)
+ {
+ subsystem->SynchronizeEvent(subsystem, flags);
+ }
+}
+
+void shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
+{
+ rdpShadowClient* client = (rdpShadowClient*) input->context;
+ rdpShadowSubsystem* subsystem = client->server->subsystem;
+
+ if (!client->mayInteract)
+ return;
+
+ if (subsystem->KeyboardEvent)
+ {
+ subsystem->KeyboardEvent(subsystem, flags, code);
+ }
+}
+
+void shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
+{
+ rdpShadowClient* client = (rdpShadowClient*) input->context;
+ rdpShadowSubsystem* subsystem = client->server->subsystem;
+
+ if (!client->mayInteract)
+ return;
+
+ if (subsystem->UnicodeKeyboardEvent)
+ {
+ subsystem->UnicodeKeyboardEvent(subsystem, flags, code);
+ }
+}
+
+void shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
+{
+ rdpShadowClient* client = (rdpShadowClient*) input->context;
+ rdpShadowSubsystem* subsystem = client->server->subsystem;
+
+ if (!client->mayInteract)
+ return;
+
+ if (subsystem->MouseEvent)
+ {
+ subsystem->MouseEvent(subsystem, flags, x, y);
+ }
+}
+
+void shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
+{
+ rdpShadowClient* client = (rdpShadowClient*) input->context;
+ rdpShadowSubsystem* subsystem = client->server->subsystem;
+
+ if (!client->mayInteract)
+ return;
+
+ if (subsystem->ExtendedMouseEvent)
+ {
+ subsystem->ExtendedMouseEvent(subsystem, flags, x, y);
+ }
+}
+
+void shadow_input_register_callbacks(rdpInput* input)
+{
+ input->SynchronizeEvent = shadow_input_synchronize_event;
+ input->KeyboardEvent = shadow_input_keyboard_event;
+ input->UnicodeKeyboardEvent = shadow_input_unicode_keyboard_event;
+ input->MouseEvent = shadow_input_mouse_event;
+ input->ExtendedMouseEvent = shadow_input_extended_mouse_event;
+}
/**
* FreeRDP: A Remote Desktop Protocol Implementation
- * Bitmap File Format Utils
*
- * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * 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.
* limitations under the License.
*/
-#ifndef FREERDP_UTILS_BITMAP_H
-#define FREERDP_UTILS_BITMAP_H
+#ifndef FREERDP_SHADOW_SERVER_INPUT_H
+#define FREERDP_SHADOW_SERVER_INPUT_H
-#include <freerdp/api.h>
+#include <freerdp/server/shadow.h>
#ifdef __cplusplus
extern "C" {
#endif
-FREERDP_API void freerdp_bitmap_write(char* filename, void* data, int width, int height, int bpp);
+void shadow_input_register_callbacks(rdpInput* input);
#ifdef __cplusplus
}
#endif
-#endif /* FREERDP_UTILS_BITMAP_H */
+#endif /* FREERDP_SHADOW_SERVER_INPUT_H */
--- /dev/null
+/**
+ * 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 "shadow.h"
+
+#include "shadow_remdesk.h"
+
+int shadow_client_remdesk_init(rdpShadowClient* client)
+{
+ RemdeskServerContext* remdesk;
+
+ remdesk = client->remdesk = remdesk_server_context_new(client->vcm);
+
+ remdesk->custom = (void*) client;
+
+ if (client->remdesk)
+ client->remdesk->Start(client->remdesk);
+
+ return 1;
+}
--- /dev/null
+/**
+ * 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 FREERDP_SHADOW_SERVER_REMDESK_H
+#define FREERDP_SHADOW_SERVER_REMDESK_H
+
+#include <freerdp/server/shadow.h>
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int shadow_client_remdesk_init(rdpShadowClient* client);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_REMDESK_H */
--- /dev/null
+/**
+ * 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 "shadow_surface.h"
+
+#include "shadow_screen.h"
+
+rdpShadowScreen* shadow_screen_new(rdpShadowServer* server)
+{
+ int x, y;
+ int width, height;
+ MONITOR_DEF* primary;
+ rdpShadowScreen* screen;
+ rdpShadowSubsystem* subsystem;
+
+ screen = (rdpShadowScreen*) calloc(1, sizeof(rdpShadowScreen));
+
+ if (!screen)
+ return NULL;
+
+ screen->server = server;
+ subsystem = server->subsystem;
+
+ if (!InitializeCriticalSectionAndSpinCount(&(screen->lock), 4000))
+ return NULL;
+
+ region16_init(&(screen->invalidRegion));
+
+ primary = &(subsystem->monitors[0]);
+
+ x = primary->left;
+ y = primary->top;
+ width = primary->right - primary->left;
+ height = primary->bottom - primary->top;
+
+ screen->width = width;
+ screen->height = height;
+
+ screen->primary = shadow_surface_new(server, x, y, width, height);
+
+ if (!screen->primary)
+ return NULL;
+
+ server->surface = screen->primary;
+
+ return screen;
+}
+
+void shadow_screen_free(rdpShadowScreen* screen)
+{
+ if (!screen)
+ return;
+
+ DeleteCriticalSection(&(screen->lock));
+
+ region16_uninit(&(screen->invalidRegion));
+
+ if (screen->primary)
+ {
+ shadow_surface_free(screen->primary);
+ screen->primary = NULL;
+ }
+
+ free(screen);
+}
+
--- /dev/null
+/**
+ * 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 FREERDP_SHADOW_SERVER_SCREEN_H
+#define FREERDP_SHADOW_SERVER_SCREEN_H
+
+#include <freerdp/server/shadow.h>
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+
+struct rdp_shadow_screen
+{
+ rdpShadowServer* server;
+
+ int width;
+ int height;
+
+ CRITICAL_SECTION lock;
+ REGION16 invalidRegion;
+
+ rdpShadowSurface* primary;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+rdpShadowScreen* shadow_screen_new(rdpShadowServer* server);
+void shadow_screen_free(rdpShadowScreen* screen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_SCREEN_H */
--- /dev/null
+/**
+ * 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 <winpr/crt.h>
+#include <winpr/ssl.h>
+#include <winpr/wnd.h>
+#include <winpr/path.h>
+#include <winpr/cmdline.h>
+#include <winpr/winsock.h>
+
+#include <freerdp/version.h>
+
+#include <winpr/tools/makecert.h>
+
+#ifdef _WIN32
+#include <openssl/applink.c>
+#endif
+
+#ifndef _WIN32
+#include <sys/select.h>
+#include <sys/signal.h>
+#endif
+
+#include "shadow.h"
+
+#ifdef _WIN32
+static BOOL g_MessagePump = TRUE;
+#else
+static BOOL g_MessagePump = FALSE;
+#endif
+
+#ifdef WITH_SHADOW_X11
+extern rdpShadowSubsystem* X11_ShadowCreateSubsystem(rdpShadowServer* server);
+#endif
+
+#ifdef WITH_SHADOW_MAC
+extern rdpShadowSubsystem* Mac_ShadowCreateSubsystem(rdpShadowServer* server);
+#endif
+
+#ifdef WITH_SHADOW_WIN
+extern rdpShadowSubsystem* Win_ShadowCreateSubsystem(rdpShadowServer* server);
+#endif
+
+static COMMAND_LINE_ARGUMENT_A shadow_args[] =
+{
+ { "port", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL, "Server port" },
+ { "ipc-socket", COMMAND_LINE_VALUE_REQUIRED, "<ipc-socket>", NULL, NULL, -1, NULL, "Server IPC socket" },
+ { "monitors", COMMAND_LINE_VALUE_OPTIONAL, "<0,1,2...>", NULL, NULL, -1, NULL, "Select or list monitors" },
+ { "may-view", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Clients may view without prompt" },
+ { "may-interact", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Clients may interact without prompt" },
+ { "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "Print version" },
+ { "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "Print help" },
+ { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
+};
+
+int shadow_server_print_command_line_help(int argc, char** argv)
+{
+ char* str;
+ int length;
+ COMMAND_LINE_ARGUMENT_A* arg;
+
+ printf("Usage: %s [options]\n", argv[0]);
+ printf("\n");
+
+ printf("Syntax:\n");
+ printf(" /flag (enables flag)\n");
+ printf(" /option:<value> (specifies option with value)\n");
+ printf(" +toggle -toggle (enables or disables toggle, where '/' is a synonym of '+')\n");
+ printf("\n");
+
+ arg = shadow_args;
+
+ do
+ {
+ if (arg->Flags & COMMAND_LINE_VALUE_FLAG)
+ {
+ printf(" %s", "/");
+ printf("%-20s", arg->Name);
+ printf("\t%s\n", arg->Text);
+ }
+ else if ((arg->Flags & COMMAND_LINE_VALUE_REQUIRED) || (arg->Flags & COMMAND_LINE_VALUE_OPTIONAL))
+ {
+ printf(" %s", "/");
+
+ if (arg->Format)
+ {
+ length = (int) (strlen(arg->Name) + strlen(arg->Format) + 2);
+ str = (char*) malloc(length + 1);
+ sprintf_s(str, length + 1, "%s:%s", arg->Name, arg->Format);
+ printf("%-20s", str);
+ free(str);
+ }
+ else
+ {
+ printf("%-20s", arg->Name);
+ }
+
+ printf("\t%s\n", arg->Text);
+ }
+ else if (arg->Flags & COMMAND_LINE_VALUE_BOOL)
+ {
+ length = (int) strlen(arg->Name) + 32;
+ str = (char*) malloc(length + 1);
+ sprintf_s(str, length + 1, "%s (default:%s)", arg->Name,
+ arg->Default ? "on" : "off");
+
+ printf(" %s", arg->Default ? "-" : "+");
+
+ printf("%-20s", str);
+ free(str);
+
+ printf("\t%s\n", arg->Text);
+ }
+ }
+ while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
+
+ return 1;
+}
+
+int shadow_server_command_line_status_print(rdpShadowServer* server, int argc, char** argv, int status)
+{
+ if (status == COMMAND_LINE_STATUS_PRINT_VERSION)
+ {
+ printf("FreeRDP version %s (git %s)\n", FREERDP_VERSION_FULL, GIT_REVISION);
+ return COMMAND_LINE_STATUS_PRINT_VERSION;
+ }
+ else if (status == COMMAND_LINE_STATUS_PRINT)
+ {
+ return COMMAND_LINE_STATUS_PRINT;
+ }
+ else if (status < 0)
+ {
+ shadow_server_print_command_line_help(argc, argv);
+ return COMMAND_LINE_STATUS_PRINT_HELP;
+ }
+
+ return 1;
+}
+
+int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** argv)
+{
+ int status;
+ DWORD flags;
+ COMMAND_LINE_ARGUMENT_A* arg;
+
+ if (argc < 2)
+ return 1;
+
+ CommandLineClearArgumentsA(shadow_args);
+
+ flags = COMMAND_LINE_SEPARATOR_COLON;
+ flags |= COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SIGIL_PLUS_MINUS;
+
+ status = CommandLineParseArgumentsA(argc, (const char**) argv, shadow_args, flags, server, NULL, NULL);
+
+ if (status < 0)
+ return status;
+
+ arg = shadow_args;
+
+ do
+ {
+ if (!(arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT))
+ continue;
+
+ CommandLineSwitchStart(arg)
+
+ CommandLineSwitchCase(arg, "port")
+ {
+ server->port = (DWORD) atoi(arg->Value);
+ }
+ CommandLineSwitchCase(arg, "ipc-socket")
+ {
+ server->ipcSocket = _strdup(arg->Value);
+ }
+ CommandLineSwitchCase(arg, "may-view")
+ {
+ server->mayView = arg->Value ? TRUE : FALSE;
+ }
+ CommandLineSwitchCase(arg, "may-interact")
+ {
+ server->mayInteract = arg->Value ? TRUE : FALSE;
+ }
+ CommandLineSwitchDefault(arg)
+ {
+
+ }
+
+ CommandLineSwitchEnd(arg)
+ }
+ while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
+
+ arg = CommandLineFindArgumentA(shadow_args, "monitors");
+
+ if (arg && (arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT))
+ {
+ if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
+ {
+ /* Select monitors */
+ }
+ else
+ {
+ int index;
+ int width, height;
+ MONITOR_DEF* monitor;
+ rdpShadowSubsystem* subsystem = server->subsystem;
+
+ /* List monitors */
+
+ for (index = 0; index < subsystem->monitorCount; index++)
+ {
+ monitor = &(subsystem->monitors[index]);
+
+ width = monitor->right - monitor->left;
+ height = monitor->bottom - monitor->top;
+
+ printf(" %s [%d] %dx%d\t+%d+%d\n",
+ (monitor->flags == 1) ? "*" : " ", index,
+ width, height, monitor->left, monitor->top);
+ }
+
+ status = COMMAND_LINE_STATUS_PRINT;
+ }
+ }
+
+ return status;
+}
+
+int shadow_server_surface_update(rdpShadowSubsystem* subsystem, REGION16* region)
+{
+ int index;
+ int count;
+ wArrayList* clients;
+ rdpShadowServer* server;
+ rdpShadowClient* client;
+
+ server = subsystem->server;
+ clients = server->clients;
+
+ ArrayList_Lock(clients);
+
+ count = ArrayList_Count(clients);
+
+ for (index = 0; index < count; index++)
+ {
+ client = ArrayList_GetItem(clients, index);
+ shadow_client_surface_update(client, region);
+ }
+
+ ArrayList_Unlock(clients);
+
+ return 1;
+}
+
+void* shadow_server_thread(rdpShadowServer* server)
+{
+ DWORD status;
+ DWORD nCount;
+ HANDLE events[32];
+ HANDLE StopEvent;
+ freerdp_listener* listener;
+ rdpShadowSubsystem* subsystem;
+
+ listener = server->listener;
+ StopEvent = server->StopEvent;
+ subsystem = server->subsystem;
+
+ if (subsystem->Start)
+ {
+ subsystem->Start(subsystem);
+ }
+
+ while (1)
+ {
+ nCount = 0;
+
+ if (listener->GetEventHandles(listener, events, &nCount) < 0)
+ {
+ fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
+ break;
+ }
+
+ events[nCount++] = server->StopEvent;
+
+ status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
+
+ if (WaitForSingleObject(server->StopEvent, 0) == WAIT_OBJECT_0)
+ {
+ break;
+ }
+
+ if (!listener->CheckFileDescriptor(listener))
+ {
+ fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
+ break;
+ }
+
+#ifdef _WIN32
+ Sleep(100); /* FIXME: listener event handles */
+#endif
+ }
+
+ listener->Close(listener);
+
+ if (subsystem->Stop)
+ {
+ subsystem->Stop(subsystem);
+ }
+
+ ExitThread(0);
+
+ return NULL;
+}
+
+int shadow_server_start(rdpShadowServer* server)
+{
+ BOOL status;
+ WSADATA wsaData;
+
+ if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
+ return -1;
+
+#ifndef _WIN32
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
+ if (!server->ipcSocket)
+ status = server->listener->Open(server->listener, NULL, (UINT16) server->port);
+ else
+ status = server->listener->OpenLocal(server->listener, server->ipcSocket);
+
+ if (status)
+ {
+ server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
+ shadow_server_thread, (void*) server, 0, NULL);
+ }
+
+ return 0;
+}
+
+int shadow_server_stop(rdpShadowServer* server)
+{
+ if (server->thread)
+ {
+ SetEvent(server->StopEvent);
+ WaitForSingleObject(server->thread, INFINITE);
+ CloseHandle(server->thread);
+ server->thread = NULL;
+
+ server->listener->Close(server->listener);
+ }
+
+ return 0;
+}
+
+int shadow_server_init_certificate(rdpShadowServer* server)
+{
+ char* filepath;
+ MAKECERT_CONTEXT* makecert;
+
+ const char* makecert_argv[6] =
+ {
+ "makecert",
+ "-rdp",
+ "-live",
+ "-silent",
+ "-y", "5"
+ };
+
+ int makecert_argc = (sizeof(makecert_argv) / sizeof(char*));
+
+ if (!PathFileExistsA(server->ConfigPath))
+ CreateDirectoryA(server->ConfigPath, 0);
+
+ filepath = GetCombinedPath(server->ConfigPath, "shadow");
+
+ if (!filepath)
+ return -1;
+
+ if (!PathFileExistsA(filepath))
+ CreateDirectoryA(filepath, 0);
+
+ server->CertificateFile = GetCombinedPath(filepath, "shadow.crt");
+ server->PrivateKeyFile = GetCombinedPath(filepath, "shadow.key");
+
+ if ((!PathFileExistsA(server->CertificateFile)) ||
+ (!PathFileExistsA(server->PrivateKeyFile)))
+ {
+ makecert = makecert_context_new();
+
+ makecert_context_process(makecert, makecert_argc, (char**) makecert_argv);
+
+ makecert_context_set_output_file_name(makecert, "shadow");
+
+ if (!PathFileExistsA(server->CertificateFile))
+ makecert_context_output_certificate_file(makecert, filepath);
+
+ if (!PathFileExistsA(server->PrivateKeyFile))
+ makecert_context_output_private_key_file(makecert, filepath);
+
+ makecert_context_free(makecert);
+ }
+
+ free(filepath);
+
+ return 1;
+}
+
+int shadow_server_init(rdpShadowServer* server)
+{
+ int status;
+
+ winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
+
+ WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi());
+
+ server->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ status = shadow_server_init_certificate(server);
+
+ if (status < 0)
+ return -1;
+
+ server->listener = freerdp_listener_new();
+
+ if (!server->listener)
+ return -1;
+
+ server->listener->info = (void*) server;
+ server->listener->PeerAccepted = shadow_client_accepted;
+
+#ifdef WITH_SHADOW_X11
+ server->CreateSubsystem = X11_ShadowCreateSubsystem;
+#endif
+
+#ifdef WITH_SHADOW_MAC
+ server->CreateSubsystem = Mac_ShadowCreateSubsystem;
+#endif
+
+#ifdef WITH_SHADOW_WIN
+ server->CreateSubsystem = Win_ShadowCreateSubsystem;
+#endif
+
+ if (server->CreateSubsystem)
+ server->subsystem = server->CreateSubsystem(server);
+
+ if (!server->subsystem)
+ return -1;
+
+ server->subsystem->SurfaceUpdate = shadow_server_surface_update;
+
+ if (server->subsystem->Init)
+ {
+ status = server->subsystem->Init(server->subsystem);
+
+ if (status < 0)
+ fprintf(stderr, "subsystem init failure: %d\n", status);
+ }
+
+ server->screen = shadow_screen_new(server);
+
+ if (!server->screen)
+ return -1;
+
+ server->capture = shadow_capture_new(server);
+
+ if (!server->capture)
+ return -1;
+
+ return 1;
+}
+
+int shadow_server_uninit(rdpShadowServer* server)
+{
+ shadow_server_stop(server);
+
+ if (server->listener)
+ {
+ freerdp_listener_free(server->listener);
+ server->listener = NULL;
+ }
+
+ if (server->subsystem)
+ {
+ server->subsystem->Free(server->subsystem);
+ server->subsystem = NULL;
+ }
+
+ if (server->CertificateFile)
+ {
+ free(server->CertificateFile);
+ server->CertificateFile = NULL;
+ }
+
+ if (server->PrivateKeyFile)
+ {
+ free(server->PrivateKeyFile);
+ server->PrivateKeyFile = NULL;
+ }
+
+ if (server->ipcSocket)
+ {
+ free(server->ipcSocket);
+ server->ipcSocket = NULL;
+ }
+
+ return 1;
+}
+
+rdpShadowServer* shadow_server_new()
+{
+ rdpShadowServer* server;
+
+ server = (rdpShadowServer*) calloc(1, sizeof(rdpShadowServer));
+
+ if (!server)
+ return NULL;
+
+ server->port = 3389;
+ server->mayView = TRUE;
+ server->mayInteract = TRUE;
+
+#ifdef _WIN32
+ server->ConfigPath = GetEnvironmentSubPath("LOCALAPPDATA", "freerdp");
+#endif
+
+ if (!server->ConfigPath)
+ server->ConfigPath = GetKnownSubPath(KNOWN_PATH_XDG_CONFIG_HOME, "freerdp");
+
+ InitializeCriticalSectionAndSpinCount(&(server->lock), 4000);
+
+ server->clients = ArrayList_New(TRUE);
+
+ return server;
+}
+
+void shadow_server_free(rdpShadowServer* server)
+{
+ if (!server)
+ return;
+
+ DeleteCriticalSection(&(server->lock));
+
+ if (server->clients)
+ {
+ ArrayList_Free(server->clients);
+ server->clients = NULL;
+ }
+
+ shadow_server_uninit(server);
+
+ free(server);
+}
+
+int main(int argc, char** argv)
+{
+ MSG msg;
+ int status;
+ DWORD dwExitCode;
+ rdpShadowServer* server;
+
+ server = shadow_server_new();
+
+ if (!server)
+ return 0;
+
+ if (shadow_server_init(server) < 0)
+ return 0;
+
+ status = shadow_server_parse_command_line(server, argc, argv);
+
+ status = shadow_server_command_line_status_print(server, argc, argv, status);
+
+ if (status < 0)
+ return 0;
+
+ if (shadow_server_start(server) < 0)
+ return 0;
+
+ if (g_MessagePump)
+ {
+ while (GetMessage(&msg, 0, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ WaitForSingleObject(server->thread, INFINITE);
+
+ GetExitCodeThread(server->thread, &dwExitCode);
+
+ shadow_server_free(server);
+
+ return 0;
+}
--- /dev/null
+/**
+ * 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 "shadow.h"
+
+#include "shadow_surface.h"
+
+rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int x, int y, int width, int height)
+{
+ rdpShadowSurface* surface;
+
+ surface = (rdpShadowSurface*) calloc(1, sizeof(rdpShadowSurface));
+
+ if (!surface)
+ return NULL;
+
+ surface->server = server;
+
+ surface->x = x;
+ surface->y = y;
+ surface->width = width;
+ surface->height = height;
+ surface->scanline = (surface->width + (surface->width % 4)) * 4;
+
+ surface->data = (BYTE*) malloc(surface->scanline * surface->height);
+
+ if (!surface->data)
+ return NULL;
+
+ ZeroMemory(surface->data, surface->scanline * surface->height);
+
+ if (!InitializeCriticalSectionAndSpinCount(&(surface->lock), 4000))
+ return NULL;
+
+ region16_init(&(surface->invalidRegion));
+
+ return surface;
+}
+
+void shadow_surface_free(rdpShadowSurface* surface)
+{
+ if (!surface)
+ return;
+
+ free(surface->data);
+
+ DeleteCriticalSection(&(surface->lock));
+
+ region16_uninit(&(surface->invalidRegion));
+
+ free(surface);
+}
--- /dev/null
+/**
+ * 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 FREERDP_SHADOW_SERVER_SURFACE_H
+#define FREERDP_SHADOW_SERVER_SURFACE_H
+
+#include <freerdp/server/shadow.h>
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+
+struct rdp_shadow_surface
+{
+ rdpShadowServer* server;
+
+ int x;
+ int y;
+ int width;
+ int height;
+ int scanline;
+ BYTE* data;
+
+ CRITICAL_SECTION lock;
+ REGION16 invalidRegion;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int x, int y, int width, int height);
+void shadow_surface_free(rdpShadowSurface* surface);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_SURFACE_H */
#include <winpr/wtypes.h>
#include <winpr/crt.h>
+#include <winpr/wlog.h>
struct _wBitStream
{
- BYTE* buffer;
+ const BYTE* buffer;
BYTE* pointer;
- DWORD position;
- DWORD length;
- DWORD capacity;
+ int position;
+ int length;
+ int capacity;
UINT32 mask;
UINT32 offset;
UINT32 prefetch;
#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 { \
- _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; \
+ 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)
+ } 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)); \
+ _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, 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
}
WINPR_API BOOL LinkedList_Contains(wLinkedList* list, void* value);
WINPR_API void LinkedList_Clear(wLinkedList* list);
-WINPR_API void LinkedList_AddFirst(wLinkedList* list, void* value);
-WINPR_API void LinkedList_AddLast(wLinkedList* list, void* value);
+WINPR_API BOOL LinkedList_AddFirst(wLinkedList* list, void* value);
+WINPR_API BOOL LinkedList_AddLast(wLinkedList* list, void* value);
-WINPR_API void LinkedList_Remove(wLinkedList* list, void* value);
+WINPR_API BOOL LinkedList_Remove(wLinkedList* list, void* value);
WINPR_API void LinkedList_RemoveFirst(wLinkedList* list);
WINPR_API void LinkedList_RemoveLast(wLinkedList* list);
#endif
+/**
+ * __lzcnt16, __lzcnt, __lzcnt64:
+ * http://msdn.microsoft.com/en-us/library/bb384809/
+ */
+
+#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
+
+/**
+ * __lzcnt16, __lzcnt, __lzcnt64:
+ * http://msdn.microsoft.com/en-us/library/bb384809/
+ *
+ * Beware: the result of __builtin_clz(0) is undefined
+ */
+
+static INLINE UINT32 __lzcnt(UINT32 _val32) {
+ return _val32 ? ((UINT32) __builtin_clz(_val32)) : 32;
+}
+
+static INLINE UINT16 __lzcnt16(UINT16 _val16) {
+ return _val16 ? ((UINT16) (__builtin_clz((UINT32) _val16) - 16)) : 16;
+}
+
+#else
+
+static INLINE UINT32 __lzcnt(UINT32 x) {
+ unsigned y;
+ int n = 32;
+ y = x >> 16; if (y != 0) { n = n - 16; x = y; }
+ y = x >> 8; if (y != 0) { n = n - 8; x = y; }
+ y = x >> 4; if (y != 0) { n = n - 4; x = y; }
+ y = x >> 2; if (y != 0) { n = n - 2; x = y; }
+ y = x >> 1; if (y != 0) return n - 2;
+ return n - x;
+}
+
+static INLINE UINT16 __lzcnt16(UINT16 x) {
+ return ((UINT16) __lzcnt((UINT32) x));
+}
+
+#endif
+
#endif
#ifndef _WIN32
--- /dev/null
+/**
+ * WinPR: Windows Portable Runtime
+ * WinPR Debugging helpers
+ *
+ * Copyright 2014 Armin Novak <armin.novak@thincast.com>
+ * Copyright 2014 Thincast Technologies GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WINPR_DEBUG_H
+#define WINPR_DEBUG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <winpr/wtypes.h>
+
+void *winpr_backtrace(DWORD size);
+void winpr_backtrace_free(void *buffer);
+char **winpr_backtrace_symbols(void *buffer, size_t *used);
+void winpr_backtrace_symbols_fd(void *buffer, int fd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WINPR_WLOG_H */
+
--- /dev/null
+/**
+ * WinPR: Windows Portable Runtime
+ * Image Utils
+ *
+ * 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 WINPR_IMAGE_H
+#define WINPR_IMAGE_H
+
+#include <winpr/winpr.h>
+#include <winpr/wtypes.h>
+
+struct _wImage
+{
+ int width;
+ int height;
+ BYTE* data;
+ int scanline;
+ int bitsPerPixel;
+ int bytesPerPixel;
+};
+typedef struct _wImage wImage;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WINPR_API int winpr_bitmap_write(const char* filename, BYTE* data, int width, int height, int bpp);
+
+WINPR_API int winpr_image_write(wImage* image, const char* filename);
+WINPR_API int winpr_image_read(wImage* image, const char* filename);
+
+WINPR_API wImage* winpr_image_new();
+WINPR_API void winpr_image_free(wImage* image, BOOL bFreeBuffer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WINPR_IMAGE_H */
WINPR_API char* GetKnownPath(int id);
WINPR_API char* GetKnownSubPath(int id, const char* path);
+WINPR_API char* GetEnvironmentPath(char* name);
+WINPR_API char* GetEnvironmentSubPath(char* name, const char* path);
WINPR_API char* GetCombinedPath(const char* basePath, const char* subPath);
-//#ifndef _WIN32
-
WINPR_API BOOL PathFileExistsA(LPCSTR pszPath);
WINPR_API BOOL PathFileExistsW(LPCWSTR pszPath);
#define PathFileExists PathFileExistsA
#endif
-//#endif
-
#endif /* WINPR_PATH_H */
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
}
WINPR_API VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
-/* Synchronization Barrier */
-
-typedef PVOID RTL_SYNCHRONIZATION_BARRIER;
-typedef RTL_SYNCHRONIZATION_BARRIER SYNCHRONIZATION_BARRIER, *PSYNCHRONIZATION_BARRIER, *LPSYNCHRONIZATION_BARRIER;
-
-WINPR_API BOOL InitializeSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount);
-WINPR_API BOOL EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags);
-WINPR_API BOOL DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier);
-
/* Sleep */
WINPR_API VOID Sleep(DWORD dwMilliseconds);
#endif
+/* Synchronization Barrier */
+
+#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0602))
+
+typedef struct _RTL_BARRIER
+{
+ DWORD Reserved1;
+ DWORD Reserved2;
+ ULONG_PTR Reserved3[2];
+ DWORD Reserved4;
+ DWORD Reserved5;
+} RTL_BARRIER, *PRTL_BARRIER;
+
+typedef RTL_BARRIER SYNCHRONIZATION_BARRIER;
+typedef PRTL_BARRIER PSYNCHRONIZATION_BARRIER;
+typedef PRTL_BARRIER LPSYNCHRONIZATION_BARRIER;
+
+#define SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY 0x01
+#define SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY 0x02
+#define SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE 0x04
+
+WINPR_API BOOL WINAPI InitializeSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount);
+WINPR_API BOOL WINAPI EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags);
+WINPR_API BOOL WINAPI DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier);
+
+#endif
+
/* Extended API */
WINPR_API VOID USleep(DWORD dwMicroseconds);
WINPR_API BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature);
/* extended flags */
-#define PF_EX_3DNOW_PREFETCH 1
-#define PF_EX_SSSE3 2
-#define PF_EX_SSE41 3
-#define PF_EX_SSE42 4
-#define PF_EX_AVX 5
-#define PF_EX_FMA 6
-#define PF_EX_AVX_AES 7
-#define PF_EX_AVX2 8
-#define PF_EX_ARM_VFP1 9
-#define PF_EX_ARM_VFP3D16 10
-#define PF_EX_ARM_VFP4 11
-#define PF_EX_ARM_IDIVA 12
-#define PF_EX_ARM_IDIVT 13
-#define PF_EX_AVX_PCLMULQDQ 14
+#define PF_EX_LZCNT 1
+#define PF_EX_3DNOW_PREFETCH 2
+#define PF_EX_SSSE3 3
+#define PF_EX_SSE41 4
+#define PF_EX_SSE42 5
+#define PF_EX_AVX 6
+#define PF_EX_FMA 7
+#define PF_EX_AVX_AES 8
+#define PF_EX_AVX2 9
+#define PF_EX_ARM_VFP1 10
+#define PF_EX_ARM_VFP3D16 11
+#define PF_EX_ARM_VFP4 12
+#define PF_EX_ARM_IDIVA 13
+#define PF_EX_ARM_IDIVT 14
+#define PF_EX_AVX_PCLMULQDQ 15
/*
* some "aliases" for the standard defines
DWORD State; \
wLogLayout* Layout; \
CRITICAL_SECTION lock; \
+ BOOL recursive; \
void* TextMessageContext; \
void* DataMessageContext; \
void* ImageMessageContext; \
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);
set(MODULE_NAME "winpr-comm")
set(MODULE_PREFIX "WINPR_COMM")
-set(${MODULE_PREFIX}_SRCS
- comm.c
- comm.h
- comm_io.c
- comm_ioctl.c
- comm_ioctl.h
- comm_serial_sys.c
- comm_serial_sys.h
- comm_sercx_sys.c
- comm_sercx_sys.h
- comm_sercx2_sys.c
- comm_sercx2_sys.h)
+if(UNIX AND NOT WIN32 AND NOT APPLE)
+ set(${MODULE_PREFIX}_SRCS
+ comm.c
+ comm.h
+ comm_io.c
+ comm_ioctl.c
+ comm_ioctl.h
+ comm_serial_sys.c
+ comm_serial_sys.h
+ comm_sercx_sys.c
+ comm_sercx_sys.h
+ comm_sercx2_sys.c
+ comm_sercx2_sys.h)
-winpr_module_add(${${MODULE_PREFIX}_SRCS})
+ winpr_module_add(${${MODULE_PREFIX}_SRCS})
-if(BUILD_TESTING AND UNIX AND NOT WIN32)
- add_subdirectory(test)
+ if(BUILD_TESTING)
+ add_subdirectory(test)
+ endif()
endif()
return TRUE;
}
+#ifdef __UCLIBC__
+int eventfd_read(int fd, eventfd_t* value)
+{
+ return (read(fd, value, sizeof(*value)) == sizeof(*value)) ? 0 : -1;
+}
+
+int eventfd_write(int fd, eventfd_t value)
+{
+ return (write(fd, &value, sizeof(value)) == sizeof(value)) ? 0 : -1;
+}
+#endif
#endif /* __linux__ */
BOOL CommIsHandled(HANDLE handle);
BOOL CommCloseHandle(HANDLE handle);
+#ifdef __UCLIBC__
+int eventfd_read(int fd, eventfd_t* value);
+int eventfd_write(int fd, eventfd_t value);
+#endif
+
#endif /* __linux__ */
#endif /* WINPR_COMM_PRIVATE_H */
#include <unistd.h>
#include "comm_serial_sys.h"
+#ifdef __UCLIBC__
+#include "comm.h"
+#endif
#include <winpr/crt.h>
#include <winpr/wlog.h>
if (!hComm || (hComm == INVALID_HANDLE_VALUE))
{
- fprintf(stderr, "CreateFileA failure: %s GetLastError() = 0x%0.8x\n", lpFileName, GetLastError());
+ fprintf(stderr, "CreateFileA failure: %s GetLastError() = 0x%08x\n", lpFileName, GetLastError());
return EXIT_FAILURE;
}
ZeroMemory(&commProp, sizeof(COMMPROP));
if (!GetCommProperties(hComm, &commProp))
{
- fprintf(stderr, "GetCommProperties failure: GetLastError(): 0x0.8x\n", GetLastError());
+ fprintf(stderr, "GetCommProperties failure: GetLastError(): 0x%08x\n", GetLastError());
return EXIT_FAILURE;
}
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(hComm, &dcb))
{
- fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError());
+ fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError());
return FALSE;
}
if (!SetCommState(hComm, &dcb))
{
- fprintf(stderr, "SetCommState failure; GetLastError(): %0.8x\n", GetLastError());
+ fprintf(stderr, "SetCommState failure; GetLastError(): %08x\n", GetLastError());
return FALSE;
}
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(hComm, &dcb))
{
- fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError());
+ fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError());
return FALSE;
}
if (!SetCommState(hComm, &dcb))
{
- fprintf(stderr, "SetCommState failure; GetLastError(): %0.8x\n", GetLastError());
+ fprintf(stderr, "SetCommState failure; GetLastError(): %08x\n", GetLastError());
return FALSE;
}
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(hComm, &dcb))
{
- fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError());
+ fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError());
return FALSE;
}
if (!CloseHandle(hComm))
{
- fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError());
+ fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError());
return EXIT_FAILURE;
}
if (!CloseHandle(hComm))
{
- fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError());
+ fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError());
return EXIT_FAILURE;
}
if (!CloseHandle(hComm))
{
- fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError());
+ fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError());
return EXIT_FAILURE;
}
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(hComm, &dcb))
{
- fprintf(stderr, "GetCommState failure, GetLastError(): 0x%0.8x\n", GetLastError());
+ fprintf(stderr, "GetCommState failure, GetLastError(): 0x%08x\n", GetLastError());
return FALSE;
}
dcb.XoffChar = XonChar;
if (!SetCommState(hComm, &dcb))
{
- fprintf(stderr, "SetCommState failure, GetLastError(): 0x%0.8x\n", GetLastError());
+ fprintf(stderr, "SetCommState failure, GetLastError(): 0x%08x\n", GetLastError());
return FALSE;
}
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(hComm, &dcb))
{
- fprintf(stderr, "GetCommState failure, GetLastError(): 0x%0.8x\n", GetLastError());
+ fprintf(stderr, "GetCommState failure, GetLastError(): 0x%08x\n", GetLastError());
return FALSE;
}
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(hComm, &dcb))
{
- fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError());
+ fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError());
return FALSE;
}
if (!CloseHandle(hComm))
{
- fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError());
+ fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError());
return EXIT_FAILURE;
}
result = SetCommState(hComm, &dcb);
if (!result)
{
- fprintf(stderr, "SetCommState failure: 0x%0.8x\n", GetLastError());
+ fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError());
return FALSE;
}
result = SetCommState(hComm, &dcb);
if (!result)
{
- fprintf(stderr, "SetCommState failure: 0x%0.8x\n", GetLastError());
+ fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError());
return FALSE;
}
result = SetCommState(hComm, &dcb);
if (!result)
{
- fprintf(stderr, "SetCommState failure: 0x%0.8x\n", GetLastError());
+ fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError());
return FALSE;
}
if (!CloseHandle(hComm))
{
- fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError());
+ fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError());
return EXIT_FAILURE;
}
if (!SetCommTimeouts(hComm, &timeouts))
{
- fprintf(stderr, "SetCommTimeouts failure, GetLastError: 0x%0.8x\n", GetLastError());
+ fprintf(stderr, "SetCommTimeouts failure, GetLastError: 0x%08x\n", GetLastError());
return FALSE;
}
ZeroMemory(&timeouts2, sizeof(COMMTIMEOUTS));
if (!GetCommTimeouts(hComm, &timeouts2))
{
- fprintf(stderr, "GetCommTimeouts failure, GetLastError: 0x%0.8x\n", GetLastError());
+ fprintf(stderr, "GetCommTimeouts failure, GetLastError: 0x%08x\n", GetLastError());
return FALSE;
}
timeouts.ReadTotalTimeoutConstant = MAXULONG;
if (SetCommTimeouts(hComm, &timeouts))
{
- fprintf(stderr, "SetCommTimeouts succeeded with ReadIntervalTimeout and ReadTotalTimeoutConstant set to MAXULONG. GetLastError: 0x%0.8x\n", GetLastError());
+ fprintf(stderr, "SetCommTimeouts succeeded with ReadIntervalTimeout and ReadTotalTimeoutConstant set to MAXULONG. GetLastError: 0x%08x\n", GetLastError());
return FALSE;
}
if (GetLastError() != ERROR_INVALID_PARAMETER)
{
- fprintf(stderr, "SetCommTimeouts failure, expected GetLastError to return ERROR_INVALID_PARAMETER and got: 0x%0.8x\n", GetLastError());
+ fprintf(stderr, "SetCommTimeouts failure, expected GetLastError to return ERROR_INVALID_PARAMETER and got: 0x%08x\n", GetLastError());
return FALSE;
}
if (!CloseHandle(hComm))
{
- fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError());
+ fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError());
return EXIT_FAILURE;
}
#include <malloc.h>
#endif
+#include "../log.h"
+#define TAG WINPR_TAG("crt")
+
struct winpr_aligned_mem
{
UINT32 sig;
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;
}
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;
}
void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, size_t offset)
{
- size_t copySize;
void* newMemblock;
WINPR_ALIGNED_MEM* pMem;
WINPR_ALIGNED_MEM* pNewMem;
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;
}
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;
}
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;
}
#include "casing.c"
+#include "../log.h"
+#define TAG WINPR_TAG("crt")
+
char* _strdup(const char* strSource)
{
char* strDestination;
strDestination = strdup(strSource);
if (strDestination == NULL)
- perror("strdup");
+ WLog_ERR(TAG,"strdup");
return strDestination;
}
if (strSource == NULL)
return NULL;
-#if sun
+#if defined(sun) && sun
strDestination = wsdup(strSource);
#elif defined(__APPLE__) && defined(__MACH__) || defined(ANDROID)
strDestination = malloc(wcslen((wchar_t*)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;
}
*strToken++ = 0;
*context = strToken;
-
return nextToken;
}
return NULL;
length = strlen(lpsz);
+
if (length < 1)
return (LPSTR) NULL;
c = c - 32;
*lpsz = c;
-
return lpsz;
}
LPWSTR CharUpperW(LPWSTR lpsz)
{
- fprintf(stderr, "CharUpperW unimplemented!\n");
-
+ WLog_ERR(TAG, "CharUpperW unimplemented!");
return (LPWSTR) NULL;
}
c = c + 32;
*lpsz = c;
-
return lpsz;
}
LPWSTR CharLowerW(LPWSTR lpsz)
{
- fprintf(stderr, "CharLowerW unimplemented!\n");
-
+ WLog_ERR(TAG, "CharLowerW unimplemented!");
return (LPWSTR) NULL;
}
BOOL IsCharAlphaW(WCHAR ch)
{
- fprintf(stderr, "IsCharAlphaW unimplemented!\n");
+ WLog_ERR(TAG, "IsCharAlphaW unimplemented!");
return 0;
}
BOOL IsCharAlphaNumericW(WCHAR ch)
{
- fprintf(stderr, "IsCharAlphaNumericW unimplemented!\n");
+ WLog_ERR(TAG, "IsCharAlphaNumericW unimplemented!");
return 0;
}
BOOL IsCharUpperW(WCHAR ch)
{
- fprintf(stderr, "IsCharUpperW unimplemented!\n");
+ WLog_ERR(TAG, "IsCharUpperW unimplemented!");
return 0;
}
BOOL IsCharLowerW(WCHAR ch)
{
- fprintf(stderr, "IsCharLowerW unimplemented!\n");
+ WLog_ERR(TAG, "IsCharLowerW unimplemented!");
return 0;
}
TestTypes.c
TestAlignment.c
TestString.c
+ TestIntrinsics.c
TestUnicodeConversion.c)
create_test_sourcelist(${MODULE_PREFIX}_SRCS
--- /dev/null
+
+#include <winpr/crt.h>
+#include <winpr/sysinfo.h>
+#include <winpr/windows.h>
+
+static BOOL g_LZCNT = FALSE;
+
+static INLINE UINT32 lzcnt_s(UINT32 x)
+{
+ if (!x)
+ return 32;
+
+ if (!g_LZCNT)
+ {
+ UINT32 y;
+ int n = 32;
+ y = x >> 16; if (y != 0) { n = n - 16; x = y; }
+ y = x >> 8; if (y != 0) { n = n - 8; x = y; }
+ y = x >> 4; if (y != 0) { n = n - 4; x = y; }
+ y = x >> 2; if (y != 0) { n = n - 2; x = y; }
+ y = x >> 1; if (y != 0) return n - 2;
+ return n - x;
+ }
+
+ return __lzcnt(x);
+}
+
+int test_lzcnt()
+{
+ if (lzcnt_s(0x1) != 31) {
+ fprintf(stderr, "__lzcnt(0x1) != 31: %d\n", __lzcnt(0x1));
+ return -1;
+ }
+
+ if (lzcnt_s(0xFF) != 24) {
+ fprintf(stderr, "__lzcnt(0xFF) != 24\n");
+ return -1;
+ }
+
+ if (lzcnt_s(0xFFFF) != 16) {
+ fprintf(stderr, "__lzcnt(0xFFFF) != 16\n");
+ return -1;
+ }
+
+ if (lzcnt_s(0xFFFFFF) != 8) {
+ fprintf(stderr, "__lzcnt(0xFFFFFF) != 8\n");
+ return -1;
+ }
+
+ if (lzcnt_s(0xFFFFFFFF) != 0) {
+ fprintf(stderr, "__lzcnt(0xFFFFFFFF) != 0\n");
+ return -1;
+ }
+
+ return 1;
+}
+
+int test_lzcnt16()
+{
+ if (__lzcnt16(0x1) != 15) {
+ fprintf(stderr, "__lzcnt16(0x1) != 15\n");
+ return -1;
+ }
+
+ if (__lzcnt16(0xFF) != 8) {
+ fprintf(stderr, "__lzcnt16(0xFF) != 8\n");
+ return -1;
+ }
+
+ if (__lzcnt16(0xFFFF) != 0) {
+ fprintf(stderr, "__lzcnt16(0xFFFF) != 0\n");
+ return -1;
+ }
+
+ return 1;
+}
+
+int TestIntrinsics(int argc, char* argv[])
+{
+ g_LZCNT = IsProcessorFeaturePresentEx(PF_EX_LZCNT);
+
+ printf("LZCNT available: %d\n", g_LZCNT);
+
+ test_lzcnt();
+ //test_lzcnt16();
+
+ return 0;
+}
/*
* 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
* 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
/* --------------------------------------------------------------------- */
-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;
}
/* --------------------------------------------------------------------- */
* 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
};
/*
* 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
const WCHAR* source;
BOOL computeLength;
ConversionResult result;
-
computeLength = (!targetEnd) ? TRUE : FALSE;
-
source = *sourceStart;
target = *targetStart;
result = conversionOK;
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)
{
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]);
}
{
switch (bytesToWrite)
{
- /* note: everything falls through. */
-
+ /* note: everything falls through. */
case 4:
--target;
ch >>= 6;
*sourceStart = source;
*targetStart = target;
-
return result;
}
* 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)
* 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;
const BYTE* source;
BOOL computeLength;
ConversionResult result;
-
computeLength = (!targetEnd) ? TRUE : FALSE;
-
result = conversionOK;
source = *sourceStart;
target = *targetStart;
*/
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];
{
/* 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)
else
{
/* target is a character in range 0xFFFF - 0x10FFFF. */
-
if ((target + 1 >= targetEnd) && (!computeLength))
{
source -= (extraBytesToRead + 1); /* Back up source pointer! */
*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;
}
/* ---------------------------------------------------------------------
#include <winpr/crt.h>
#include <winpr/print.h>
#include <winpr/crypto.h>
+#include <winpr/wlog.h>
static const char* SECRET_PASSWORD_TEST = "MySecretPassword123!";
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));
}
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))
{
}
printf("Decrypted CipherText: %s\n", pCipherText);
-
SecureZeroMemory(pCipherText, cbCipherText);
free(pCipherText);
-
return 0;
}
#include <fcntl.h>
#endif
+#include "../log.h"
+#define TAG WINPR_TAG("file")
+
/**
* api-ms-win-core-file-l1-2-0.dll:
*
*/
/* _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);
}
return FALSE;
}
-
EnterCriticalSection(&_HandleCreatorsLock);
for (i=0; i<HANDLE_CREATOR_MAX; i++)
if (_HandleCreators[i] == NULL)
{
_HandleCreators[i] = pHandleCreator;
-
-
LeaveCriticalSection(&_HandleCreatorsLock);
return TRUE;
}
}
SetLastError(ERROR_INSUFFICIENT_BUFFER);
-
LeaveCriticalSection(&_HandleCreatorsLock);
return FALSE;
}
void AioSignalHandler(int signum, siginfo_t* siginfo, void* arg)
{
- printf("AioSignalHandler\n");
+ WLog_INFO("%d", signum);
}
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;
}
#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;
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;
}
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;
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)
if (flags != -1)
fcntl(pNamedPipe->clientfd, F_SETFL, flags | O_NONBLOCK);
+
#endif
}
}
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;
}
BOOL DeleteFileA(LPCSTR lpFileName)
{
int status;
-
status = unlink(lpFileName);
-
return (status != -1) ? TRUE : FALSE;
}
}
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;
}
{
int io_status;
WINPR_PIPE* pipe;
-
pipe = (WINPR_PIPE*) Object;
do
{
int io_status;
WINPR_NAMED_PIPE* pipe;
-
pipe = (WINPR_NAMED_PIPE*) Object;
if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
case EWOULDBLOCK:
SetLastError(ERROR_NO_DATA);
break;
+
default:
SetLastError(ERROR_BROKEN_PIPE);
break;
else
{
/* Overlapped I/O */
-
if (!lpOverlapped)
return FALSE;
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;
return status;
}
#else
-
/* synchronous behavior */
-
lpOverlapped->Internal = 0;
lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToRead;
lpOverlapped->Pointer = (PVOID) lpBuffer;
-
SetEvent(lpOverlapped->hEvent);
-
#endif
}
}
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;
}
{
int io_status;
WINPR_PIPE* pipe;
-
pipe = (WINPR_PIPE*) Object;
do
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))
{
*lpNumberOfBytesWritten = 0;
- switch(errno)
+ switch (errno)
{
case EWOULDBLOCK:
io_status = 0;
status = TRUE;
break;
+
default:
status = FALSE;
}
else
{
/* Overlapped I/O */
-
if (!lpOverlapped)
return FALSE;
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;
return status;
}
#else
-
/* synchronous behavior */
-
lpOverlapped->Internal = 1;
lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToWrite;
lpOverlapped->Pointer = (PVOID) lpBuffer;
-
SetEvent(lpOverlapped->hEvent);
-
#endif
}
}
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;
}
}
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;
}
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)
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);
}
/* Open directory for reading */
-
pFileSearch->pDir = opendir(pFileSearch->lpPath);
if (!pFileSearch->pDir)
}
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;
}
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;
}
return NULL;
lpFileName = _strdup(&lpName[strlen(NAMED_PIPE_PREFIX_PATH)]);
-
return lpFileName;
}
{
char* lpTempPath;
char* lpPipePath;
-
lpTempPath = GetKnownPath(KNOWN_PATH_TEMP);
lpPipePath = GetCombinedPath(lpTempPath, ".pipe");
-
free(lpTempPath);
-
return lpPipePath;
}
char* lpPipePath;
char* lpFileName;
char* lpFilePath;
-
lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA();
-
lpFileName = GetNamedPipeNameWithoutPrefixA(lpName);
lpFilePath = GetCombinedPath(lpPipePath, (char*) lpFileName);
-
free(lpPipePath);
free(lpFileName);
-
return lpFilePath;
}
#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;
{
#ifndef _WIN32
mode_t fl = 0;
-
fl |= (flags & 0x4000) ? S_ISUID : 0;
fl |= (flags & 0x2000) ? S_ISGID : 0;
fl |= (flags & 0x1000) ? S_ISVTX : 0;
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;
#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
LPSTR FilePatternFindNextWildcardA(LPCSTR lpPattern, DWORD* pFlags)
{
LPSTR lpWildcard;
-
*pFlags = 0;
lpWildcard = strpbrk(lpPattern, "*?~");
}
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;
/*
* State 0: match 'X'
*/
-
if (_strnicmp(lpFileName, lpX, cchX) != 0)
return FALSE;
/**
* State 3: final state
*/
-
*ppMatchEnd = (LPSTR) &lpMatch[cchY];
-
return TRUE;
}
else if (*lpWildcard == '?')
/*
* State 0: match 'X'
*/
-
if (cchFileName < cchX)
return FALSE;
if (_strnicmp(lpMatch, lpY, cchY) != 0)
return FALSE;
- }
+ }
else
{
if ((cchX + 1) > 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;
}
if (!FilePatternFindNextWildcardA(lpTail, &dwFlags))
{
/* tail contains no wildcards */
-
if (cchFileName < cchTail)
return FALSE;
* ^EOF of .^
*
*/
-
lpWildcard = FilePatternFindNextWildcardA(lpPattern, &dwFlags);
if (lpWildcard)
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);
{
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
{
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);
}
else
{
/* no wildcard characters */
-
if (_stricmp(lpFileName, lpPattern) == 0)
return TRUE;
}
/* _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;
if (_HandleCloseCbs[i] == NULL)
{
_HandleCloseCbs[i] = pHandleCloseCb;
-
LeaveCriticalSection(&_HandleCloseCbsLock);
return TRUE;
}
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;
}
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)
close(event->pipe_fd[0]);
event->pipe_fd[0] = -1;
}
+
if (event->pipe_fd[1] != -1)
{
close(event->pipe_fd[1]);
}
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)
}
#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
+#endif
free(Object);
-
return TRUE;
}
else if (Type == HANDLE_TYPE_ANONYMOUS_PIPE)
{
WINPR_PIPE* pipe;
-
pipe = (WINPR_PIPE*) Object;
if (pipe->fd != -1)
}
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);
}
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)
free(token->Domain);
free(token);
-
return TRUE;
}
}
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;
}
#define WINPR_HANDLE_SET_TYPE(_handle, _type) \
_handle->Type = _type
-static inline BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject)
+static INLINE BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject)
{
WINPR_HANDLE* wHandle;
return TRUE;
}
-
typedef BOOL (*pcIsHandled)(HANDLE handle);
typedef BOOL (*pcCloseHandle)(HANDLE handle);
return previousValue;
}
-#elif ANDROID || (defined(__GNUC__) && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8))
+#elif (defined(ANDROID) && ANDROID) || (defined(__GNUC__) && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8))
#include <pthread.h>
#include <winpr/library.h>
+#include "../log.h"
+#define TAG WINPR_TAG("library")
+
/**
* api-ms-win-core-libraryloader-l1-1-1.dll:
*
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;
}
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;
}
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;
}
BOOL FreeLibrary(HMODULE hLibModule)
{
int status;
-
status = dlclose(hLibModule);
if (status != 0)
}
DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
-{
+{
#if defined(__linux__)
int status;
int length;
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)
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);
CopyMemory(lpFilename, buffer, nSize - 1);
lpFilename[nSize - 1] = '\0';
}
-
+
return 0;
}
-#endif
+#endif
return 0;
}
/**
* FreeRDP: A Remote Desktop Protocol Implementation
- * X11 Server Graphical Updates
+ * Winpr log defines
*
- * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.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.
* limitations under the License.
*/
-#ifndef __XF_UPDATE_H
-#define __XF_UPDATE_H
+#ifndef WINPR_LOG_PRIV_H
+#define WINPR_LOG_PRIV_H
-#include "xfreerdp.h"
+#include <winpr/wlog.h>
-void* xf_update_thread(void* param);
-
-#endif /* __XF_UPDATE_H */
+#define WINPR_TAG(tag) "com.winpr." tag
+#endif /* FREERDP_UTILS_DEBUG_H */
return subPath;
}
+char* GetEnvironmentPath(char* name)
+{
+ char* env;
+ DWORD nSize;
+
+ nSize = GetEnvironmentVariableA(name, NULL, 0);
+
+ if (nSize)
+ {
+ env = (LPSTR) malloc(nSize);
+ nSize = GetEnvironmentVariableA(name, env, nSize);
+ }
+
+ return env;
+}
+
+char* GetEnvironmentSubPath(char* name, const char* path)
+{
+ char* env;
+ char* subpath;
+
+ env = GetEnvironmentPath(name);
+
+ if (!env)
+ return NULL;
+
+ subpath = GetCombinedPath(env, path);
+
+ free(env);
+
+ return subpath;
+}
+
char* GetCombinedPath(const char* basePath, const char* subPath)
{
int length;
return path;
}
-//#ifndef _WIN32
-
BOOL PathFileExistsA(LPCSTR pszPath)
{
struct stat stat_info;
return FALSE;
}
-//#endif
#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.,
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;
}
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;
}
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;
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;
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;
}
}
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;
}
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++;
if (flags != -1)
fcntl(pNamedPipe->serverfd, F_SETFL, flags | O_NONBLOCK);
+
#endif
}
hNamedPipe = (HANDLE) pNamedPipe;
-
out:
+
if (hNamedPipe == INVALID_HANDLE_VALUE)
{
if (pNamedPipe)
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;
}
{
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;
}
return FALSE;
pNamedPipe->lpOverlapped = lpOverlapped;
-
/* synchronous behavior */
-
lpOverlapped->Internal = 2;
lpOverlapped->InternalHigh = (ULONG_PTR) 0;
lpOverlapped->Pointer = (PVOID) NULL;
-
SetEvent(lpOverlapped->hEvent);
}
BOOL DisconnectNamedPipe(HANDLE hNamedPipe)
{
WINPR_NAMED_PIPE* pNamedPipe;
-
pNamedPipe = (WINPR_NAMED_PIPE*) hNamedPipe;
if (pNamedPipe->clientfd != -1)
}
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;
}
break;
}
}
+
free(lpFilePath);
return status;
}
BOOL WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
{
+ WLog_ERR(TAG, "Not implemented");
return TRUE;
}
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)
if (lpMaxCollectionCount)
{
-
}
if (lpCollectDataTimeout)
{
-
}
return TRUE;
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;
}
#include <winpr/winpr.h>
#include <winpr/print.h>
#include <winpr/synch.h>
+#include <winpr/wlog.h>
#include <winpr/thread.h>
#ifndef _WIN32
#include <signal.h>
DWORD nNumberOfBytesToWrite;
DWORD lpNumberOfBytesRead;
DWORD lpNumberOfBytesWritten;
-
WaitForSingleObject(ReadyEvent, INFINITE);
-
hNamedPipe = CreateFile(lpszPipeNameMt, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (!hNamedPipe)
lpNumberOfBytesWritten = 0;
nNumberOfBytesToWrite = PIPE_BUFFER_SIZE;
-
FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x59);
if (!WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten, NULL) ||
- lpNumberOfBytesWritten != nNumberOfBytesToWrite)
+ lpNumberOfBytesWritten != nNumberOfBytesToWrite)
{
printf("%s: Client NamedPipe WriteFile failure\n", __FUNCTION__);
goto out;
lpNumberOfBytesRead = 0;
nNumberOfBytesToRead = PIPE_BUFFER_SIZE;
-
ZeroMemory(lpReadBuffer, PIPE_BUFFER_SIZE);
if (!ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, &lpNumberOfBytesRead, NULL) ||
- lpNumberOfBytesRead != nNumberOfBytesToRead)
+ lpNumberOfBytesRead != nNumberOfBytesToRead)
{
printf("%s: Client NamedPipe ReadFile failure\n", __FUNCTION__);
goto out;
}
printf("Client ReadFile (%d):\n", lpNumberOfBytesRead);
- winpr_HexDump(lpReadBuffer, lpNumberOfBytesRead);
+ winpr_HexDump("pipe.test", WLOG_DEBUG, lpReadBuffer, lpNumberOfBytesRead);
fSuccess = TRUE;
-
out:
free(lpReadBuffer);
free(lpWriteBuffer);
CloseHandle(hNamedPipe);
+
if (!fSuccess)
- testFailed = TRUE;
+ testFailed = TRUE;
+
return NULL;
}
DWORD nNumberOfBytesToWrite;
DWORD lpNumberOfBytesRead;
DWORD lpNumberOfBytesWritten;
-
hNamedPipe = CreateNamedPipe(lpszPipeNameMt,
- PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
- PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL);
+ PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL);
if (!hNamedPipe)
{
}
SetEvent(ReadyEvent);
-
fConnected = ConnectNamedPipe(hNamedPipe, NULL);
if (!fConnected)
lpNumberOfBytesRead = 0;
nNumberOfBytesToRead = PIPE_BUFFER_SIZE;
-
ZeroMemory(lpReadBuffer, PIPE_BUFFER_SIZE);
if (!ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, &lpNumberOfBytesRead, NULL) ||
- lpNumberOfBytesRead != nNumberOfBytesToRead)
+ lpNumberOfBytesRead != nNumberOfBytesToRead)
{
printf("%s: Server NamedPipe ReadFile failure\n", __FUNCTION__);
goto out;
}
printf("Server ReadFile (%d):\n", lpNumberOfBytesRead);
- winpr_HexDump(lpReadBuffer, lpNumberOfBytesRead);
-
+ winpr_HexDump("pipe.test", WLOG_DEBUG, lpReadBuffer, lpNumberOfBytesRead);
lpNumberOfBytesWritten = 0;
nNumberOfBytesToWrite = PIPE_BUFFER_SIZE;
-
FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x45);
if (!WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten, NULL) ||
- lpNumberOfBytesWritten != nNumberOfBytesToWrite)
+ lpNumberOfBytesWritten != nNumberOfBytesToWrite)
{
printf("%s: Server NamedPipe WriteFile failure\n", __FUNCTION__);
goto out;
}
- fSuccess = TRUE;
+ fSuccess = TRUE;
out:
free(lpReadBuffer);
free(lpWriteBuffer);
CloseHandle(hNamedPipe);
+
if (!fSuccess)
- testFailed = TRUE;
+ testFailed = TRUE;
+
return NULL;
}
#ifndef _WIN32
WINPR_NAMED_PIPE* p;
#endif
-
numPipes = TESTNUMPIPESST;
-
memset(servers, 0, sizeof(servers));
memset(clients, 0, sizeof(clients));
-
WaitForSingleObject(ReadyEvent, INFINITE);
for (i = 0; i < numPipes; i++)
{
if (!(servers[i] = CreateNamedPipe(lpszPipeNameSt,
- PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
- PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL)))
+ PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL)))
{
printf("%s: CreateNamedPipe #%d failed\n", __FUNCTION__, i);
goto out;
}
#ifndef _WIN32
+
for (i = 0; i < numPipes; i++)
{
p = (WINPR_NAMED_PIPE*)servers[i];
if (strcmp(lpszPipeNameSt, p->name))
{
printf("%s: Pipe name mismatch for pipe #%d ([%s] instead of [%s])\n",
- __FUNCTION__, i, p->name, lpszPipeNameSt);
+ __FUNCTION__, i, p->name, lpszPipeNameSt);
goto out;
}
if (p->clientfd != -1)
{
printf("%s: Unexpected client fd value for pipe #%d (%d instead of -1)\n",
- __FUNCTION__, i, p->clientfd);
+ __FUNCTION__, i, p->clientfd);
goto out;
}
if (p->serverfd < 1)
{
printf("%s: Unexpected server fd value for pipe #%d (%d is not > 0)\n",
- __FUNCTION__, i, p->serverfd);
+ __FUNCTION__, i, p->serverfd);
goto out;
}
if (p->ServerMode == FALSE)
{
printf("%s: Unexpected ServerMode value for pipe #%d (0 instead of 1)\n",
- __FUNCTION__, i);
+ __FUNCTION__, i);
goto out;
}
}
+
#endif
for (i = 0; i < numPipes; i++)
{
if (!(clients[i] = CreateFile(lpszPipeNameSt, GENERIC_READ | GENERIC_WRITE,
- 0, NULL, OPEN_EXISTING, 0, NULL)))
+ 0, NULL, OPEN_EXISTING, 0, NULL)))
{
printf("%s: CreateFile #%d failed\n", __FUNCTION__, i);
goto out;
}
#ifndef _WIN32
+
for (i = 0; i < numPipes; i++)
{
p = servers[i];
if (p->clientfd < 1)
{
printf("%s: Unexpected client fd value for pipe #%d (%d is not > 0)\n",
- __FUNCTION__, i, p->clientfd);
+ __FUNCTION__, i, p->clientfd);
goto out;
}
if (p->ServerMode)
{
printf("%s: Unexpected ServerMode value for pipe #%d (1 instead of 0)\n",
- __FUNCTION__, i);
+ __FUNCTION__, i);
goto out;
}
}
for (i = 0; i < numPipes; i++)
{
/* Test writing from clients to servers */
-
ZeroMemory(sndbuf, sizeof(sndbuf));
ZeroMemory(rcvbuf, sizeof(rcvbuf));
sprintf_s(sndbuf, sizeof(sndbuf), "CLIENT->SERVER ON PIPE #%05d", i);
-
p = servers[i];
if (!WriteFile(clients[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL) ||
- dwWritten != sizeof(sndbuf))
+ dwWritten != sizeof(sndbuf))
{
printf("%s: Error writing to client end of pipe #%d\n", __FUNCTION__, i);
goto out;
}
if (!ReadFile(servers[i], rcvbuf, dwWritten, &dwRead, NULL) ||
- dwRead != dwWritten)
+ dwRead != dwWritten)
{
printf("%s: Error reading on server end of pipe #%d\n", __FUNCTION__, i);
goto out;
if (memcmp(sndbuf, rcvbuf, sizeof(sndbuf)))
{
printf("%s: Error data read on server end of pipe #%d is corrupted\n",
- __FUNCTION__, i);
+ __FUNCTION__, i);
goto out;
}
/* Test writing from servers to clients */
-
ZeroMemory(sndbuf, sizeof(sndbuf));
ZeroMemory(rcvbuf, sizeof(rcvbuf));
sprintf_s(sndbuf, sizeof(sndbuf), "SERVER->CLIENT ON PIPE #%05d", i);
-
p = servers[i];
+
if (!WriteFile(servers[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL) ||
- dwWritten != sizeof(sndbuf))
+ dwWritten != sizeof(sndbuf))
{
printf("%s: Error writing to server end of pipe #%d\n", __FUNCTION__, i);
goto out;
}
if (!ReadFile(clients[i], rcvbuf, dwWritten, &dwRead, NULL) ||
- dwRead != dwWritten)
+ dwRead != dwWritten)
{
printf("%s: Error reading on client end of pipe #%d\n", __FUNCTION__, i);
goto out;
if (memcmp(sndbuf, rcvbuf, sizeof(sndbuf)))
{
printf("%s: Error data read on client end of pipe #%d is corrupted\n",
- __FUNCTION__, i);
+ __FUNCTION__, i);
goto out;
}
}
-#endif
+#endif
/**
* After DisconnectNamedPipe on server end
* ReadFile/WriteFile must fail on client end
*/
i = numPipes - 1;
-
DisconnectNamedPipe(servers[i]);
if (ReadFile(clients[i], rcvbuf, sizeof(rcvbuf), &dwRead, NULL))
CloseHandle(servers[i]);
CloseHandle(clients[i]);
-
numPipes--;
-
-
/**
* After CloseHandle (without calling DisconnectNamedPipe first) on server end
* ReadFile/WriteFile must fail on client end
*/
i = numPipes - 1;
-
CloseHandle(servers[i]);
if (ReadFile(clients[i], rcvbuf, sizeof(rcvbuf), &dwRead, NULL))
}
CloseHandle(clients[i]);
-
numPipes--;
-
-
/**
* After CloseHandle on client end
* ReadFile/WriteFile must fail on server end
*/
i = numPipes - 1;
-
CloseHandle(clients[i]);
if (ReadFile(servers[i], rcvbuf, sizeof(rcvbuf), &dwRead, NULL))
DisconnectNamedPipe(servers[i]);
CloseHandle(servers[i]);
-
numPipes--;
/* Close all remaining pipes */
CloseHandle(servers[i]);
CloseHandle(clients[i]);
}
- numPipes = 0;
+ numPipes = 0;
bSuccess = TRUE;
-
out:
+
if (!bSuccess)
testFailed = TRUE;
+
return NULL;
}
HANDLE SingleThread;
HANDLE ClientThread;
HANDLE ServerThread;
-
#ifndef _WIN32
- signal(SIGPIPE, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
#endif
-
ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
SingleThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_single_thread, NULL, 0, NULL);
ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL);
ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL);
-
WaitForSingleObject(SingleThread, INFINITE);
WaitForSingleObject(ClientThread, INFINITE);
WaitForSingleObject(ServerThread, INFINITE);
-
CloseHandle(SingleThread);
CloseHandle(ClientThread);
CloseHandle(ServerThread);
-
return testFailed;
}
#include <winpr/file.h>
#include <winpr/tchar.h>
#include <winpr/winpr.h>
+#include <winpr/wlog.h>
#include <winpr/print.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
DWORD nNumberOfBytesToRead;
DWORD nNumberOfBytesToWrite;
DWORD NumberOfBytesTransferred;
-
WaitForSingleObject(ReadyEvent, INFINITE);
-
hNamedPipe = CreateFile(lpszPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (!hNamedPipe)
lpReadBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE);
lpWriteBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE);
-
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
overlapped.hEvent = hEvent;
-
nNumberOfBytesToWrite = PIPE_BUFFER_SIZE;
-
FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x59);
-
fSuccess = WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, NULL, &overlapped);
if (!fSuccess)
printf("Client NamedPipe WriteFile failure: %d\n", GetLastError());
free(lpReadBuffer);
free(lpWriteBuffer);
-
CloseHandle(hNamedPipe);
CloseHandle(hEvent);
return NULL;
}
status = WaitForMultipleObjects(1, &hEvent, FALSE, INFINITE);
-
NumberOfBytesTransferred = 0;
fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, TRUE);
-
printf("Client GetOverlappedResult: fSuccess: %d NumberOfBytesTransferred: %d\n", fSuccess, NumberOfBytesTransferred);
-
nNumberOfBytesToRead = PIPE_BUFFER_SIZE;
-
ZeroMemory(lpReadBuffer, PIPE_BUFFER_SIZE);
-
fSuccess = ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, NULL, &overlapped);
if (!fSuccess)
printf("Client NamedPipe ReadFile failure: %d\n", GetLastError());
free(lpReadBuffer);
free(lpWriteBuffer);
-
CloseHandle(hNamedPipe);
CloseHandle(hEvent);
return NULL;
}
status = WaitForMultipleObjects(1, &hEvent, FALSE, INFINITE);
-
NumberOfBytesTransferred = 0;
fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, TRUE);
-
printf("Client GetOverlappedResult: fSuccess: %d NumberOfBytesTransferred: %d\n", fSuccess, NumberOfBytesTransferred);
-
printf("Client ReadFile (%d):\n", NumberOfBytesTransferred);
- winpr_HexDump(lpReadBuffer, NumberOfBytesTransferred);
-
+ winpr_HexDump("pipe.test", WLOG_DEBUG, lpReadBuffer, NumberOfBytesTransferred);
free(lpReadBuffer);
free(lpWriteBuffer);
-
CloseHandle(hNamedPipe);
CloseHandle(hEvent);
-
return NULL;
}
DWORD nNumberOfBytesToRead;
DWORD nNumberOfBytesToWrite;
DWORD NumberOfBytesTransferred;
-
hNamedPipe = CreateNamedPipe(lpszPipeName,
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
- PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL);
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL);
if (!hNamedPipe)
{
}
SetEvent(ReadyEvent);
-
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
overlapped.hEvent = hEvent;
-
fConnected = ConnectNamedPipe(hNamedPipe, &overlapped);
-
printf("ConnectNamedPipe status: %d\n", GetLastError());
if (!fConnected)
fConnected = (GetLastError() == ERROR_IO_PENDING);
status = WaitForMultipleObjects(1, &hEvent, FALSE, INFINITE);
-
NumberOfBytesTransferred = 0;
fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, TRUE);
-
printf("Server GetOverlappedResult: fSuccess: %d NumberOfBytesTransferred: %d\n", fSuccess, NumberOfBytesTransferred);
if (!fConnected)
{
printf("ConnectNamedPipe failure: %d\n", GetLastError());
-
CloseHandle(hNamedPipe);
CloseHandle(hEvent);
-
return NULL;
}
lpReadBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE);
lpWriteBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE);
-
nNumberOfBytesToRead = PIPE_BUFFER_SIZE;
-
ZeroMemory(lpReadBuffer, PIPE_BUFFER_SIZE);
-
fSuccess = ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, NULL, &overlapped);
if (!fSuccess)
printf("Server NamedPipe ReadFile failure: %d\n", GetLastError());
free(lpReadBuffer);
free(lpWriteBuffer);
-
CloseHandle(hNamedPipe);
CloseHandle(hEvent);
-
return NULL;
}
status = WaitForMultipleObjects(1, &hEvent, FALSE, INFINITE);
-
NumberOfBytesTransferred = 0;
fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, TRUE);
-
printf("Server GetOverlappedResult: fSuccess: %d NumberOfBytesTransferred: %d\n", fSuccess, NumberOfBytesTransferred);
-
printf("Server ReadFile (%d):\n", NumberOfBytesTransferred);
- winpr_HexDump(lpReadBuffer, NumberOfBytesTransferred);
-
+ winpr_HexDump("pipe.test", WLOG_DEBUG, lpReadBuffer, NumberOfBytesTransferred);
nNumberOfBytesToWrite = PIPE_BUFFER_SIZE;
-
FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x45);
-
fSuccess = WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, NULL, &overlapped);
if (!fSuccess)
if (!fSuccess)
{
printf("Server NamedPipe WriteFile failure: %d\n", GetLastError());
-
free(lpReadBuffer);
free(lpWriteBuffer);
-
CloseHandle(hNamedPipe);
CloseHandle(hEvent);
-
return NULL;
}
status = WaitForMultipleObjects(1, &hEvent, FALSE, INFINITE);
-
NumberOfBytesTransferred = 0;
fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, TRUE);
-
printf("Server GetOverlappedResult: fSuccess: %d NumberOfBytesTransferred: %d\n", fSuccess, NumberOfBytesTransferred);
-
free(lpReadBuffer);
free(lpWriteBuffer);
-
CloseHandle(hNamedPipe);
CloseHandle(hEvent);
-
return NULL;
}
{
HANDLE ClientThread;
HANDLE ServerThread;
-
ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL);
ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL);
-
WaitForSingleObject(ClientThread, INFINITE);
WaitForSingleObject(ServerThread, INFINITE);
-
return 0;
}
#include <winpr/pool.h>
#include "pool.h"
+#include "../log.h"
+#define TAG WINPR_TAG("pool")
#ifdef _WIN32
static BOOL module_available = FALSE;
static HMODULE kernel32_module = NULL;
-static PTP_WORK (WINAPI * pCreateThreadpoolWork)(PTP_WORK_CALLBACK pfnwk, PVOID pv, PTP_CALLBACK_ENVIRON pcbe);
-static VOID (WINAPI * pCloseThreadpoolWork)(PTP_WORK pwk);
-static VOID (WINAPI * pSubmitThreadpoolWork)(PTP_WORK pwk);
-static BOOL (WINAPI * pTrySubmitThreadpoolCallback)(PTP_SIMPLE_CALLBACK pfns, PVOID pv, PTP_CALLBACK_ENVIRON pcbe);
-static VOID (WINAPI * pWaitForThreadpoolWorkCallbacks)(PTP_WORK pwk, BOOL fCancelPendingCallbacks);
+static PTP_WORK(WINAPI* pCreateThreadpoolWork)(PTP_WORK_CALLBACK pfnwk, PVOID pv, PTP_CALLBACK_ENVIRON pcbe);
+static VOID (WINAPI* pCloseThreadpoolWork)(PTP_WORK pwk);
+static VOID (WINAPI* pSubmitThreadpoolWork)(PTP_WORK pwk);
+static BOOL (WINAPI* pTrySubmitThreadpoolCallback)(PTP_SIMPLE_CALLBACK pfns, PVOID pv, PTP_CALLBACK_ENVIRON pcbe);
+static VOID (WINAPI* pWaitForThreadpoolWorkCallbacks)(PTP_WORK pwk, BOOL fCancelPendingCallbacks);
static void module_init()
{
return;
module_available = TRUE;
-
pCreateThreadpoolWork = (void*) GetProcAddress(kernel32_module, "CreateThreadpoolWork");
pCloseThreadpoolWork = (void*) GetProcAddress(kernel32_module, "CloseThreadpoolWork");
pSubmitThreadpoolWork = (void*) GetProcAddress(kernel32_module, "SubmitThreadpoolWork");
PTP_WORK CreateThreadpoolWork(PTP_WORK_CALLBACK pfnwk, PVOID pv, PTP_CALLBACK_ENVIRON pcbe)
{
PTP_WORK work = NULL;
-
#ifdef _WIN32
module_init();
if (pCreateThreadpoolWork)
return pCreateThreadpoolWork(pfnwk, pv, pcbe);
+
#else
work = (PTP_WORK) malloc(sizeof(TP_WORK));
work->CallbackEnvironment = pcbe;
}
-#endif
+#endif
return work;
}
if (pCloseThreadpoolWork)
pCloseThreadpoolWork(pwk);
+
#else
free(pwk);
#endif
if (pSubmitThreadpoolWork)
pSubmitThreadpoolWork(pwk);
+
#else
PTP_POOL pool;
PTP_CALLBACK_INSTANCE callbackInstance;
-
pool = pwk->CallbackEnvironment->Pool;
-
callbackInstance = (PTP_CALLBACK_INSTANCE) malloc(sizeof(TP_CALLBACK_INSTANCE));
if (callbackInstance)
CountdownEvent_AddCount(pool->WorkComplete, 1);
Queue_Enqueue(pool->PendingQueue, callbackInstance);
}
+
#endif
}
if (pTrySubmitThreadpoolCallback)
return pTrySubmitThreadpoolCallback(pfns, pv, pcbe);
+
#else
#endif
return FALSE;
if (pWaitForThreadpoolWorkCallbacks)
pWaitForThreadpoolWorkCallbacks(pwk, fCancelPendingCallbacks);
+
#else
HANDLE event;
PTP_POOL pool;
-
pool = pwk->CallbackEnvironment->Pool;
event = CountdownEvent_WaitHandle(pool->WorkComplete);
if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0)
- printf("WaitForThreadpoolWorkCallbacks: error waiting on work completion\n");
+ WLog_ERR(TAG, "error waiting on work completion");
+
#endif
}
#include "registry_reg.h"
+#include "../log.h"
+#define TAG WINPR_TAG("registry")
+
#define WINPR_HKLM_HIVE "/etc/winpr/HKLM.reg"
static void reg_print_key(Reg* reg, RegKey* key);
static void reg_load_start(Reg* reg)
{
long int file_size;
-
fseek(reg->fp, 0, SEEK_END);
file_size = ftell(reg->fp);
fseek(reg->fp, 0, SEEK_SET);
-
reg->line = NULL;
reg->next_line = NULL;
reg->buffer = NULL;
reg->buffer[file_size] = '\n';
reg->buffer[file_size + 1] = '\0';
-
reg->next_line = strtok(reg->buffer, "\n");
}
char* type;
char* data;
RegVal* value;
-
p[0] = reg->line + 1;
p[1] = strstr(p[0], "\"=");
p[2] = p[1] + 2;
p[3] = strchr(p[2], ':');
data = p[3] + 1;
-
length = p[1] - p[0];
name = (char*) malloc(length + 1);
memcpy(name, p[0], length);
name[length] = '\0';
-
value = (RegVal*) malloc(sizeof(RegVal));
-
value->name = name;
value->type = REG_NONE;
value->next = value->prev = NULL;
}
else
{
- fprintf(stderr, "unimplemented format: %s\n", REG_DATA_TYPE_STRINGS[value->type]);
+ WLog_ERR(TAG, "unimplemented format: %s", REG_DATA_TYPE_STRINGS[value->type]);
}
if (!key->values)
reg->line = reg->next_line;
reg->next_line = strtok(NULL, "\n");
reg->line_length = strlen(reg->line);
-
return reg->line;
}
char* path;
char* save;
int length;
-
path = _strdup(subkey->name);
-
name = strtok_s(path, "\\", &save);
while (name != NULL)
int length;
char* line;
RegKey* subkey;
-
p[0] = reg->line + 1;
p[1] = strrchr(p[0], ']');
-
subkey = (RegKey*) malloc(sizeof(RegKey));
-
subkey->values = NULL;
subkey->prev = subkey->next = NULL;
-
length = p[1] - p[0];
subkey->name = (char*) malloc(length + 1);
memcpy(subkey->name, p[0], length);
{
if (value->type == REG_DWORD)
{
-
}
else if (value->type == REG_SZ)
{
}
else
{
- fprintf(stderr, "unimplemented format: %s\n", REG_DATA_TYPE_STRINGS[value->type]);
+ WLog_ERR(TAG, "unimplemented format: %s", REG_DATA_TYPE_STRINGS[value->type]);
}
free(value);
{
RegVal* pValue;
RegVal* pValueNext;
-
pValue = key->values;
while (pValue != NULL)
{
RegKey* pKey;
RegKey* pKeyNext;
-
pKey = reg->root_key->subkeys;
while (pKey != NULL)
Reg* reg_open(BOOL read_only)
{
Reg* reg;
-
reg = (Reg*) malloc(sizeof(Reg));
if (reg)
}
reg->root_key = (RegKey*) malloc(sizeof(RegKey));
-
reg->root_key->values = NULL;
reg->root_key->subkeys = NULL;
reg->root_key->name = "HKEY_LOCAL_MACHINE";
-
reg_load(reg);
}
void reg_print_value(Reg* reg, RegVal* value)
{
- fprintf(stderr, "\"%s\"=", value->name);
+ WLog_INFO(TAG, "\"%s\"=", value->name);
if (value->type == REG_DWORD)
{
- fprintf(stderr, "dword:%08X\n", (int) value->data.dword);
+ WLog_INFO(TAG, "dword:%08X", (int) value->data.dword);
}
else if (value->type == REG_SZ)
{
- fprintf(stderr, "%s\"\n", value->data.string);
+ WLog_INFO(TAG, "%s\"", value->data.string);
}
else
{
- fprintf(stderr, "unimplemented format: %s\n", REG_DATA_TYPE_STRINGS[value->type]);
+ WLog_ERR(TAG, "unimplemented format: %s", REG_DATA_TYPE_STRINGS[value->type]);
}
}
void reg_print_key(Reg* reg, RegKey* key)
{
RegVal* pValue;
-
pValue = key->values;
-
- fprintf(stderr, "[%s]\n", key->name);
+ WLog_INFO(TAG, "[%s]", key->name);
while (pValue != NULL)
{
void reg_print(Reg* reg)
{
RegKey* pKey;
-
pKey = reg->root_key->subkeys;
while (pKey != NULL)
#include "ndr_private.h"
+#include "../log.h"
+#define TAG WINPR_TAG("rpc")
+
/**
* MSRPC NDR Types Technical Overview:
* http://dvlabs.tippingpoint.com/blog/2007/11/24/msrpc-ndr-types/
void NdrPrintParamAttributes(PARAM_ATTRIBUTES attributes)
{
if (attributes.ServerAllocSize)
- fprintf(stderr, "ServerAllocSize, ");
+ WLog_INFO(TAG, "ServerAllocSize, ");
+
if (attributes.SaveForAsyncFinish)
- fprintf(stderr, "SaveForAsyncFinish, ");
+ WLog_INFO(TAG, "SaveForAsyncFinish, ");
+
if (attributes.IsDontCallFreeInst)
- fprintf(stderr, "IsDontCallFreeInst, ");
+ WLog_INFO(TAG, "IsDontCallFreeInst, ");
+
if (attributes.IsSimpleRef)
- fprintf(stderr, "IsSimpleRef, ");
+ WLog_INFO(TAG, "IsSimpleRef, ");
+
if (attributes.IsByValue)
- fprintf(stderr, "IsByValue, ");
+ WLog_INFO(TAG, "IsByValue, ");
+
if (attributes.IsBasetype)
- fprintf(stderr, "IsBaseType, ");
+ WLog_INFO(TAG, "IsBaseType, ");
+
if (attributes.IsReturn)
- fprintf(stderr, "IsReturn, ");
+ WLog_INFO(TAG, "IsReturn, ");
+
if (attributes.IsOut)
- fprintf(stderr, "IsOut, ");
+ WLog_INFO(TAG, "IsOut, ");
+
if (attributes.IsIn)
- fprintf(stderr, "IsIn, ");
+ WLog_INFO(TAG, "IsIn, ");
+
if (attributes.IsPipe)
- fprintf(stderr, "IsPipe, ");
+ WLog_INFO(TAG, "IsPipe, ");
+
if (attributes.MustFree)
- fprintf(stderr, "MustFree, ");
+ WLog_INFO(TAG, "MustFree, ");
+
if (attributes.MustSize)
- fprintf(stderr, "MustSize, ");
+ WLog_INFO(TAG, "MustSize, ");
}
void NdrProcessParam(PMIDL_STUB_MESSAGE pStubMsg, NDR_PHASE phase, unsigned char* pMemory, NDR_PARAM* param)
PFORMAT_STRING fmt;
unsigned char* arg;
unsigned char type;
-
params = (NDR_PARAM*) pFormat;
-
- fprintf(stderr, "Params = \n{\n");
+ WLog_INFO(TAG, "Params = ");
for (i = 0; i < numberParams; i++)
{
#ifdef __x86_64__
float tmp;
#endif
-
arg = pStubMsg->StackTop + params[i].StackOffset;
fmt = (PFORMAT_STRING) &pStubMsg->StubDesc->pFormatTypes[params[i].Type.Offset];
-
#ifdef __x86_64__
+
if ((params[i].Attributes.IsBasetype) &&
!(params[i].Attributes.IsSimpleRef) &&
((params[i].Type.FormatChar) == FC_FLOAT) && !fpuArgs)
tmp = *(double*) arg;
arg = (unsigned char*) &tmp;
}
-#endif
-
- fprintf(stderr, "\t#%d\t", i);
+#endif
type = (params[i].Attributes.IsBasetype) ? params[i].Type.FormatChar : *fmt;
-
- fprintf(stderr, " type %s (0x%02X) ", FC_TYPE_STRINGS[type], type);
-
+ WLog_INFO(TAG, "'\t#%d\ttype %s (0x%02X) ", i, FC_TYPE_STRINGS[type], type);
NdrPrintParamAttributes(params[i].Attributes);
if (params[i].Attributes.IsIn)
{
NdrProcessParam(pStubMsg, phase, arg, ¶ms[i]);
}
-
- fprintf(stderr, "\n");
}
-
- fprintf(stderr, "}\n");
}
void NdrClientInitializeNew(PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg,
- PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum)
+ PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum)
{
pRpcMessage->Handle = NULL;
pRpcMessage->RpcFlags = 0;
pRpcMessage->DataRepresentation = 0;
pRpcMessage->ReservedForRuntime = NULL;
pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
-
pStubMsg->RpcMsg = pRpcMessage;
pStubMsg->BufferStart = NULL;
pStubMsg->BufferEnd = NULL;
void NdrPrintOptFlags(INTERPRETER_OPT_FLAGS optFlags)
{
if (optFlags.ClientMustSize)
- fprintf(stderr, "ClientMustSize, ");
+ WLog_INFO(TAG, "ClientMustSize, ");
+
if (optFlags.ServerMustSize)
- fprintf(stderr, "ServerMustSize, ");
+ WLog_INFO(TAG, "ServerMustSize, ");
+
if (optFlags.HasAsyncUuid)
- fprintf(stderr, "HasAsyncUiid, ");
+ WLog_INFO(TAG, "HasAsyncUiid, ");
+
if (optFlags.HasAsyncHandle)
- fprintf(stderr, "HasAsyncHandle, ");
+ WLog_INFO(TAG, "HasAsyncHandle, ");
+
if (optFlags.HasReturn)
- fprintf(stderr, "HasReturn, ");
+ WLog_INFO(TAG, "HasReturn, ");
+
if (optFlags.HasPipes)
- fprintf(stderr, "HasPipes, ");
+ WLog_INFO(TAG, "HasPipes, ");
+
if (optFlags.HasExtensions)
- fprintf(stderr, "HasExtensions, ");
+ WLog_INFO(TAG, "HasExtensions, ");
}
void NdrPrintExtFlags(INTERPRETER_OPT_FLAGS2 extFlags)
{
if (extFlags.HasNewCorrDesc)
- fprintf(stderr, "HasNewCorrDesc, ");
+ WLog_INFO(TAG, "HasNewCorrDesc, ");
+
if (extFlags.ClientCorrCheck)
- fprintf(stderr, "ClientCorrCheck, ");
+ WLog_INFO(TAG, "ClientCorrCheck, ");
+
if (extFlags.ServerCorrCheck)
- fprintf(stderr, "ServerCorrCheck, ");
+ WLog_INFO(TAG, "ServerCorrCheck, ");
+
if (extFlags.HasNotify)
- fprintf(stderr, "HasNotify, ");
+ WLog_INFO(TAG, "HasNotify, ");
+
if (extFlags.HasNotify2)
- fprintf(stderr, "HasNotify2, ");
+ WLog_INFO(TAG, "HasNotify2, ");
}
CLIENT_CALL_RETURN NdrClientCall(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, void** stackTop, void** fpuStack)
NDR_PROC_HEADER* procHeader;
NDR_OI2_PROC_HEADER* oi2ProcHeader;
CLIENT_CALL_RETURN client_call_return;
-
procNum = stackSize = numberParams = 0;
procHeader = (NDR_PROC_HEADER*) &pFormat[0];
-
client_call_return.Pointer = NULL;
-
handleType = procHeader->HandleType;
flags = procHeader->OldOiFlags;
procNum = procHeader->ProcNum;
stackSize = procHeader->StackSize;
pFormat += sizeof(NDR_PROC_HEADER);
-
/* The Header: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378707/ */
/* Procedure Header Descriptor: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374387/ */
/* Handles: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373932/ */
-
- fprintf(stderr, "Oi Header: HandleType: 0x%02X OiFlags: 0x%02X ProcNum: %d StackSize: 0x%04X\n",
- handleType, *((unsigned char*) &flags),
- (unsigned short) procNum, (unsigned short) stackSize);
+ WLog_DBG(TAG, "Oi Header: HandleType: 0x%02X OiFlags: 0x%02X ProcNum: %d StackSize: 0x%04X",
+ handleType, *((unsigned char*) &flags),
+ (unsigned short) procNum, (unsigned short) stackSize);
if (handleType > 0)
{
/* implicit handle */
- fprintf(stderr, "Implicit Handle\n");
+ WLog_INFO(TAG, "Implicit Handle");
oi2ProcHeader = (NDR_OI2_PROC_HEADER*) &pFormat[0];
pFormat += sizeof(NDR_OI2_PROC_HEADER);
}
else
{
/* explicit handle */
- fprintf(stderr, "Explicit Handle\n");
+ WLog_INFO(TAG, "Explicit Handle");
oi2ProcHeader = (NDR_OI2_PROC_HEADER*) &pFormat[6];
pFormat += sizeof(NDR_OI2_PROC_HEADER) + 6;
}
optFlags = oi2ProcHeader->Oi2Flags;
numberParams = oi2ProcHeader->NumberParams;
-
- fprintf(stderr, "Oi2 Header: Oi2Flags: 0x%02X, NumberParams: %d ClientBufferSize: %d ServerBufferSize: %d\n",
- *((unsigned char*) &optFlags),
- (unsigned char) numberParams,
- oi2ProcHeader->ClientBufferSize,
- oi2ProcHeader->ServerBufferSize);
-
- fprintf(stderr, "Oi2Flags: ");
+ WLog_DBG(TAG, "Oi2 Header: Oi2Flags: 0x%02X, NumberParams: %d ClientBufferSize: %d ServerBufferSize: %d",
+ *((unsigned char*) &optFlags),
+ (unsigned char) numberParams,
+ oi2ProcHeader->ClientBufferSize,
+ oi2ProcHeader->ServerBufferSize);
+ WLog_INFO(TAG, "Oi2Flags: ");
NdrPrintOptFlags(optFlags);
- fprintf(stderr, "\n");
-
NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDescriptor, procNum);
if (optFlags.HasExtensions)
{
INTERPRETER_OPT_FLAGS2 extFlags;
NDR_PROC_HEADER_EXTS* extensions = (NDR_PROC_HEADER_EXTS*) pFormat;
-
pFormat += extensions->Size;
extFlags = extensions->Flags2;
-
- fprintf(stderr, "Extensions: Size: %d, flags2: 0x%02X\n",
- extensions->Size, *((unsigned char*) &extensions->Flags2));
-
+ WLog_DBG(TAG, "Extensions: Size: %d, flags2: 0x%02X",
+ extensions->Size, *((unsigned char*) &extensions->Flags2));
#ifdef __x86_64__
+
if (extensions->Size > sizeof(*extensions) && fpuStack)
{
int i;
- unsigned short fpuMask = *(unsigned short*) (extensions + 1);
+ unsigned short fpuMask = *(unsigned short*)(extensions + 1);
for (i = 0; i < 4; i++, fpuMask >>= 2)
{
switch (fpuMask & 3)
{
- case 1: *(float*) &stackTop[i] = *(float*) &fpuStack[i];
+ case 1:
+ *(float*) &stackTop[i] = *(float*) &fpuStack[i];
break;
- case 2: *(double*) &stackTop[i] = *(double*) &fpuStack[i];
+ case 2:
+ *(double*) &stackTop[i] = *(double*) &fpuStack[i];
break;
}
}
}
+
#endif
- fprintf(stderr, "ExtFlags: ");
+ WLog_INFO(TAG, "ExtFlags: ");
NdrPrintExtFlags(extFlags);
- fprintf(stderr, "\n");
}
stubMsg.StackTop = (unsigned char*) stackTop;
-
NdrProcessParams(&stubMsg, pFormat, NDR_PHASE_SIZE, fpuStack, numberParams);
-
- fprintf(stderr, "stubMsg BufferLength: %d\n", (int) stubMsg.BufferLength);
-
+ WLog_DBG(TAG, "stubMsg BufferLength: %d", (int) stubMsg.BufferLength);
return client_call_return;
}
{
va_list args;
CLIENT_CALL_RETURN client_call_return;
-
va_start(args, pFormat);
client_call_return = NdrClientCall(pStubDescriptor, pFormat, va_arg(args, void**), NULL);
va_end(args);
-
return client_call_return;
}
#include <winpr/rpc.h>
#include "ndr_array.h"
+#include "ndr_private.h"
#ifndef _WIN32
* element_description<>
* FC_END
*/
-
unsigned char type;
unsigned char alignment;
unsigned short element_size;
-
type = pFormat[0];
alignment = pFormat[1] + 1;
element_size = *(unsigned short*) &pFormat[2];
if (type != FC_CARRAY)
{
- fprintf(stderr, "error: expected FC_CARRAY, got 0x%02X\n", type);
+ WLog_ERR(TAG, "error: expected FC_CARRAY, got 0x%02X", type);
return;
}
- fprintf(stderr, "warning: NdrConformantArrayBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrConformantArrayBufferSize unimplemented");
}
void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
* element_description<>
* FC_END
*/
-
- fprintf(stderr, "warning: NdrConformantVaryingArrayBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrConformantVaryingArrayBufferSize unimplemented");
}
void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
* element_description<>
* FC_END
*/
-
/**
* FC_LGFARRAY
* alignment<1>
* element_description<>
* FC_END
*/
-
- fprintf(stderr, "warning: NdrFixedArrayBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrFixedArrayBufferSize unimplemented");
}
void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
* element_description<>
* FC_END
*/
-
/**
* FC_LGVARRAY
* alignment<1>
* element_description<>
* FC_END
*/
-
- fprintf(stderr, "warning: NdrVaryingArrayBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrVaryingArrayBufferSize unimplemented");
}
void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
* element_description<>
* FC_END
*/
-
- fprintf(stderr, "warning: NdrComplexArrayBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrComplexArrayBufferSize unimplemented");
}
#endif
#include "ndr_context.h"
#include "ndr_private.h"
+#include "../log.h"
+#define TAG WINPR_TAG("rpc")
+
void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
unsigned char type = *pFormat;
* flag<1>
* offset<2>
*/
-
- fprintf(stderr, "warning: NdrContextHandleBufferSize FC_BIND_PRIMITIVE unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrContextHandleBufferSize FC_BIND_PRIMITIVE unimplemented");
}
else if (type == FC_BIND_GENERIC)
{
* binding_routine_pair_index<1>
* FC_PAD
*/
-
- fprintf(stderr, "warning: NdrContextHandleBufferSize FC_BIND_GENERIC unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrContextHandleBufferSize FC_BIND_GENERIC unimplemented");
}
else if (type == FC_BIND_CONTEXT)
{
* context_rundown_routine_index<1>
* param_num<1>
*/
-
NdrpAlignLength(&(pStubMsg->BufferLength), 4);
NdrpIncrementLength(&(pStubMsg->BufferLength), 20);
}
unsigned char conformance;
unsigned char correlation_type;
unsigned char correlation_operator;
-
correlation_type = pFormat[0];
type = correlation_type & 0x0F;
conformance = correlation_type & 0xF0;
-
correlation_operator = pFormat[1];
offset = *(unsigned short*) & pFormat[2];
{
ptr = pStubMsg->StackTop;
}
- else if (conformance == FC_CONSTANT_CONFORMANCE )
+ else if (conformance == FC_CONSTANT_CONFORMANCE)
{
data = offset | ((DWORD) pFormat[1] << 16);
*pCount = data;
case FC_CALLBACK:
{
- fprintf(stderr, "warning: NdrpComputeConformance FC_CALLBACK unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrpComputeConformance FC_CALLBACK unimplemented\n");
}
break;
}
PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
ULONG_PTR ActualCount = pStubMsg->ActualCount;
-
pFormat = NdrpComputeCount(pStubMsg, pMemory, pFormat, &ActualCount);
pStubMsg->ActualCount = (ULONG) ActualCount;
-
return pFormat;
}
* FC_PAD
* pointer_instance<8>
*/
-
pFormat += 10;
}
else if (*pFormat == FC_FIXED_REPEAT)
{
unsigned short number_of_pointers;
-
/**
* FC_FIXED_REPEAT
* FC_PAD
* number_of_pointers<2>
* { pointer_instance<8> }*
*/
-
pFormat += 8;
number_of_pointers = *(unsigned short*) pFormat;
pFormat += 2 + (number_of_pointers * 8);
else if (*pFormat == FC_VARIABLE_REPEAT)
{
unsigned short number_of_pointers;
-
/**
* FC_VARIABLE_REPEAT (FC_FIXED_OFFSET | FC_VARIABLE_OFFSET)
* FC_PAD ?!
* number_of_pointers<2>
* { pointer_instance<8> }*
*/
-
pFormat += 6;
number_of_pointers = *(unsigned short*) pFormat;
pFormat += 2 + (number_of_pointers * 8);
}
else
{
- fprintf(stderr, "error: NdrpSkipPointerLayout unexpected 0x%02X\n", *pFormat);
+ WLog_ERR(TAG, "error: NdrpSkipPointerLayout unexpected 0x%02X", *pFormat);
break;
}
}
unsigned char attributes;
PFORMAT_STRING pNextFormat;
NDR_TYPE_SIZE_ROUTINE pfnSizeRoutine;
-
type = pFormat[0];
attributes = pFormat[1];
pFormat += 2;
{
case FC_RP: /* Reference Pointer */
break;
-
case FC_UP: /* Unique Pointer */
case FC_OP: /* Unique Pointer in an object interface */
return;
break;
-
case FC_FP: /* Full Pointer */
- fprintf(stderr, "warning: FC_FP unimplemented\n");
+ WLog_ERR(TAG, "warning: FC_FP unimplemented");
break;
}
unsigned short pointer_count;
unsigned short offset_to_array;
unsigned short number_of_pointers;
-
Memory = pStubMsg->Memory;
MemoryCopy = pStubMsg->Memory;
if (pFormat[1] == FC_VARIABLE_OFFSET)
{
- pMemory += pStubMsg->Offset * *((unsigned short*) &pFormat[1]);
+ pMemory += pStubMsg->Offset * (*(unsigned short*) &pFormat[1]);
}
}
pFormat += 2;
increment = *(unsigned short*) pFormat;
-
pFormat += 2;
offset_to_array = *(unsigned short*) pFormat;
pStubMsg->Memory = Memory + offset_to_array;
-
pFormat += 2;
number_of_pointers = *(unsigned short*) pFormat;
-
pFormat += 2;
-
pFormatPointers = pFormat;
if (MaxCount)
pFormat = pFormatPointers + (number_of_pointers * 8);
pStubMsg->Memory = Memory;
-
return pFormat;
}
unsigned long BufferLengthCopy = 0;
unsigned long PointerLength;
unsigned char* pMemoryPtr = NULL;
-
pFormatCopy = pFormat;
if (!pStubMsg->IgnoreEmbeddedPointers)
pStubMsg->Offset = Offset;
pStubMsg->MaxCount = MaxCount;
-
NdrpEmbeddedRepeatPointerBufferSize(pStubMsg, pMemory, pFormat, &pMemoryPtr);
}
void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
- fprintf(stderr, "warning: NdrByteCountPointerBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrByteCountPointerBufferSize unimplemented");
}
#endif
#include <winpr/rpc.h>
+#include "../log.h"
+#define TAG WINPR_TAG("rpc")
+
#ifndef _WIN32
void NdrpAlignLength(ULONG* length, unsigned int alignment);
#ifndef _WIN32
#include "ndr_string.h"
+#include "ndr_private.h"
void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
- fprintf(stderr, "warning: NdrConformantStringBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrConformantStringBufferSize unimplemented");
}
void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
- fprintf(stderr, "warning: NdrNonConformantStringBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrNonConformantStringBufferSize unimplemented");
}
#endif
* member_layout<>
* FC_END
*/
-
/**
* FC_PSTRUCT
* alignment<1>
* member_layout<>
* FC_END
*/
-
unsigned char type;
unsigned char alignment;
unsigned short memory_size;
-
type = pFormat[0];
alignment = pFormat[1] + 1;
memory_size = *(unsigned short*) &pFormat[2];
-
NdrpAlignLength(&(pStubMsg->BufferLength), alignment);
NdrpIncrementLength(&(pStubMsg->BufferLength), memory_size);
-
pFormat += 4;
if (*pFormat == FC_PSTRUCT)
NdrpEmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
- fprintf(stderr, "warning: NdrSimpleStructBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrSimpleStructBufferSize unimplemented");
}
void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
* member_layout<>
* FC_END
*/
-
/**
* FC_CPSTRUCT alignment<1>
* memory_size<2>
* pointer_layout<>
* member_layout<> FC_END
*/
-
- fprintf(stderr, "warning: NdrConformantStructBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrConformantStructBufferSize unimplemented");
}
void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
* layout<>
* FC_END
*/
-
- fprintf(stderr, "warning: NdrConformantVaryingStructBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrConformantVaryingStructBufferSize unimplemented");
}
ULONG NdrComplexStructMemberSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
case FC_FP:
case FC_POINTER:
size += sizeof(void*);
+
if (*pFormat != FC_POINTER)
pFormat += 4;
+
break;
case FC_ALIGNM2:
break;
case FC_EMBEDDED_COMPLEX:
- fprintf(stderr, "warning: NdrComplexStructMemberSize FC_EMBEDDED_COMPLEX unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrComplexStructMemberSize FC_EMBEDDED_COMPLEX unimplemented");
break;
default:
- fprintf(stderr, "warning: NdrComplexStructMemberSize 0x%02X unimplemented\n", *pFormat);
+ WLog_ERR(TAG, "warning: NdrComplexStructMemberSize 0x%02X unimplemented", *pFormat);
break;
}
* FC_END
* [pointer_layout<>]
*/
-
ULONG_PTR MaxCount;
unsigned long Offset;
unsigned long ActualCount;
unsigned char* pMemoryCopy;
-
unsigned char type;
unsigned char alignment;
unsigned short memory_size;
unsigned char* conformant_array_description;
unsigned short offset_to_pointer_layout;
unsigned short offset_to_conformant_array_description;
-
type = pFormat[0];
pMemoryCopy = pMemory;
pointer_layout = conformant_array_description = NULL;
if (type != FC_BOGUS_STRUCT)
{
- fprintf(stderr, "error: expected FC_BOGUS_STRUCT, got 0x%02X\n", type);
+ WLog_ERR(TAG, "error: expected FC_BOGUS_STRUCT, got 0x%02X", type);
return;
}
alignment = pFormat[1] + 1;
memory_size = *(unsigned short*) &pFormat[2];
-
NdrpAlignLength(&(pStubMsg->BufferLength), alignment);
if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
{
unsigned long BufferLengthCopy = pStubMsg->BufferLength;
int IgnoreEmbeddedPointersCopy = pStubMsg->IgnoreEmbeddedPointers;
-
pStubMsg->IgnoreEmbeddedPointers = 1;
NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
pStubMsg->IgnoreEmbeddedPointers = IgnoreEmbeddedPointersCopy;
-
pStubMsg->PointerLength = pStubMsg->BufferLength;
pStubMsg->BufferLength = BufferLengthCopy;
}
pFormat += 4;
-
offset_to_conformant_array_description = *(unsigned short*) &pFormat[0];
if (offset_to_conformant_array_description)
conformant_array_description = (unsigned char*) pFormat + offset_to_conformant_array_description;
- pFormat += 2;
+ pFormat += 2;
offset_to_pointer_layout = *(unsigned short*) &pFormat[0];
if (offset_to_pointer_layout)
pointer_layout = (unsigned char*) pFormat + offset_to_pointer_layout;
- pFormat += 2;
+ pFormat += 2;
pStubMsg->Memory = pMemory;
if (conformant_array_description)
{
ULONG size;
unsigned char array_type;
-
array_type = conformant_array_description[0];
size = NdrComplexStructMemberSize(pStubMsg, pFormat);
-
- fprintf(stderr, "warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented\n", array_type);
-
+ WLog_ERR(TAG, "warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented", array_type);
NdrpComputeConformance(pStubMsg, pMemory + size, conformant_array_description);
NdrpComputeVariance(pStubMsg, pMemory + size, conformant_array_description);
-
MaxCount = pStubMsg->MaxCount;
ActualCount = pStubMsg->ActualCount;
Offset = pStubMsg->Offset;
if (conformant_array_description)
{
unsigned char array_type;
-
array_type = conformant_array_description[0];
-
pStubMsg->MaxCount = MaxCount;
pStubMsg->ActualCount = ActualCount;
pStubMsg->Offset = Offset;
-
- fprintf(stderr, "warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented\n", array_type);
+ WLog_ERR(TAG, "warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented", array_type);
}
pStubMsg->Memory = pMemoryCopy;
#ifndef _WIN32
#include "ndr_union.h"
+#include "ndr_private.h"
void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
- fprintf(stderr, "warning: NdrEncapsulatedUnionBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrEncapsulatedUnionBufferSize unimplemented");
}
void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
- fprintf(stderr, "warning: NdrNonEncapsulatedUnionBufferSize unimplemented\n");
+ WLog_ERR(TAG, "warning: NdrNonEncapsulatedUnionBufferSize unimplemented");
}
#endif
#include <openssl/rand.h>
+#include "../log.h"
+#define TAG WINPR_TAG("rpc")
+
RPC_STATUS RpcBindingCopy(RPC_BINDING_HANDLE SourceBinding, RPC_BINDING_HANDLE* DestinationBinding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingFree(RPC_BINDING_HANDLE* Binding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingSetOption(RPC_BINDING_HANDLE hBinding, unsigned long option, ULONG_PTR optionValue)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
-RPC_STATUS RpcBindingInqOption(RPC_BINDING_HANDLE hBinding, unsigned long option, ULONG_PTR *pOptionValue)
+RPC_STATUS RpcBindingInqOption(RPC_BINDING_HANDLE hBinding, unsigned long option, ULONG_PTR* pOptionValue)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingFromStringBindingA(RPC_CSTR StringBinding, RPC_BINDING_HANDLE* Binding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE* Binding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcSsGetContextBinding(void* ContextHandle, RPC_BINDING_HANDLE* Binding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingInqObject(RPC_BINDING_HANDLE Binding, UUID* ObjectUuid)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingReset(RPC_BINDING_HANDLE Binding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingSetObject(RPC_BINDING_HANDLE Binding, UUID* ObjectUuid)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtInqDefaultProtectLevel(unsigned long AuthnSvc, unsigned long* AuthnLevel)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingToStringBindingA(RPC_BINDING_HANDLE Binding, RPC_CSTR* StringBinding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingToStringBindingW(RPC_BINDING_HANDLE Binding, RPC_WSTR* StringBinding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingVectorFree(RPC_BINDING_VECTOR** BindingVector)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcStringBindingComposeA(RPC_CSTR ObjUuid, RPC_CSTR Protseq, RPC_CSTR NetworkAddr,
- RPC_CSTR Endpoint, RPC_CSTR Options, RPC_CSTR* StringBinding)
+ RPC_CSTR Endpoint, RPC_CSTR Options, RPC_CSTR* StringBinding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcStringBindingComposeW(RPC_WSTR ObjUuid, RPC_WSTR Protseq, RPC_WSTR NetworkAddr,
- RPC_WSTR Endpoint, RPC_WSTR Options, RPC_WSTR* StringBinding)
+ RPC_WSTR Endpoint, RPC_WSTR Options, RPC_WSTR* StringBinding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcStringBindingParseA(RPC_CSTR StringBinding, RPC_CSTR* ObjUuid, RPC_CSTR* Protseq,
- RPC_CSTR* NetworkAddr, RPC_CSTR *Endpoint, RPC_CSTR* NetworkOptions)
+ RPC_CSTR* NetworkAddr, RPC_CSTR* Endpoint, RPC_CSTR* NetworkOptions)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcStringBindingParseW(RPC_WSTR StringBinding, RPC_WSTR* ObjUuid, RPC_WSTR* Protseq,
- RPC_WSTR* NetworkAddr, RPC_WSTR *Endpoint, RPC_WSTR* NetworkOptions)
+ RPC_WSTR* NetworkAddr, RPC_WSTR* Endpoint, RPC_WSTR* NetworkOptions)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcStringFreeA(RPC_CSTR* String)
{
+ WLog_ERR(TAG, "Not implemented");
free(String);
return RPC_S_OK;
}
RPC_STATUS RpcStringFreeW(RPC_WSTR* String)
{
+ WLog_ERR(TAG, "Not implemented");
free(String);
return RPC_S_OK;
}
RPC_STATUS RpcIfInqId(RPC_IF_HANDLE RpcIfHandle, RPC_IF_ID* RpcIfId)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcNetworkIsProtseqValidA(RPC_CSTR Protseq)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcNetworkIsProtseqValidW(RPC_WSTR Protseq)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtInqComTimeout(RPC_BINDING_HANDLE Binding, unsigned int* Timeout)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtSetComTimeout(RPC_BINDING_HANDLE Binding, unsigned int Timeout)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtSetCancelTimeout(long Timeout)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcNetworkInqProtseqsA(RPC_PROTSEQ_VECTORA** ProtseqVector)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcNetworkInqProtseqsW(RPC_PROTSEQ_VECTORW** ProtseqVector)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcObjectInqType(UUID* ObjUuid, UUID* TypeUuid)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcObjectSetInqFn(RPC_OBJECT_INQ_FN* InquiryFn)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcObjectSetType(UUID* ObjUuid, UUID* TypeUuid)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcProtseqVectorFreeA(RPC_PROTSEQ_VECTORA** ProtseqVector)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcProtseqVectorFreeW(RPC_PROTSEQ_VECTORW** ProtseqVector)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
-RPC_STATUS RpcServerInqBindings (RPC_BINDING_VECTOR** BindingVector)
+RPC_STATUS RpcServerInqBindings(RPC_BINDING_VECTOR** BindingVector)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerInqIf(RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV** MgrEpv)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerListen(unsigned int MinimumCallThreads, unsigned int MaxCalls, unsigned int DontWait)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerRegisterIf(RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerRegisterIfEx(RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
- unsigned int Flags, unsigned int MaxCalls, RPC_IF_CALLBACK_FN* IfCallback)
+ unsigned int Flags, unsigned int MaxCalls, RPC_IF_CALLBACK_FN* IfCallback)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerRegisterIf2(RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
- unsigned int Flags, unsigned int MaxCalls, unsigned int MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn)
+ unsigned int Flags, unsigned int MaxCalls, unsigned int MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUnregisterIf(RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, unsigned int WaitForCallsToComplete)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUnregisterIfEx(RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, int RundownContextHandles)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseAllProtseqs(unsigned int MaxCalls, void* SecurityDescriptor)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseAllProtseqsEx(unsigned int MaxCalls, void* SecurityDescriptor, PRPC_POLICY Policy)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseAllProtseqsIf(unsigned int MaxCalls, RPC_IF_HANDLE IfSpec, void* SecurityDescriptor)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseAllProtseqsIfEx(unsigned int MaxCalls, RPC_IF_HANDLE IfSpec, void* SecurityDescriptor, PRPC_POLICY Policy)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, void* SecurityDescriptor)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqExA(RPC_CSTR Protseq, unsigned int MaxCalls, void* SecurityDescriptor, PRPC_POLICY Policy)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls, void* SecurityDescriptor)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqExW(RPC_WSTR Protseq, unsigned int MaxCalls, void* SecurityDescriptor, PRPC_POLICY Policy)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqEpA(RPC_CSTR Protseq, unsigned int MaxCalls, RPC_CSTR Endpoint, void* SecurityDescriptor)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqEpExA(RPC_CSTR Protseq, unsigned int MaxCalls, RPC_CSTR Endpoint, void* SecurityDescriptor, PRPC_POLICY Policy)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqEpW(RPC_WSTR Protseq, unsigned int MaxCalls, RPC_WSTR Endpoint, void* SecurityDescriptor)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqEpExW(RPC_WSTR Protseq, unsigned int MaxCalls, RPC_WSTR Endpoint, void* SecurityDescriptor, PRPC_POLICY Policy)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqIfA(RPC_CSTR Protseq, unsigned int MaxCalls, RPC_IF_HANDLE IfSpec, void* SecurityDescriptor)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqIfExA(RPC_CSTR Protseq, unsigned int MaxCalls, RPC_IF_HANDLE IfSpec, void* SecurityDescriptor, PRPC_POLICY Policy)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqIfW(RPC_WSTR Protseq, unsigned int MaxCalls, RPC_IF_HANDLE IfSpec, void* SecurityDescriptor)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerUseProtseqIfExW(RPC_WSTR Protseq, unsigned int MaxCalls, RPC_IF_HANDLE IfSpec, void* SecurityDescriptor, PRPC_POLICY Policy)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
void RpcServerYield()
{
-
+ WLog_ERR(TAG, "Not implemented");
}
RPC_STATUS RpcMgmtStatsVectorFree(RPC_STATS_VECTOR** StatsVector)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtInqStats(RPC_BINDING_HANDLE Binding, RPC_STATS_VECTOR** Statistics)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtIsServerListening(RPC_BINDING_HANDLE Binding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtStopServerListening(RPC_BINDING_HANDLE Binding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtWaitServerListen(void)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtSetServerStackSize(unsigned long ThreadStackSize)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
void RpcSsDontSerializeContext(void)
{
-
+ WLog_ERR(TAG, "Not implemented");
}
RPC_STATUS RpcMgmtEnableIdleCleanup(void)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtInqIfIds(RPC_BINDING_HANDLE Binding, RPC_IF_ID_VECTOR** IfIdVector)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcIfIdVectorFree(RPC_IF_ID_VECTOR** IfIdVector)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtInqServerPrincNameA(RPC_BINDING_HANDLE Binding, unsigned long AuthnSvc, RPC_CSTR* ServerPrincName)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtInqServerPrincNameW(RPC_BINDING_HANDLE Binding, unsigned long AuthnSvc, RPC_WSTR* ServerPrincName)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerInqDefaultPrincNameA(unsigned long AuthnSvc, RPC_CSTR* PrincName)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerInqDefaultPrincNameW(unsigned long AuthnSvc, RPC_WSTR* PrincName)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcEpResolveBinding(RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcNsBindingInqEntryNameA(RPC_BINDING_HANDLE Binding, unsigned long EntryNameSyntax, RPC_CSTR* EntryName)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcNsBindingInqEntryNameW(RPC_BINDING_HANDLE Binding, unsigned long EntryNameSyntax, RPC_WSTR* EntryName)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcRevertToSelf()
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingInqAuthClientA(RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE* Privs,
- RPC_CSTR* ServerPrincName, unsigned long* AuthnLevel, unsigned long* AuthnSvc, unsigned long* AuthzSvc)
+ RPC_CSTR* ServerPrincName, unsigned long* AuthnLevel, unsigned long* AuthnSvc, unsigned long* AuthzSvc)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingInqAuthClientW(RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE* Privs,
- RPC_WSTR* ServerPrincName, unsigned long* AuthnLevel, unsigned long* AuthnSvc, unsigned long* AuthzSvc)
+ RPC_WSTR* ServerPrincName, unsigned long* AuthnLevel, unsigned long* AuthnSvc, unsigned long* AuthzSvc)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingInqAuthClientExA(RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE* Privs,
- RPC_CSTR* ServerPrincName, unsigned long* AuthnLevel, unsigned long* AuthnSvc, unsigned long* AuthzSvc, unsigned long Flags)
+ RPC_CSTR* ServerPrincName, unsigned long* AuthnLevel, unsigned long* AuthnSvc, unsigned long* AuthzSvc, unsigned long Flags)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingInqAuthClientExW(RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE* Privs,
- RPC_WSTR* ServerPrincName, unsigned long* AuthnLevel, unsigned long* AuthnSvc, unsigned long* AuthzSvc, unsigned long Flags)
+ RPC_WSTR* ServerPrincName, unsigned long* AuthnLevel, unsigned long* AuthnSvc, unsigned long* AuthzSvc, unsigned long Flags)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingInqAuthInfoA(RPC_BINDING_HANDLE Binding, RPC_CSTR* ServerPrincName, unsigned long* AuthnLevel,
- unsigned long* AuthnSvc, RPC_AUTH_IDENTITY_HANDLE* AuthIdentity, unsigned long* AuthzSvc)
+ unsigned long* AuthnSvc, RPC_AUTH_IDENTITY_HANDLE* AuthIdentity, unsigned long* AuthzSvc)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingInqAuthInfoW(RPC_BINDING_HANDLE Binding, RPC_WSTR* ServerPrincName, unsigned long* AuthnLevel,
- unsigned long* AuthnSvc, RPC_AUTH_IDENTITY_HANDLE* AuthIdentity, unsigned long* AuthzSvc)
+ unsigned long* AuthnSvc, RPC_AUTH_IDENTITY_HANDLE* AuthIdentity, unsigned long* AuthzSvc)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingSetAuthInfoA(RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, unsigned long AuthnLevel,
- unsigned long AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, unsigned long AuthzSvc)
+ unsigned long AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, unsigned long AuthzSvc)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingSetAuthInfoExA(RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, unsigned long AuthnLevel,
- unsigned long AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, unsigned long AuthzSvc, RPC_SECURITY_QOS* SecurityQos)
+ unsigned long AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, unsigned long AuthzSvc, RPC_SECURITY_QOS* SecurityQos)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingSetAuthInfoW(RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, unsigned long AuthnLevel,
- unsigned long AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, unsigned long AuthzSvc)
+ unsigned long AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, unsigned long AuthzSvc)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingSetAuthInfoExW(RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, unsigned long AuthnLevel,
- unsigned long AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, unsigned long AuthzSvc, RPC_SECURITY_QOS* SecurityQOS)
+ unsigned long AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, unsigned long AuthzSvc, RPC_SECURITY_QOS* SecurityQOS)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingInqAuthInfoExA(RPC_BINDING_HANDLE Binding, RPC_CSTR* ServerPrincName, unsigned long* AuthnLevel,
- unsigned long* AuthnSvc, RPC_AUTH_IDENTITY_HANDLE* AuthIdentity, unsigned long* AuthzSvc,
- unsigned long RpcQosVersion, RPC_SECURITY_QOS* SecurityQOS)
+ unsigned long* AuthnSvc, RPC_AUTH_IDENTITY_HANDLE* AuthIdentity, unsigned long* AuthzSvc,
+ unsigned long RpcQosVersion, RPC_SECURITY_QOS* SecurityQOS)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingInqAuthInfoExW(RPC_BINDING_HANDLE Binding, RPC_WSTR* ServerPrincName, unsigned long* AuthnLevel,
- unsigned long* AuthnSvc, RPC_AUTH_IDENTITY_HANDLE* AuthIdentity, unsigned long* AuthzSvc,
- unsigned long RpcQosVersion, RPC_SECURITY_QOS* SecurityQOS)
+ unsigned long* AuthnSvc, RPC_AUTH_IDENTITY_HANDLE* AuthIdentity, unsigned long* AuthzSvc,
+ unsigned long RpcQosVersion, RPC_SECURITY_QOS* SecurityQOS)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerRegisterAuthInfoA(RPC_CSTR ServerPrincName, unsigned long AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, void* Arg)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerRegisterAuthInfoW(RPC_WSTR ServerPrincName, unsigned long AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, void* Arg)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE* ServerBinding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
void RpcRaiseException(RPC_STATUS exception)
{
- fprintf(stderr, "RpcRaiseException: 0x%08luX\n", exception);
+ WLog_ERR(TAG, "RpcRaiseException: 0x%08luX", exception);
exit((int) exception);
}
RPC_STATUS RpcTestCancel()
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerTestCancel(RPC_BINDING_HANDLE BindingHandle)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcCancelThread(void* Thread)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcCancelThreadEx(void* Thread, long Timeout)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
* Format is 32 hex digits partitioned in 5 groups:
* xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
*/
-
sprintf_s((char*) *StringUuid, 36 + 1, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- Uuid->Data1, Uuid->Data2, Uuid->Data3,
- Uuid->Data4[0], Uuid->Data4[1],
- Uuid->Data4[2], Uuid->Data4[3], Uuid->Data4[4],
- Uuid->Data4[5], Uuid->Data4[6], Uuid->Data4[7]);
-
+ Uuid->Data1, Uuid->Data2, Uuid->Data3,
+ Uuid->Data4[0], Uuid->Data4[1],
+ Uuid->Data4[2], Uuid->Data4[3], Uuid->Data4[4],
+ Uuid->Data4[5], Uuid->Data4[6], Uuid->Data4[7]);
return RPC_S_OK;
}
RPC_STATUS UuidToStringW(UUID* Uuid, RPC_WSTR* StringUuid)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
}
Uuid->Data1 = ((bin[0] << 28) | (bin[1] << 24) | (bin[2] << 20) | (bin[3] << 16) |
- (bin[4] << 12) | (bin[5] << 8) | (bin[6] << 4) | bin[7]);
-
+ (bin[4] << 12) | (bin[5] << 8) | (bin[6] << 4) | bin[7]);
Uuid->Data2 = ((bin[9] << 12) | (bin[10] << 8) | (bin[11] << 4) | bin[12]);
Uuid->Data3 = ((bin[14] << 12) | (bin[15] << 8) | (bin[16] << 4) | bin[17]);
-
Uuid->Data4[0] = ((bin[19] << 4) | bin[20]);
Uuid->Data4[1] = ((bin[21] << 4) | bin[22]);
Uuid->Data4[2] = ((bin[24] << 4) | bin[25]);
Uuid->Data4[5] = ((bin[30] << 4) | bin[31]);
Uuid->Data4[6] = ((bin[32] << 4) | bin[33]);
Uuid->Data4[7] = ((bin[34] << 4) | bin[35]);
-
return RPC_S_OK;
}
RPC_STATUS UuidFromStringW(RPC_WSTR StringUuid, UUID* Uuid)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
signed int UuidCompare(UUID* Uuid1, UUID* Uuid2, RPC_STATUS* Status)
{
int index;
-
*Status = RPC_S_OK;
if (!Uuid1)
unsigned short UuidHash(UUID* Uuid, RPC_STATUS* Status)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcEpRegisterNoReplaceA(RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, UUID_VECTOR* UuidVector, RPC_CSTR Annotation)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcEpRegisterNoReplaceW(RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, UUID_VECTOR* UuidVector, RPC_WSTR Annotation)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcEpRegisterA(RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, UUID_VECTOR* UuidVector, RPC_CSTR Annotation)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcEpRegisterW(RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, UUID_VECTOR* UuidVector, RPC_WSTR Annotation)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcEpUnregister(RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, UUID_VECTOR* UuidVector)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS DceErrorInqTextA(RPC_STATUS RpcStatus, RPC_CSTR ErrorText)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS DceErrorInqTextW(RPC_STATUS RpcStatus, RPC_WSTR ErrorText)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtEpEltInqBegin(RPC_BINDING_HANDLE EpBinding, unsigned long InquiryType, RPC_IF_ID* IfId,
- unsigned long VersOption, UUID* ObjectUuid, RPC_EP_INQ_HANDLE* InquiryContext)
+ unsigned long VersOption, UUID* ObjectUuid, RPC_EP_INQ_HANDLE* InquiryContext)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtEpEltInqDone(RPC_EP_INQ_HANDLE* InquiryContext)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtEpEltInqNextA(RPC_EP_INQ_HANDLE InquiryContext, RPC_IF_ID* IfId,
- RPC_BINDING_HANDLE* Binding, UUID* ObjectUuid, RPC_CSTR* Annotation)
+ RPC_BINDING_HANDLE* Binding, UUID* ObjectUuid, RPC_CSTR* Annotation)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtEpEltInqNextW(RPC_EP_INQ_HANDLE InquiryContext, RPC_IF_ID* IfId,
- RPC_BINDING_HANDLE* Binding, UUID* ObjectUuid, RPC_WSTR* Annotation)
+ RPC_BINDING_HANDLE* Binding, UUID* ObjectUuid, RPC_WSTR* Annotation)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtEpUnregister(RPC_BINDING_HANDLE EpBinding, RPC_IF_ID* IfId,
- RPC_BINDING_HANDLE Binding, UUID* ObjectUuid)
+ RPC_BINDING_HANDLE Binding, UUID* ObjectUuid)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcMgmtSetAuthorizationFn(RPC_MGMT_AUTHORIZATION_FN AuthorizationFn)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
RPC_STATUS RpcServerInqBindingHandle(RPC_BINDING_HANDLE* Binding)
{
+ WLog_ERR(TAG, "Not implemented");
return 0;
}
#include "smartcard_pcsc.h"
+#include "../log.h"
+#define TAG WINPR_TAG("smartcard")
+
/**
* PC/SC transactions:
* http://developersblog.wwpass.com/?p=180
char SMARTCARD_PNP_NOTIFICATION_A[] = "\\\\?PnP?\\Notification";
WCHAR SMARTCARD_PNP_NOTIFICATION_W[] = { '\\','\\','?','P','n','P','?',
- '\\','N','o','t','i','f','i','c','a','t','i','o','n','\0' };
+ '\\','N','o','t','i','f','i','c','a','t','i','o','n','\0'
+ };
const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT0Pci = { SCARD_PROTOCOL_T0, sizeof(PCSC_SCARD_IO_REQUEST) };
const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(PCSC_SCARD_IO_REQUEST) };
* define SCARD_E_UNSUPPORTED_FEATURE to 0x8010001F,
* when the real value should be 0x80100022.
*/
-
if (errorCode == SCARD_E_UNEXPECTED)
errorCode = SCARD_E_UNSUPPORTED_FEATURE;
* pcsc-lite also never sets SCARD_SPECIFIC,
* which is expected by some windows applications.
*/
-
if (status == SCARD_S_SUCCESS)
{
if ((dwCardState & PCSC_SCARD_NEGOTIABLE) || (dwCardState & PCSC_SCARD_SPECIFIC))
if (dwCardState & PCSC_SCARD_POWERED)
return SCARD_POWERED;
+
if (dwCardState & PCSC_SCARD_NEGOTIABLE)
return SCARD_NEGOTIABLE;
+
if (dwCardState & PCSC_SCARD_SPECIFIC)
return SCARD_SPECIFIC;
+
if (dwCardState & PCSC_SCARD_ABSENT)
return SCARD_ABSENT;
+
if (dwCardState & PCSC_SCARD_PRESENT)
return SCARD_PRESENT;
+
if (dwCardState & PCSC_SCARD_SWALLOWED)
return SCARD_SWALLOWED;
+
if (dwCardState & PCSC_SCARD_UNKNOWN)
return SCARD_UNKNOWN;
* pcsc-lite uses a different value for SCARD_PROTOCOL_RAW,
* and also has SCARD_PROTOCOL_T15 which is not in WinSCard.
*/
-
if (dwProtocols & PCSC_SCARD_PROTOCOL_RAW)
{
dwProtocols &= ~PCSC_SCARD_PROTOCOL_RAW;
* pcsc-lite uses a different value for SCARD_PROTOCOL_RAW,
* and it does not define WinSCard's SCARD_PROTOCOL_DEFAULT.
*/
-
if (dwProtocols & SCARD_PROTOCOL_RAW)
{
dwProtocols &= ~SCARD_PROTOCOL_RAW;
PCSC_SCARDCONTEXT* PCSC_EstablishCardContext(SCARDCONTEXT hContext)
{
PCSC_SCARDCONTEXT* pContext;
-
pContext = (PCSC_SCARDCONTEXT*) calloc(1, sizeof(PCSC_SCARDCONTEXT));
if (!pContext)
return NULL;
pContext->hContext = hContext;
-
InitializeCriticalSectionAndSpinCount(&(pContext->lock), 4000);
if (!g_CardContexts)
}
ListDictionary_Add(g_CardContexts, (void*) hContext, (void*) pContext);
-
return pContext;
}
void PCSC_ReleaseCardContext(SCARDCONTEXT hContext)
{
PCSC_SCARDCONTEXT* pContext;
-
pContext = PCSC_GetCardContextData(hContext);
if (!pContext)
{
- printf("PCSC_ReleaseCardContext: null pContext!\n");
+ WLog_ERR(TAG, "PCSC_ReleaseCardContext: null pContext!");
return;
}
DeleteCriticalSection(&(pContext->lock));
-
free(pContext);
if (!g_CardContexts)
BOOL PCSC_LockCardContext(SCARDCONTEXT hContext)
{
PCSC_SCARDCONTEXT* pContext;
-
pContext = PCSC_GetCardContextData(hContext);
if (!pContext)
{
- fprintf(stderr, "PCSC_LockCardContext: invalid context (%p)\n", (void*) hContext);
+ WLog_ERR(TAG, "PCSC_LockCardContext: invalid context (%p)", (void*) hContext);
return FALSE;
}
EnterCriticalSection(&(pContext->lock));
-
return TRUE;
}
BOOL PCSC_UnlockCardContext(SCARDCONTEXT hContext)
{
PCSC_SCARDCONTEXT* pContext;
-
pContext = PCSC_GetCardContextData(hContext);
if (!pContext)
{
- fprintf(stderr, "PCSC_UnlockCardContext: invalid context (%p)\n", (void*) hContext);
+ WLog_ERR(TAG, "PCSC_UnlockCardContext: invalid context (%p)", (void*) hContext);
return FALSE;
}
LeaveCriticalSection(&(pContext->lock));
-
return TRUE;
}
SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard)
{
PCSC_SCARDHANDLE* pCard;
-
pCard = PCSC_GetCardHandleData(hCard);
if (!pCard)
{
PCSC_SCARDHANDLE* pCard;
PCSC_SCARDCONTEXT* pContext;
-
pContext = PCSC_GetCardContextData(hSharedContext);
if (!pContext)
{
- printf("PCSC_ConnectCardHandle: null pContext!\n");
+ WLog_ERR(TAG, "PCSC_ConnectCardHandle: null pContext!");
return NULL;
}
pCard->hSharedContext = hSharedContext;
pCard->hPrivateContext = hPrivateContext;
-
InitializeCriticalSectionAndSpinCount(&(pCard->lock), 4000);
-
pContext->dwCardHandleCount++;
if (!g_CardHandles)
g_CardHandles = ListDictionary_New(TRUE);
ListDictionary_Add(g_CardHandles, (void*) hCard, (void*) pCard);
-
return pCard;
}
{
PCSC_SCARDHANDLE* pCard;
PCSC_SCARDCONTEXT* pContext;
-
pCard = PCSC_GetCardHandleData(hCard);
if (!pCard)
return;
DeleteCriticalSection(&(pCard->lock));
-
pContext = PCSC_GetCardContextData(pCard->hSharedContext);
-
PCSC_SCardReleaseContext_Internal(pCard->hPrivateContext);
-
free(pCard);
if (!g_CardHandles)
if (!pContext)
{
- printf("PCSC_DisconnectCardHandle: null pContext!");
+ WLog_ERR(TAG, "PCSC_DisconnectCardHandle: null pContext!");
return;
}
BOOL PCSC_LockCardHandle(SCARDHANDLE hCard)
{
PCSC_SCARDHANDLE* pCard;
-
pCard = PCSC_GetCardHandleData(hCard);
if (!pCard)
{
- fprintf(stderr, "PCSC_LockCardHandle: invalid handle (%p)\n", (void*) hCard);
+ WLog_ERR(TAG, "PCSC_LockCardHandle: invalid handle (%p)", (void*) hCard);
return FALSE;
}
EnterCriticalSection(&(pCard->lock));
-
return TRUE;
}
BOOL PCSC_UnlockCardHandle(SCARDHANDLE hCard)
{
PCSC_SCARDHANDLE* pCard;
-
pCard = PCSC_GetCardHandleData(hCard);
if (!pCard)
{
- fprintf(stderr, "PCSC_UnlockCardHandle: invalid handle (%p)\n", (void*) hCard);
+ WLog_ERR(TAG, "PCSC_UnlockCardHandle: invalid handle (%p)", (void*) hCard);
return FALSE;
}
LeaveCriticalSection(&(pCard->lock));
-
return TRUE;
}
BOOL PCSC_LockCardTransaction(SCARDHANDLE hCard)
{
PCSC_SCARDHANDLE* pCard;
-
return TRUE; /* disable for now because it deadlocks */
-
pCard = PCSC_GetCardHandleData(hCard);
if (!pCard)
{
- fprintf(stderr, "PCSC_LockCardTransaction: invalid handle (%p)\n", (void*) hCard);
+ WLog_ERR(TAG, "PCSC_LockCardTransaction: invalid handle (%p)", (void*) hCard);
return FALSE;
}
EnterCriticalSection(&(pCard->lock));
-
return TRUE;
}
BOOL PCSC_UnlockCardTransaction(SCARDHANDLE hCard)
{
PCSC_SCARDHANDLE* pCard;
-
return TRUE; /* disable for now because it deadlocks */
-
pCard = PCSC_GetCardHandleData(hCard);
if (!pCard)
{
- fprintf(stderr, "PCSC_UnlockCardTransaction: invalid handle (%p)\n", (void*) hCard);
+ WLog_ERR(TAG, "PCSC_UnlockCardTransaction: invalid handle (%p)", (void*) hCard);
return FALSE;
}
LeaveCriticalSection(&(pCard->lock));
-
return TRUE;
}
int count;
PCSC_READER* reader;
char* namePCSC = NULL;
-
ArrayList_Lock(g_Readers);
-
count = ArrayList_Count(g_Readers);
for (index = 0; index < count; index++)
}
ArrayList_Unlock(g_Readers);
-
return namePCSC;
}
reader->namePCSC = _strdup(namePCSC);
reader->nameWinSCard = _strdup(nameWinSCard);
-
ArrayList_Add(g_Readers, reader);
-
return TRUE;
}
int length;
int ctoken;
int ntokens;
- char *p, *q;
+ char* p, *q;
char* tokens[64][2];
char* nameWinSCard;
-
/**
* pcsc-lite reader name format:
* name [interface] (serial) index slot
* the index is a two digit zero-padded integer
* the slot is a two digit zero-padded integer
*/
-
length = strlen(name);
if (length < 10)
slot = index = -1;
ctoken = ntokens - 1;
-
- slot = PCSC_AtoiWithLength(tokens[ctoken][0], (int) (tokens[ctoken][1] - tokens[ctoken][0]));
+ slot = PCSC_AtoiWithLength(tokens[ctoken][0], (int)(tokens[ctoken][1] - tokens[ctoken][0]));
ctoken--;
-
- index = PCSC_AtoiWithLength(tokens[ctoken][0], (int) (tokens[ctoken][1] - tokens[ctoken][0]));
+ index = PCSC_AtoiWithLength(tokens[ctoken][0], (int)(tokens[ctoken][1] - tokens[ctoken][0]));
ctoken--;
if (index < 0)
index = slot;
ctoken++;
}
-
+
if ((index < 0) || (slot < 0))
return NULL;
{
while ((*(tokens[ctoken][0]) != '(') && (ctoken > 0))
ctoken--;
+
ctoken--;
}
{
while ((*(tokens[ctoken][0]) != '[') && (ctoken > 0))
ctoken--;
+
ctoken--;
}
p = tokens[0][0];
q = tokens[ctoken][1];
-
length = (q - p);
size = length + 16;
-
nameWinSCard = (char*) malloc(size);
if (!nameWinSCard)
* while WinSCard uses an index number based on readers of the same name.
* Force an index number of 0 for now, fix later.
*/
-
index = 0;
-
sprintf_s(nameWinSCard, size, "%.*s %d", length, p, index);
-
- //printf("Smart Card Reader Name Alias: %s -> %s\n", p, nameWinSCard);
-
return nameWinSCard;
}
char* PCSC_GetReaderAliasFromName(char* namePCSC)
{
char* nameWinSCard;
-
nameWinSCard = PCSC_ConvertReaderNameToWinSCard(namePCSC);
if (nameWinSCard)
char* PCSC_ConvertReaderNamesToWinSCard(const char* names, LPDWORD pcchReaders)
{
int length;
- char *p, *q;
+ char* p, *q;
DWORD cchReaders;
char* nameWinSCard;
char* namesWinSCard;
-
p = (char*) names;
cchReaders = *pcchReaders;
-
namesWinSCard = (char*) malloc(cchReaders * 2);
if (!namesWinSCard)
q += length;
*q = '\0';
q++;
-
p += strlen(p) + 1;
}
*q = '\0';
q++;
-
- *pcchReaders = (DWORD) (q - namesWinSCard);
-
+ *pcchReaders = (DWORD)(q - namesWinSCard);
return namesWinSCard;
}
char* PCSC_ConvertReaderNamesToPCSC(const char* names, LPDWORD pcchReaders)
{
int length;
- char *p, *q;
+ char* p, *q;
char* namePCSC;
char* namesPCSC;
DWORD cchReaders;
-
p = (char*) names;
cchReaders = *pcchReaders;
-
namesPCSC = (char*) malloc(cchReaders * 2);
if (!namesPCSC)
length = strlen(namePCSC);
CopyMemory(q, namePCSC, length);
-
q += length;
*q = '\0';
q++;
-
p += strlen(p) + 1;
}
*q = '\0';
q++;
-
- *pcchReaders = (DWORD) (q - namesPCSC);
-
+ *pcchReaders = (DWORD)(q - namesPCSC);
return namesPCSC;
}
void* PCSC_SCardAllocMemory(SCARDCONTEXT hContext, size_t size)
{
void* pvMem;
-
pvMem = malloc(size);
if (!pvMem)
return NULL;
PCSC_AddMemoryBlock(hContext, pvMem);
-
return pvMem;
}
return SCARD_E_NO_SERVICE;
pcsc_dwScope = SCARD_SCOPE_SYSTEM; /* this is the only scope supported by pcsc-lite */
-
status = (LONG) g_PCSC.pfnSCardEstablishContext(pcsc_dwScope, pvReserved1, pvReserved2, phContext);
status = PCSC_MapErrorCodeToWinSCard(status);
-
return status;
}
LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
{
LONG status = SCARD_S_SUCCESS;
-
status = PCSC_SCardEstablishContext_Internal(dwScope, pvReserved1, pvReserved2, phContext);
if (status == SCARD_S_SUCCESS)
if (!hContext)
{
- fprintf(stderr, "SCardReleaseContext: null hContext\n");
+ WLog_ERR(TAG, "SCardReleaseContext: null hContext");
return status;
}
status = (LONG) g_PCSC.pfnSCardReleaseContext(hContext);
status = PCSC_MapErrorCodeToWinSCard(status);
-
return status;
}
WINSCARDAPI LONG WINAPI PCSC_SCardReleaseContext(SCARDCONTEXT hContext)
{
LONG status = SCARD_S_SUCCESS;
-
status = PCSC_SCardReleaseContext_Internal(hContext);
if (status != SCARD_S_SUCCESS)
status = (LONG) g_PCSC.pfnSCardIsValidContext(hContext);
status = PCSC_MapErrorCodeToWinSCard(status);
-
return status;
}
status = (LONG) g_PCSC.pfnSCardListReaderGroups(hContext, mszGroups, &pcsc_cchGroups);
status = PCSC_MapErrorCodeToWinSCard(status);
-
*pcchGroups = (DWORD) pcsc_cchGroups;
if (!PCSC_UnlockCardContext(hContext))
mszGroups = NULL;
pcchGroups = 0;
-
/* FIXME: unicode conversion */
-
status = (LONG) g_PCSC.pfnSCardListReaderGroups(hContext, (LPSTR) mszGroups, &pcsc_cchGroups);
status = PCSC_MapErrorCodeToWinSCard(status);
-
*pcchGroups = (DWORD) pcsc_cchGroups;
if (!PCSC_UnlockCardContext(hContext))
if (pcchReadersAlloc && !g_SCardAutoAllocate)
{
pcsc_cchReaders = 0;
-
status = (LONG) g_PCSC.pfnSCardListReaders(hContext, mszGroups, NULL, &pcsc_cchReaders);
if (status == SCARD_S_SUCCESS)
}
status = PCSC_MapErrorCodeToWinSCard(status);
-
*pcchReaders = (DWORD) pcsc_cchReaders;
if (status == SCARD_S_SUCCESS)
if (mszReadersWinSCard)
{
PCSC_SCardFreeMemory_Internal(hContext, *pMszReaders);
-
*pMszReaders = mszReadersWinSCard;
PCSC_AddMemoryBlock(hContext, *pMszReaders);
}
{
*pcchReaders = ConvertToUnicode(CP_UTF8, 0, *pMszReadersA, *pcchReaders, (WCHAR**) mszReaders, 0);
PCSC_AddMemoryBlock(hContext, mszReaders);
-
PCSC_SCardFreeMemory_Internal(hContext, *pMszReadersA);
}
{
LONG status = 0;
SCARDCONTEXT hContext = 0;
-
status = PCSC_SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
if (status != SCARD_S_SUCCESS)
}
g_StartedEventRefCount++;
-
return g_StartedEvent;
}
if (!g_PCSC.pfnSCardGetStatusChange)
return SCARD_E_NO_SERVICE;
-
+
if (!cReaders)
return SCARD_S_SUCCESS;
* To work around this apparent lack of "\\\\?PnP?\\Notification" support,
* we have to filter rgReaderStates to exclude the special PnP reader name.
*/
-
map = (int*) calloc(pcsc_cReaders, sizeof(int));
-
+
if (!map)
return SCARD_E_NO_MEMORY;
-
+
states = (PCSC_SCARD_READERSTATE*) calloc(pcsc_cReaders, sizeof(PCSC_SCARD_READERSTATE));
if (!states)
return SCARD_E_NO_MEMORY;
-
+
for (i = j = 0; i < pcsc_cReaders; i++)
{
if (!g_PnP_Notification)
continue;
}
}
-
+
map[i] = j;
-
states[j].szReader = PCSC_GetReaderNameFromAlias((char*) rgReaderStates[i].szReader);
if (!states[j].szReader)
states[j].dwEventState = rgReaderStates[i].dwEventState;
states[j].cbAtr = rgReaderStates[i].cbAtr;
CopyMemory(&(states[j].rgbAtr), &(rgReaderStates[i].rgbAtr), PCSC_MAX_ATR_SIZE);
-
j++;
}
-
+
cMappedReaders = j;
/**
if (cMappedReaders > 0)
{
status = (LONG) g_PCSC.pfnSCardGetStatusChange(hContext,
- pcsc_dwTimeout ? pcsc_dwTimeout : 1,
- states, cMappedReaders);
-
+ pcsc_dwTimeout ? pcsc_dwTimeout : 1,
+ states, cMappedReaders);
status = PCSC_MapErrorCodeToWinSCard(status);
}
else
{
if (map[i] < 0)
continue; /* unmapped */
-
+
j = map[i];
-
rgReaderStates[i].dwCurrentState = states[j].dwCurrentState;
rgReaderStates[i].cbAtr = states[j].cbAtr;
CopyMemory(&(rgReaderStates[i].rgbAtr), &(states[j].rgbAtr), PCSC_MAX_ATR_SIZE);
-
/* pcsc-lite puts an event count in the higher bits of dwEventState */
states[j].dwEventState &= 0xFFFF;
-
dwEventState = states[j].dwEventState & ~SCARD_STATE_CHANGED;
if (dwEventState != rgReaderStates[i].dwCurrentState)
free(states);
free(map);
-
return status;
}
{
states[index].szReader = NULL;
ConvertFromUnicode(CP_UTF8, 0, rgReaderStates[index].szReader, -1,
- (char**) &(states[index].szReader), 0, NULL, NULL);
-
+ (char**) &(states[index].szReader), 0, NULL, NULL);
states[index].pvUserData = rgReaderStates[index].pvUserData;
states[index].dwCurrentState = rgReaderStates[index].dwCurrentState;
states[index].dwEventState = rgReaderStates[index].dwEventState;
status = (LONG) g_PCSC.pfnSCardCancel(hContext);
status = PCSC_MapErrorCodeToWinSCard(status);
-
return status;
}
szReaderPCSC = (char*) szReader;
pcsc_dwPreferredProtocols = (PCSC_DWORD) PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols);
-
status = (LONG) g_PCSC.pfnSCardConnect(hPrivateContext, szReaderPCSC,
- pcsc_dwShareMode, pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol);
+ pcsc_dwShareMode, pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol);
status = PCSC_MapErrorCodeToWinSCard(status);
if (status == SCARD_S_SUCCESS)
return SCARD_E_INVALID_HANDLE;
status = PCSC_SCardConnect_Internal(hContext, szReader, dwShareMode,
- dwPreferredProtocols, phCard, pdwActiveProtocol);
+ dwPreferredProtocols, phCard, pdwActiveProtocol);
if (!PCSC_UnlockCardContext(hContext))
return SCARD_E_INVALID_HANDLE;
ConvertFromUnicode(CP_UTF8, 0, szReader, -1, &szReaderA, 0, NULL, NULL);
status = PCSC_SCardConnect_Internal(hContext, szReaderA, dwShareMode,
- dwPreferredProtocols, phCard, pdwActiveProtocol);
-
+ dwPreferredProtocols, phCard, pdwActiveProtocol);
free(szReaderA);
if (!PCSC_UnlockCardContext(hContext))
return SCARD_E_NO_SERVICE;
pcsc_dwPreferredProtocols = (PCSC_DWORD) PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols);
-
status = (LONG) g_PCSC.pfnSCardReconnect(hCard, pcsc_dwShareMode,
- pcsc_dwPreferredProtocols, pcsc_dwInitialization, &pcsc_dwActiveProtocol);
+ pcsc_dwPreferredProtocols, pcsc_dwInitialization, &pcsc_dwActiveProtocol);
status = PCSC_MapErrorCodeToWinSCard(status);
-
*pdwActiveProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwActiveProtocol);
-
return status;
}
}
pContext->isTransactionLocked = TRUE;
-
return status;
}
}
pContext->isTransactionLocked = FALSE;
-
return status;
}
}
WINSCARDAPI LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard,
- LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
+ LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
{
PCSC_DWORD cchReaderLen;
SCARDCONTEXT hContext = 0;
return SCARD_E_INVALID_VALUE;
cchReaderLen = SCARD_AUTOALLOCATE;
-
status = (LONG) g_PCSC.pfnSCardStatus(hCard, (LPSTR) &mszReaderNames, &cchReaderLen,
- &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen);
+ &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen);
status = PCSC_MapErrorCodeToWinSCard(status);
if (mszReaderNames)
*pdwState = (DWORD) pcsc_dwState;
*pdwProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwProtocol);
*pcbAtrLen = (DWORD) pcsc_cbAtrLen;
-
return status;
}
pcsc_cbAtrLen = 0;
status = (LONG) g_PCSC.pfnSCardStatus(hCard,
- (pcchReaderLenAlloc) ? NULL : mszReaderNames, &pcsc_cchReaderLen,
- &pcsc_dwState, &pcsc_dwProtocol,
- (pcbAtrLenAlloc) ? NULL : pbAtr, &pcsc_cbAtrLen);
+ (pcchReaderLenAlloc) ? NULL : mszReaderNames, &pcsc_cchReaderLen,
+ &pcsc_dwState, &pcsc_dwProtocol,
+ (pcbAtrLenAlloc) ? NULL : pbAtr, &pcsc_cbAtrLen);
if (status == SCARD_S_SUCCESS)
{
}
status = (LONG) g_PCSC.pfnSCardStatus(hCard,
- *pMszReaderNames, &pcsc_cchReaderLen,
- &pcsc_dwState, &pcsc_dwProtocol,
- pbAtr, &pcsc_cbAtrLen);
+ *pMszReaderNames, &pcsc_cchReaderLen,
+ &pcsc_dwState, &pcsc_dwProtocol,
+ pbAtr, &pcsc_cbAtrLen);
if (status != SCARD_S_SUCCESS)
{
else
{
status = (LONG) g_PCSC.pfnSCardStatus(hCard, mszReaderNames, &pcsc_cchReaderLen,
- &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen);
+ &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen);
}
status = PCSC_MapErrorCodeToWinSCard(status);
-
*pcchReaderLen = (DWORD) pcsc_cchReaderLen;
-
mszReaderNamesWinSCard = PCSC_ConvertReaderNamesToWinSCard(*pMszReaderNames, pcchReaderLen);
if (mszReaderNamesWinSCard)
{
PCSC_SCardFreeMemory_Internal(hContext, *pMszReaderNames);
-
*pMszReaderNames = mszReaderNamesWinSCard;
PCSC_AddMemoryBlock(hContext, *pMszReaderNames);
}
pcsc_dwState &= 0xFFFF;
*pdwState = PCSC_ConvertCardStateToWinSCard((DWORD) pcsc_dwState, status);
-
*pdwProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwProtocol);
-
*pcbAtrLen = (DWORD) pcsc_cbAtrLen;
-
return status;
}
LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
{
LONG status = SCARD_S_SUCCESS;
-
status = PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen);
-
return status;
}
{
*pcchReaderLen = ConvertToUnicode(CP_UTF8, 0, mszReaderNamesA, *pcchReaderLen, (WCHAR**) mszReaderNames, 0);
PCSC_AddMemoryBlock(hContext, mszReaderNames);
-
PCSC_SCardFreeMemory_Internal(hContext, mszReaderNamesA);
}
PCSC_DWORD cbAtrLen = 0;
PCSC_DWORD dwProtocol = 0;
PCSC_DWORD cchReaderLen = 0;
-
/**
* pcsc-lite cannot have a null pioSendPci parameter, unlike WinSCard.
* Query the current protocol and use default SCARD_IO_REQUEST for it.
*/
-
status = (LONG) g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState, &dwProtocol, NULL, &cbAtrLen);
if (status == SCARD_S_SUCCESS)
pcsc_pioSendPci->dwProtocol = (PCSC_DWORD) pioSendPci->dwProtocol;
pcsc_pioSendPci->cbPciLength = sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes;
-
pbExtraBytes = &((BYTE*) pioSendPci)[sizeof(SCARD_IO_REQUEST)];
pcsc_pbExtraBytes = &((BYTE*) pcsc_pioSendPci)[sizeof(PCSC_SCARD_IO_REQUEST)];
-
CopyMemory(pcsc_pbExtraBytes, pbExtraBytes, cbExtraBytes);
}
pcsc_pioRecvPci->dwProtocol = (PCSC_DWORD) pioRecvPci->dwProtocol;
pcsc_pioRecvPci->cbPciLength = sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes;
-
pbExtraBytes = &((BYTE*) pioRecvPci)[sizeof(SCARD_IO_REQUEST)];
pcsc_pbExtraBytes = &((BYTE*) pcsc_pioRecvPci)[sizeof(PCSC_SCARD_IO_REQUEST)];
-
CopyMemory(pcsc_pbExtraBytes, pbExtraBytes, cbExtraBytes);
}
status = (LONG) g_PCSC.pfnSCardTransmit(hCard, pcsc_pioSendPci, pbSendBuffer,
- pcsc_cbSendLength, pcsc_pioRecvPci, pbRecvBuffer, &pcsc_cbRecvLength);
+ pcsc_cbSendLength, pcsc_pioRecvPci, pbRecvBuffer, &pcsc_cbRecvLength);
status = PCSC_MapErrorCodeToWinSCard(status);
-
*pcbRecvLength = (DWORD) pcsc_cbRecvLength;
if (pioSendPci)
dwControlCode = PCSC_SCARD_CTL_CODE(IoCtlFunction);
pcsc_dwControlCode = (PCSC_DWORD) dwControlCode;
-
status = (LONG) g_PCSC.pfnSCardControl(hCard,
- pcsc_dwControlCode, lpInBuffer, pcsc_cbInBufferSize,
- lpOutBuffer, pcsc_cbOutBufferSize, &pcsc_BytesReturned);
+ pcsc_dwControlCode, lpInBuffer, pcsc_cbInBufferSize,
+ lpOutBuffer, pcsc_cbOutBufferSize, &pcsc_BytesReturned);
status = PCSC_MapErrorCodeToWinSCard(status);
-
*lpBytesReturned = (DWORD) pcsc_BytesReturned;
if (getFeatureRequest)
PCSC_TLV_STRUCTURE* tlv = (PCSC_TLV_STRUCTURE*) lpOutBuffer;
void* lpOutBufferEnd = (void*) &((BYTE*) lpOutBuffer)[*lpBytesReturned];
- for ( ; ((void*) tlv) < lpOutBufferEnd; tlv++)
+ for (; ((void*) tlv) < lpOutBufferEnd; tlv++)
{
ioCtlValue = _byteswap_ulong(tlv->value);
ioCtlValue -= 0x42000000; /* inverse of PCSC_SCARD_CTL_CODE() */
-
IoCtlMethod = METHOD_FROM_CTL_CODE(ioCtlValue);
IoCtlFunction = FUNCTION_FROM_CTL_CODE(ioCtlValue);
IoCtlAccess = ACCESS_FROM_CTL_CODE(ioCtlValue);
IoCtlDeviceType = DEVICE_TYPE_FROM_CTL_CODE(ioCtlValue);
ioCtlValue = SCARD_CTL_CODE(IoCtlFunction);
-
tlv->value = _byteswap_ulong(ioCtlValue);
}
}
if (pcbAttrLenAlloc && !g_SCardAutoAllocate)
{
pcsc_cbAttrLen = 0;
-
status = (LONG) g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, NULL, &pcsc_cbAttrLen);
if (status == SCARD_S_SUCCESS)
}
status = PCSC_MapErrorCodeToWinSCard(status);
-
*pcbAttrLen = (DWORD) pcsc_cbAttrLen;
-
return status;
}
WCHAR* friendlyNameW = NULL;
LONG status = SCARD_S_SUCCESS;
LPBYTE* pPbAttr = (LPBYTE*) pbAttr;
-
hContext = PCSC_GetCardContextFromHandle(hCard);
if (!hContext)
cbAttrLen = *pcbAttrLen;
*pcbAttrLen = SCARD_AUTOALLOCATE;
-
status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A,
- (LPBYTE) &pbAttrA, pcbAttrLen);
+ (LPBYTE) &pbAttrA, pcbAttrLen);
if (status != SCARD_S_SUCCESS)
{
pbAttrA = NULL;
*pcbAttrLen = SCARD_AUTOALLOCATE;
-
status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W,
- (LPBYTE) &pbAttrW, pcbAttrLen);
+ (LPBYTE) &pbAttrW, pcbAttrLen);
if (status != SCARD_S_SUCCESS)
return status;
length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW,
- *pcbAttrLen, (char**) &pbAttrA, 0, NULL, NULL);
-
+ *pcbAttrLen, (char**) &pbAttrA, 0, NULL, NULL);
namePCSC = pbAttrA;
PCSC_SCardFreeMemory_Internal(hContext, pbAttrW);
}
if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W)
{
length = ConvertToUnicode(CP_UTF8, 0, (char*) friendlyNameA, -1, &friendlyNameW, 0);
-
free(friendlyNameA);
if (!friendlyNameW)
BOOL pcbAttrLenAlloc = FALSE;
LONG status = SCARD_S_SUCCESS;
LPBYTE* pPbAttr = (LPBYTE*) pbAttr;
-
cbAttrLen = *pcbAttrLen;
if (*pcbAttrLen == SCARD_AUTOALLOCATE)
* pcsc-lite adds a null terminator to the vendor name,
* while WinSCard doesn't. Strip the null terminator.
*/
-
if (pcbAttrLenAlloc)
*pcbAttrLen = strlen((char*) *pPbAttr);
else
PCSC_DWORD cbAtrLen = 0;
PCSC_DWORD dwProtocol = 0;
PCSC_DWORD cchReaderLen = 0;
-
status = (LONG) g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState, &dwProtocol, NULL, &cbAtrLen);
if (status == SCARD_S_SUCCESS)
}
else if (dwAttrId == SCARD_ATTR_VENDOR_IFD_TYPE)
{
-
}
else if (dwAttrId == SCARD_ATTR_CHANNEL_ID)
{
-
}
else if (dwAttrId == SCARD_ATTR_DEFAULT_CLK)
{
-
}
else if (dwAttrId == SCARD_ATTR_DEFAULT_DATA_RATE)
{
-
}
else if (dwAttrId == SCARD_ATTR_MAX_CLK)
{
-
}
else if (dwAttrId == SCARD_ATTR_MAX_DATA_RATE)
{
-
}
else if (dwAttrId == SCARD_ATTR_MAX_IFSD)
{
-
}
else if (dwAttrId == SCARD_ATTR_CHARACTERISTICS)
{
-
}
else if (dwAttrId == SCARD_ATTR_DEVICE_SYSTEM_NAME_A)
{
-
}
else if (dwAttrId == SCARD_ATTR_DEVICE_UNIT)
{
-
}
else if (dwAttrId == SCARD_ATTR_POWER_MGMT_SUPPORT)
{
-
}
else if (dwAttrId == SCARD_ATTR_CURRENT_CLK)
{
-
}
else if (dwAttrId == SCARD_ATTR_CURRENT_F)
{
-
}
else if (dwAttrId == SCARD_ATTR_CURRENT_D)
{
-
}
else if (dwAttrId == SCARD_ATTR_CURRENT_N)
{
-
}
else if (dwAttrId == SCARD_ATTR_CURRENT_CWT)
{
-
}
else if (dwAttrId == SCARD_ATTR_CURRENT_BWT)
{
-
}
else if (dwAttrId == SCARD_ATTR_CURRENT_IFSC)
{
-
}
else if (dwAttrId == SCARD_ATTR_CURRENT_EBC_ENCODING)
{
-
}
else if (dwAttrId == SCARD_ATTR_CURRENT_IFSD)
{
-
}
else if (dwAttrId == SCARD_ATTR_ICC_TYPE_PER_ATR)
{
-
}
}
status = (LONG) g_PCSC.pfnSCardSetAttrib(hCard, pcsc_dwAttrId, pbAttr, pcsc_cbAttrLen);
status = PCSC_MapErrorCodeToWinSCard(status);
-
return status;
}
{
/* Disable pcsc-lite's (poor) blocking so we can handle it ourselves */
SetEnvironmentVariableA("PCSCLITE_NO_BLOCKING", "1");
-
#ifndef DISABLE_PCSC_LINK
+
if (PCSC_InitializeSCardApi_Link() >= 0)
{
g_PCSC.pfnSCardEstablishContext = g_PCSC_Link.pfnSCardEstablishContext;
g_PCSC.pfnSCardCancel = g_PCSC_Link.pfnSCardCancel;
g_PCSC.pfnSCardGetAttrib = g_PCSC_Link.pfnSCardGetAttrib;
g_PCSC.pfnSCardSetAttrib = g_PCSC_Link.pfnSCardSetAttrib;
-
return 1;
}
+
#endif
-
#ifdef __MACOSX__
g_PCSCModule = LoadLibraryA("/System/Library/Frameworks/PCSC.framework/PCSC");
#else
if (!g_PCSCModule)
g_PCSCModule = LoadLibraryA("libpcsclite.so");
+
#endif
if (!g_PCSCModule)
g_PCSC.pfnSCardCancel = (void*) GetProcAddress(g_PCSCModule, "SCardCancel");
g_PCSC.pfnSCardGetAttrib = (void*) GetProcAddress(g_PCSCModule, "SCardGetAttrib");
g_PCSC.pfnSCardSetAttrib = (void*) GetProcAddress(g_PCSCModule, "SCardSetAttrib");
-
g_PCSC.pfnSCardFreeMemory = NULL;
-
#ifndef __APPLE__
g_PCSC.pfnSCardFreeMemory = (void*) GetProcAddress(g_PCSCModule, "SCardFreeMemory");
#endif
-
+
if (g_PCSC.pfnSCardFreeMemory)
g_SCardAutoAllocate = TRUE;
g_PCSC.pfnSCardFreeMemory = NULL;
g_SCardAutoAllocate = FALSE;
#endif
-
#ifdef __APPLE__
g_PnP_Notification = FALSE;
#endif
-
return 1;
}
#include "ntlm_message.h"
+#include "../../log.h"
+#define TAG WINPR_TAG("sspi.NTLM")
+
char* NTLM_PACKAGE_NAME = "NTLM";
int ntlm_SetContextWorkstation(NTLM_CONTEXT* context, char* Workstation)
if (!Workstation)
{
GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize);
-
ws = (char*) malloc(nSize);
if (!ws)
if (status <= 0)
return -1;
- context->Workstation.Length = (USHORT) (status - 1);
+ context->Workstation.Length = (USHORT)(status - 1);
context->Workstation.Length *= 2;
if (!Workstation)
return -1;
CopyMemory(context->ServicePrincipalName.Buffer, ServicePrincipalName, context->ServicePrincipalName.Length + 2);
-
return 1;
}
int ntlm_SetContextServicePrincipalNameA(NTLM_CONTEXT* context, char* ServicePrincipalName)
{
int status;
-
context->ServicePrincipalName.Buffer = NULL;
-
status = ConvertToUnicode(CP_UTF8, 0, ServicePrincipalName, -1, &context->ServicePrincipalName.Buffer, 0);
if (status <= 0)
return -1;
- context->ServicePrincipalName.Length = (USHORT) ((status - 1) * 2);
-
+ context->ServicePrincipalName.Length = (USHORT)((status - 1) * 2);
return 1;
}
if (status <= 0)
return -1;
- context->TargetName.cbBuffer = (USHORT) ((status - 1) * 2);
+ context->TargetName.cbBuffer = (USHORT)((status - 1) * 2);
if (!TargetName)
free(name);
DWORD dwSize;
DWORD dwValue;
NTLM_CONTEXT* context;
-
context = (NTLM_CONTEXT*) calloc(1, sizeof(NTLM_CONTEXT));
if (!context)
context->SendWorkstationName = TRUE;
context->NegotiateKeyExchange = TRUE;
context->UseSamFileDatabase = TRUE;
-
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\WinPR\\NTLM"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
if (status == ERROR_SUCCESS)
* but enabling it in WinPR breaks TS Gateway at this point
*/
context->SuppressExtendedProtection = FALSE;
-
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\LSA"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
if (status == ERROR_SUCCESS)
sspi_SecBufferFree(&context->TargetName);
sspi_SecBufferFree(&context->NtChallengeResponse);
sspi_SecBufferFree(&context->LmChallengeResponse);
-
free(context->ServicePrincipalName.Buffer);
free(context->Workstation.Buffer);
free(context);
SEC_WINNT_AUTH_IDENTITY* identity;
if ((fCredentialUse != SECPKG_CRED_OUTBOUND) &&
- (fCredentialUse != SECPKG_CRED_INBOUND) &&
- (fCredentialUse != SECPKG_CRED_BOTH))
+ (fCredentialUse != SECPKG_CRED_INBOUND) &&
+ (fCredentialUse != SECPKG_CRED_BOTH))
{
return SEC_E_INVALID_PARAMETER;
}
credentials->fCredentialUse = fCredentialUse;
credentials->pGetKeyFn = pGetKeyFn;
credentials->pvGetKeyArgument = pvGetKeyArgument;
-
identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData;
if (identity)
sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials);
sspi_SecureHandleSetUpperPointer(phCredential, (void*) NTLM_PACKAGE_NAME);
-
return SEC_E_OK;
}
SEC_WINNT_AUTH_IDENTITY* identity;
if ((fCredentialUse != SECPKG_CRED_OUTBOUND) &&
- (fCredentialUse != SECPKG_CRED_INBOUND) &&
- (fCredentialUse != SECPKG_CRED_BOTH))
+ (fCredentialUse != SECPKG_CRED_INBOUND) &&
+ (fCredentialUse != SECPKG_CRED_BOTH))
{
return SEC_E_INVALID_PARAMETER;
}
credentials->fCredentialUse = fCredentialUse;
credentials->pGetKeyFn = pGetKeyFn;
credentials->pvGetKeyArgument = pvGetKeyArgument;
-
identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData;
if (identity)
sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials);
sspi_SecureHandleSetUpperPointer(phCredential, (void*) NTLM_PACKAGE_NAME);
-
return SEC_E_OK;
}
return SEC_E_INVALID_HANDLE;
sspi_CredentialsFree(credentials);
-
return SEC_E_OK;
}
SSPI_CREDENTIALS* credentials;
PSecBuffer input_buffer;
PSecBuffer output_buffer;
-
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
context->credentials = credentials;
-
ntlm_SetContextTargetName(context, NULL);
-
sspi_SecureHandleSetLowerPointer(phNewContext, context);
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NTLM_PACKAGE_NAME);
}
PSecBuffer input_buffer = NULL;
PSecBuffer output_buffer = NULL;
PSecBuffer channel_bindings = NULL;
-
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
}
status = ntlm_InitializeSecurityContextW(phCredential, phContext, pszTargetNameW, fContextReq,
- Reserved1, TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
+ Reserved1, TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
if (pszTargetNameW)
free(pszTargetNameW);
-
+
return status;
}
{
NTLM_CONTEXT* context;
SECURITY_STATUS status = SEC_E_OK;
-
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext)
{
NTLM_CONTEXT* context;
-
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
return SEC_E_INVALID_HANDLE;
ntlm_ContextFree(context);
-
return SEC_E_OK;
}
if (ulAttribute == SECPKG_ATTR_SIZES)
{
SecPkgContext_Sizes* ContextSizes = (SecPkgContext_Sizes*) pBuffer;
-
ContextSizes->cbMaxToken = 2010;
ContextSizes->cbMaxSignature = 16;
ContextSizes->cbBlockSize = 0;
ContextSizes->cbSecurityTrailer = 16;
-
return SEC_E_OK;
}
else if (ulAttribute == SECPKG_ATTR_AUTH_IDENTITY)
char* DomainA = NULL;
SSPI_CREDENTIALS* credentials;
SecPkgContext_AuthIdentity* AuthIdentity = (SecPkgContext_AuthIdentity*) pBuffer;
-
context->UseSamFileDatabase = FALSE;
-
credentials = context->credentials;
ZeroMemory(AuthIdentity, sizeof(SecPkgContext_AuthIdentity));
-
UserA = AuthIdentity->User;
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) credentials->identity.User,
- credentials->identity.UserLength,
- &UserA, 256, NULL, NULL);
+ credentials->identity.UserLength,
+ &UserA, 256, NULL, NULL);
if (status <= 0)
return SEC_E_INTERNAL_ERROR;
DomainA = AuthIdentity->Domain;
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) credentials->identity.Domain,
- credentials->identity.DomainLength,
- &DomainA, 256, NULL, NULL);
+ credentials->identity.DomainLength,
+ &DomainA, 256, NULL, NULL);
if (status <= 0)
return SEC_E_INTERNAL_ERROR;
return SEC_E_INVALID_PARAMETER;
CopyMemory(context->ClientChallenge, AuthNtlmClientChallenge->ClientChallenge, 8);
-
return SEC_E_OK;
}
else if (ulAttribute == SECPKG_ATTR_AUTH_NTLM_SERVER_CHALLENGE)
return SEC_E_INVALID_PARAMETER;
CopyMemory(context->ServerChallenge, AuthNtlmServerChallenge->ServerChallenge, 8);
-
return SEC_E_OK;
}
NTLM_CONTEXT* context;
PSecBuffer data_buffer = NULL;
PSecBuffer signature_buffer = NULL;
-
SeqNo = MessageSeqNo;
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
return SEC_E_INSUFFICIENT_MEMORY;
CopyMemory(data, data_buffer->pvBuffer, length);
-
/* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */
HMAC_CTX_init(&hmac);
HMAC_Init_ex(&hmac, context->SendSigningKey, 16, EVP_md5(), NULL);
CopyMemory(data_buffer->pvBuffer, data, length);
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "Data Buffer (length = %d)\n", length);
- winpr_HexDump(data, length);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Encrypted Data Buffer (length = %d)\n", (int) data_buffer->cbBuffer);
- winpr_HexDump(data_buffer->pvBuffer, data_buffer->cbBuffer);
- fprintf(stderr, "\n");
+ WLog_DBG(TAG, "Data Buffer (length = %d)", length);
+ winpr_HexDump(TAG, WLOG_DEBUG, data, length);
+ WLog_DBG(TAG, "Encrypted Data Buffer (length = %d)", (int) data_buffer->cbBuffer);
+ winpr_HexDump(TAG, WLOG_DEBUG, data_buffer->pvBuffer, data_buffer->cbBuffer);
#endif
-
free(data);
-
/* RC4-encrypt first 8 bytes of digest */
RC4(&context->SendRc4Seal, 8, digest, checksum);
-
signature = (BYTE*) signature_buffer->pvBuffer;
-
/* Concatenate version, ciphertext and sequence number to build signature */
CopyMemory(signature, (void*) &version, 4);
CopyMemory(&signature[4], (void*) checksum, 8);
CopyMemory(&signature[12], (void*) &(SeqNo), 4);
context->SendSeqNum++;
-
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "Signature (length = %d)\n", (int) signature_buffer->cbBuffer);
- winpr_HexDump(signature_buffer->pvBuffer, signature_buffer->cbBuffer);
- fprintf(stderr, "\n");
+ WLog_DBG(TAG, "Signature (length = %d)", (int) signature_buffer->cbBuffer);
+ winpr_HexDump(TAG, WLOG_DEBUG, signature_buffer->pvBuffer, signature_buffer->cbBuffer);
#endif
-
return SEC_E_OK;
}
BYTE expected_signature[16];
PSecBuffer data_buffer = NULL;
PSecBuffer signature_buffer = NULL;
-
SeqNo = (UINT32) MessageSeqNo;
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
HMAC_Update(&hmac, (void*) data_buffer->pvBuffer, data_buffer->cbBuffer);
HMAC_Final(&hmac, digest, NULL);
HMAC_CTX_cleanup(&hmac);
-
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "Encrypted Data Buffer (length = %d)\n", length);
- winpr_HexDump(data, length);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Data Buffer (length = %d)\n", (int) data_buffer->cbBuffer);
- winpr_HexDump(data_buffer->pvBuffer, data_buffer->cbBuffer);
- fprintf(stderr, "\n");
+ WLog_DBG(TAG, "Encrypted Data Buffer (length = %d)", length);
+ winpr_HexDump(TAG, WLOG_DEBUG, data, length);
+ WLog_DBG(TAG, "Data Buffer (length = %d)", (int) data_buffer->cbBuffer);
+ winpr_HexDump(TAG, WLOG_DEBUG, data_buffer->pvBuffer, data_buffer->cbBuffer);
#endif
-
free(data);
-
/* RC4-encrypt first 8 bytes of digest */
RC4(&context->RecvRc4Seal, 8, digest, checksum);
-
/* Concatenate version, ciphertext and sequence number to build signature */
CopyMemory(expected_signature, (void*) &version, 4);
CopyMemory(&expected_signature[4], (void*) checksum, 8);
if (memcmp(signature_buffer->pvBuffer, expected_signature, 16) != 0)
{
/* signature verification failed! */
- fprintf(stderr, "signature verification failed, something nasty is going on!\n");
-
- fprintf(stderr, "Expected Signature:\n");
- winpr_HexDump(expected_signature, 16);
- fprintf(stderr, "Actual Signature:\n");
- winpr_HexDump((BYTE*) signature_buffer->pvBuffer, 16);
-
+ WLog_ERR(TAG, "signature verification failed, something nasty is going on!");
+ WLog_ERR(TAG, "Expected Signature:");
+ winpr_HexDump(TAG, WLOG_ERROR, expected_signature, 16);
+ WLog_ERR(TAG, "Actual Signature:");
+ winpr_HexDump(TAG, WLOG_ERROR, (BYTE*) signature_buffer->pvBuffer, 16);
return SEC_E_MESSAGE_ALTERED;
}
#include "ntlm_av_pairs.h"
+#include "../../log.h"
+#define TAG WINPR_TAG("sspi.NTLM")
+
const char* const AV_PAIR_STRINGS[] =
{
"MsvAvEOL",
void ntlm_av_pair_list_init(NTLM_AV_PAIR* pAvPairList)
{
NTLM_AV_PAIR* pAvPair = pAvPairList;
-
pAvPair->AvId = MsvAvEOL;
pAvPair->AvLen = 0;
}
}
length = (pAvPair - pAvPairList) + sizeof(NTLM_AV_PAIR);
-
return length;
}
if (!pAvPair)
return;
- fprintf(stderr, "AV_PAIRs =\n{\n");
+ WLog_INFO(TAG, "AV_PAIRs =");
while (pAvPair->AvId != MsvAvEOL)
{
- fprintf(stderr, "\t%s AvId: %d AvLen: %d\n",
- AV_PAIR_STRINGS[pAvPair->AvId],
- pAvPair->AvId, pAvPair->AvLen);
-
- winpr_HexDump(ntlm_av_pair_get_value_pointer(pAvPair), pAvPair->AvLen);
-
+ WLog_INFO(TAG, "\t%s AvId: %d AvLen: %d",
+ AV_PAIR_STRINGS[pAvPair->AvId],
+ pAvPair->AvId, pAvPair->AvLen);
+ winpr_HexDump(TAG, WLOG_INFO, ntlm_av_pair_get_value_pointer(pAvPair), pAvPair->AvLen);
pAvPair = ntlm_av_pair_get_next_pointer(pAvPair);
}
-
- fprintf(stderr, "}\n");
}
ULONG ntlm_av_pair_list_size(ULONG AvPairsCount, ULONG AvPairsValueLength)
NTLM_AV_PAIR* ntlm_av_pair_get_next_pointer(NTLM_AV_PAIR* pAvPair)
{
- return (NTLM_AV_PAIR*) ((PBYTE) pAvPair + ntlm_av_pair_get_next_offset(pAvPair));
+ return (NTLM_AV_PAIR*)((PBYTE) pAvPair + ntlm_av_pair_get_next_offset(pAvPair));
}
NTLM_AV_PAIR* ntlm_av_pair_get(NTLM_AV_PAIR* pAvPairList, NTLM_AV_ID AvId)
NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, NTLM_AV_ID AvId, PBYTE Value, UINT16 AvLen)
{
NTLM_AV_PAIR* pAvPair;
-
pAvPair = ntlm_av_pair_get(pAvPairList, MsvAvEOL);
if (!pAvPair)
pAvPair->AvId = AvId;
pAvPair->AvLen = AvLen;
-
CopyMemory(ntlm_av_pair_get_value_pointer(pAvPair), Value, AvLen);
-
return pAvPair;
}
NTLM_AV_PAIR* ntlm_av_pair_add_copy(NTLM_AV_PAIR* pAvPairList, NTLM_AV_PAIR* pAvPair)
{
NTLM_AV_PAIR* pAvPairCopy;
-
pAvPairCopy = ntlm_av_pair_get(pAvPairList, MsvAvEOL);
if (!pAvPairCopy)
pAvPairCopy->AvId = pAvPair->AvId;
pAvPairCopy->AvLen = pAvPair->AvLen;
-
CopyMemory(ntlm_av_pair_get_value_pointer(pAvPairCopy),
- ntlm_av_pair_get_value_pointer(pAvPair), pAvPair->AvLen);
-
+ ntlm_av_pair_get_value_pointer(pAvPair), pAvPair->AvLen);
return pAvPairCopy;
}
char* name;
int status;
DWORD nSize = 0;
-
GetComputerNameExA(type, NULL, &nSize);
-
name = (char*) malloc(nSize);
-
+
if (!name)
return -1;
-
+
if (!GetComputerNameExA(type, name, &nSize))
return -1;
if (status <= 0)
return status;
- pName->Length = (USHORT) ((status - 1) * 2);
+ pName->Length = (USHORT)((status - 1) * 2);
pName->MaximumLength = pName->Length;
-
free(name);
-
return 1;
}
static void ntlm_md5_update_uint32_be(MD5_CTX* md5, UINT32 num)
{
BYTE be32[4];
-
be32[0] = (num >> 0) & 0xFF;
be32[1] = (num >> 8) & 0xFF;
be32[2] = (num >> 16) & 0xFF;
be32[3] = (num >> 24) & 0xFF;
-
MD5_Update(md5, be32, 4);
}
BYTE* ChannelBindingToken;
UINT32 ChannelBindingTokenLength;
SEC_CHANNEL_BINDINGS* ChannelBindings;
-
ZeroMemory(context->ChannelBindingsHash, 16);
ChannelBindings = context->Bindings.Bindings;
ChannelBindingTokenLength = context->Bindings.BindingsLength - sizeof(SEC_CHANNEL_BINDINGS);
ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset];
-
MD5_Init(&md5);
-
ntlm_md5_update_uint32_be(&md5, ChannelBindings->dwInitiatorAddrType);
ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbInitiatorLength);
ntlm_md5_update_uint32_be(&md5, ChannelBindings->dwAcceptorAddrType);
ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbAcceptorLength);
ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbApplicationDataLength);
-
MD5_Update(&md5, (void*) ChannelBindingToken, ChannelBindingTokenLength);
-
MD5_Final(context->ChannelBindingsHash, &md5);
}
* different or if they are on different hosts, then the information MUST be ignored.
* Any fields after the MachineID field MUST be ignored on receipt.
*/
-
context->SingleHostData.Size = 48;
context->SingleHostData.Z4 = 0;
context->SingleHostData.DataPresent = 1;
UNICODE_STRING NbComputerName;
UNICODE_STRING DnsDomainName;
UNICODE_STRING DnsComputerName;
-
NbDomainName.Buffer = NULL;
if (ntlm_get_target_computer_name(&NbDomainName, ComputerNameNetBIOS) < 0)
AvPairsCount = 5;
AvPairsLength = NbDomainName.Length + NbComputerName.Length +
- DnsDomainName.Length + DnsComputerName.Length + 8;
-
+ DnsDomainName.Length + DnsComputerName.Length + 8;
length = ntlm_av_pair_list_size(AvPairsCount, AvPairsLength);
if (!sspi_SecBufferAlloc(&context->ChallengeTargetInfo, length))
pAvPairList = (NTLM_AV_PAIR*) context->ChallengeTargetInfo.pvBuffer;
AvPairListSize = (ULONG) context->ChallengeTargetInfo.cbBuffer;
-
ntlm_av_pair_list_init(pAvPairList);
ntlm_av_pair_add(pAvPairList, MsvAvNbDomainName, (PBYTE) NbDomainName.Buffer, NbDomainName.Length);
ntlm_av_pair_add(pAvPairList, MsvAvNbComputerName, (PBYTE) NbComputerName.Buffer, NbComputerName.Length);
ntlm_av_pair_add(pAvPairList, MsvAvDnsDomainName, (PBYTE) DnsDomainName.Buffer, DnsDomainName.Length);
ntlm_av_pair_add(pAvPairList, MsvAvDnsComputerName, (PBYTE) DnsComputerName.Buffer, DnsComputerName.Length);
ntlm_av_pair_add(pAvPairList, MsvAvTimestamp, context->Timestamp, sizeof(context->Timestamp));
-
ntlm_free_unicode_string(&NbDomainName);
ntlm_free_unicode_string(&NbComputerName);
ntlm_free_unicode_string(&DnsDomainName);
ntlm_free_unicode_string(&DnsComputerName);
-
return 1;
}
NTLM_AV_PAIR* AvDnsTreeName;
NTLM_AV_PAIR* ChallengeTargetInfo;
NTLM_AV_PAIR* AuthenticateTargetInfo;
-
AvPairsCount = 1;
AvPairsValueLength = 0;
ChallengeTargetInfo = (NTLM_AV_PAIR*) context->ChallengeTargetInfo.pvBuffer;
-
AvNbDomainName = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvNbDomainName);
AvNbComputerName = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvNbComputerName);
AvDnsDomainName = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvDnsDomainName);
* SEC_CHANNEL_BINDINGS structure
* http://msdn.microsoft.com/en-us/library/windows/desktop/dd919963/
*/
-
AvPairsCount++; /* MsvChannelBindings */
AvPairsValueLength += 16;
ntlm_compute_channel_bindings(context);
sspi_SecBufferAlloc(&context->AuthenticateTargetInfo, size);
AuthenticateTargetInfo = (NTLM_AV_PAIR*) context->AuthenticateTargetInfo.pvBuffer;
-
ntlm_av_pair_list_init(AuthenticateTargetInfo);
if (AvNbDomainName)
if (context->SendSingleHostData)
{
ntlm_av_pair_add(AuthenticateTargetInfo, MsvAvSingleHost,
- (PBYTE) &context->SingleHostData, context->SingleHostData.Size);
+ (PBYTE) &context->SingleHostData, context->SingleHostData.Size);
}
if (!context->SuppressExtendedProtection)
if (context->ServicePrincipalName.Length > 0)
{
ntlm_av_pair_add(AuthenticateTargetInfo, MsvAvTargetName,
- (PBYTE) context->ServicePrincipalName.Buffer,
- context->ServicePrincipalName.Length);
+ (PBYTE) context->ServicePrincipalName.Buffer,
+ context->ServicePrincipalName.Length);
}
}
if (context->NTLMv2)
{
NTLM_AV_PAIR* AvEOL;
-
AvEOL = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvEOL);
ZeroMemory((void*) AvEOL, 4);
}
#include "ntlm_compute.h"
+#include "../../log.h"
+#define TAG WINPR_TAG("sspi.NTLM")
+
const char LM_MAGIC[] = "KGS!@#$%";
static const char NTLM_CLIENT_SIGN_MAGIC[] = "session key to client-to-server signing key magic constant";
static const char NTLM_SERVER_SEAL_MAGIC[] = "session key to server-to-client sealing key magic constant";
static const BYTE NTLM_NULL_BUFFER[16] =
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/**
- * Populate VERSION structure.\n
+ * Populate VERSION structure.
* VERSION @msdn{cc236654}
* @param s
*/
void ntlm_get_version_info(NTLM_VERSION_INFO* versionInfo)
{
OSVERSIONINFOA osVersionInfo;
-
osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
-
GetVersionExA(&osVersionInfo);
-
versionInfo->ProductMajorVersion = (UINT8) osVersionInfo.dwMajorVersion;
versionInfo->ProductMinorVersion = (UINT8) osVersionInfo.dwMinorVersion;
versionInfo->ProductBuild = (UINT16) osVersionInfo.dwBuildNumber;
}
/**
- * Read VERSION structure.\n
+ * Read VERSION structure.
* VERSION @msdn{cc236654}
* @param s
*/
Stream_Read_UINT16(s, versionInfo->ProductBuild); /* ProductBuild (2 bytes) */
Stream_Read(s, versionInfo->Reserved, sizeof(versionInfo->Reserved)); /* Reserved (3 bytes) */
Stream_Read_UINT8(s, versionInfo->NTLMRevisionCurrent); /* NTLMRevisionCurrent (1 byte) */
-
return 1;
}
/**
- * Write VERSION structure.\n
+ * Write VERSION structure.
* VERSION @msdn{cc236654}
* @param s
*/
}
/**
- * Print VERSION structure.\n
+ * Print VERSION structure.
* VERSION @msdn{cc236654}
* @param s
*/
void ntlm_print_version_info(NTLM_VERSION_INFO* versionInfo)
{
- fprintf(stderr, "VERSION =\n{\n");
- fprintf(stderr, "\tProductMajorVersion: %d\n", versionInfo->ProductMajorVersion);
- fprintf(stderr, "\tProductMinorVersion: %d\n", versionInfo->ProductMinorVersion);
- fprintf(stderr, "\tProductBuild: %d\n", versionInfo->ProductBuild);
- fprintf(stderr, "\tReserved: 0x%02X%02X%02X\n", versionInfo->Reserved[0],
- versionInfo->Reserved[1], versionInfo->Reserved[2]);
- fprintf(stderr, "\tNTLMRevisionCurrent: 0x%02X\n", versionInfo->NTLMRevisionCurrent);
+ WLog_INFO(TAG, "VERSION ={");
+ WLog_INFO(TAG, "\tProductMajorVersion: %d", versionInfo->ProductMajorVersion);
+ WLog_INFO(TAG, "\tProductMinorVersion: %d", versionInfo->ProductMinorVersion);
+ WLog_INFO(TAG, "\tProductBuild: %d", versionInfo->ProductBuild);
+ WLog_INFO(TAG, "\tReserved: 0x%02X%02X%02X", versionInfo->Reserved[0],
+ versionInfo->Reserved[1], versionInfo->Reserved[2]);
+ WLog_INFO(TAG, "\tNTLMRevisionCurrent: 0x%02X", versionInfo->NTLMRevisionCurrent);
}
int ntlm_read_ntlm_v2_client_challenge(wStream* s, NTLMv2_CLIENT_CHALLENGE* challenge)
{
size_t size;
-
Stream_Read_UINT8(s, challenge->RespType);
Stream_Read_UINT8(s, challenge->HiRespType);
Stream_Read_UINT16(s, challenge->Reserved1);
Stream_Read(s, challenge->Timestamp, 8);
Stream_Read(s, challenge->ClientChallenge, 8);
Stream_Read_UINT32(s, challenge->Reserved3);
-
size = Stream_Length(s) - Stream_GetPosition(s);
challenge->AvPairs = (NTLM_AV_PAIR*) malloc(size);
return -1;
Stream_Read(s, challenge->AvPairs, size);
-
return 1;
}
int ntlm_write_ntlm_v2_client_challenge(wStream* s, NTLMv2_CLIENT_CHALLENGE* challenge)
{
ULONG length;
-
Stream_Write_UINT8(s, challenge->RespType);
Stream_Write_UINT8(s, challenge->HiRespType);
Stream_Write_UINT16(s, challenge->Reserved1);
Stream_Write(s, challenge->Timestamp, 8);
Stream_Write(s, challenge->ClientChallenge, 8);
Stream_Write_UINT32(s, challenge->Reserved3);
-
length = ntlm_av_pair_list_length(challenge->AvPairs);
Stream_Write(s, challenge->AvPairs, length);
-
return 1;
}
{
FILETIME filetime;
ULARGE_INTEGER time64;
-
GetSystemTimeAsFileTime(&filetime);
-
time64.LowPart = filetime.dwLowDateTime;
time64.HighPart = filetime.dwHighDateTime;
-
CopyMemory(timestamp, &(time64.QuadPart), 8);
}
WINPR_SAM* sam;
WINPR_SAM_ENTRY* entry;
SSPI_CREDENTIALS* credentials = context->credentials;
-
sam = SamOpen(TRUE);
-
+
if (!sam)
return -1;
entry = SamLookupUserW(sam,
- (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
- (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2);
+ (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
+ (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2);
if (entry)
{
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "NTLM Hash:\n");
- winpr_HexDump(entry->NtHash, 16);
+ WLog_DBG(TAG, "NTLM Hash:");
+ winpr_HexDump(TAG, WLOG_DEBUG, entry->NtHash, 16);
#endif
-
NTOWFv2FromHashW(entry->NtHash,
- (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
- (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2,
- (BYTE*) hash);
-
+ (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
+ (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2,
+ (BYTE*) hash);
SamFreeEntry(sam, entry);
SamClose(sam);
-
return 1;
}
entry = SamLookupUserW(sam,
- (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2, NULL, 0);
+ (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2, NULL, 0);
if (entry)
{
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "NTLM Hash:\n");
- winpr_HexDump(entry->NtHash, 16);
+ WLog_DBG(TAG, "NTLM Hash:");
+ winpr_HexDump(TAG, WLOG_DEBUG, entry->NtHash, 16);
#endif
-
NTOWFv2FromHashW(entry->NtHash,
- (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
- (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2,
- (BYTE*) hash);
-
+ (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
+ (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2,
+ (BYTE*) hash);
SamFreeEntry(sam, entry);
SamClose(sam);
-
return 1;
}
else
{
- fprintf(stderr, "Error: Could not find user in SAM database\n");
+ WLog_ERR(TAG, "Error: Could not find user in SAM database");
return 0;
}
SamClose(sam);
-
return 1;
}
char* PasswordHash = NULL;
UINT32 PasswordHashLength = 0;
SSPI_CREDENTIALS* credentials = context->credentials;
-
/* Password contains a password hash of length (PasswordLength / SSPI_CREDENTIALS_HASH_LENGTH_FACTOR) */
-
PasswordHashLength = credentials->identity.PasswordLength / SSPI_CREDENTIALS_HASH_LENGTH_FACTOR;
-
status = ConvertFromUnicode(CP_UTF8, 0, (LPCWSTR) credentials->identity.Password,
- PasswordHashLength, &PasswordHash, 0, NULL, NULL);
+ PasswordHashLength, &PasswordHash, 0, NULL, NULL);
if (status <= 0)
return -1;
}
free(PasswordHash);
-
return 1;
}
if (memcmp(context->NtlmHash, NTLM_NULL_BUFFER, 16) != 0)
{
NTOWFv2FromHashW(context->NtlmHash,
- (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
- (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2,
- (BYTE*) hash);
+ (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
+ (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2,
+ (BYTE*) hash);
}
else if (credentials->identity.PasswordLength > 256)
{
/* Special case for WinPR: password hash */
-
if (ntlm_convert_password_hash(context, context->NtlmHash) < 0)
return -1;
NTOWFv2FromHashW(context->NtlmHash,
- (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
- (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2,
- (BYTE*) hash);
+ (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
+ (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2,
+ (BYTE*) hash);
}
else if (credentials->identity.PasswordLength > 0)
{
NTOWFv2W((LPWSTR) credentials->identity.Password, credentials->identity.PasswordLength * 2,
- (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
- (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2, (BYTE*) hash);
+ (LPWSTR) credentials->identity.User, credentials->identity.UserLength * 2,
+ (LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2, (BYTE*) hash);
}
else if (context->UseSamFileDatabase)
{
return -1;
ZeroMemory(context->LmChallengeResponse.pvBuffer, 24);
-
return 1;
}
return -1;
response = (BYTE*) context->LmChallengeResponse.pvBuffer;
-
/* Compute the HMAC-MD5 hash of the resulting value using the NTLMv2 hash as the key */
HMAC(EVP_md5(), (void*) context->NtlmV2Hash, 16, (BYTE*) value, 16, (BYTE*) response, NULL);
-
/* Concatenate the resulting HMAC-MD5 hash and the client challenge, giving us the LMv2 response (24 bytes) */
CopyMemory(&response[16], context->ClientChallenge, 8);
-
return 1;
}
/**
- * Compute NTLMv2 Response.\n
- * NTLMv2_RESPONSE @msdn{cc236653}\n
+ * Compute NTLMv2 Response.
+ * NTLMv2_RESPONSE @msdn{cc236653}
* NTLMv2 Authentication @msdn{cc236700}
* @param NTLM context
*/
SecBuffer ntlm_v2_temp_chal;
PSecBuffer TargetInfo;
SSPI_CREDENTIALS* credentials;
-
credentials = context->credentials;
TargetInfo = &context->ChallengeTargetInfo;
return -1;
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "Password (length = %d)\n", credentials->identity.PasswordLength * 2);
- winpr_HexDump((BYTE*) credentials->identity.Password, credentials->identity.PasswordLength * 2);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Username (length = %d)\n", credentials->identity.UserLength * 2);
- winpr_HexDump((BYTE*) credentials->identity.User, credentials->identity.UserLength * 2);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Domain (length = %d)\n", credentials->identity.DomainLength * 2);
- winpr_HexDump((BYTE*) credentials->identity.Domain, credentials->identity.DomainLength * 2);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Workstation (length = %d)\n", context->Workstation.Length);
- winpr_HexDump((BYTE*) context->Workstation.Buffer, context->Workstation.Length);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "NTOWFv2, NTLMv2 Hash\n");
- winpr_HexDump(context->NtlmV2Hash, 16);
- fprintf(stderr, "\n");
+ WLog_DBG(TAG, "Password (length = %d)", credentials->identity.PasswordLength * 2);
+ winpr_HexDump(TAG, WLOG_DEBUG, (BYTE*) credentials->identity.Password, credentials->identity.PasswordLength * 2);
+ WLog_DBG(TAG, "Username (length = %d)", credentials->identity.UserLength * 2);
+ winpr_HexDump(TAG, WLOG_DEBUG, (BYTE*) credentials->identity.User, credentials->identity.UserLength * 2);
+ WLog_DBG(TAG, "Domain (length = %d)", credentials->identity.DomainLength * 2);
+ winpr_HexDump(TAG, WLOG_DEBUG, (BYTE*) credentials->identity.Domain, credentials->identity.DomainLength * 2);
+ WLog_DBG(TAG, "Workstation (length = %d)", context->Workstation.Length);
+ winpr_HexDump(TAG, WLOG_DEBUG, (BYTE*) context->Workstation.Buffer, context->Workstation.Length);
+ WLog_DBG(TAG, "NTOWFv2, NTLMv2 Hash");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->NtlmV2Hash, 16);
#endif
-
/* Construct temp */
blob[0] = 1; /* RespType (1 byte) */
blob[1] = 1; /* HighRespType (1 byte) */
CopyMemory(&blob[16], context->ClientChallenge, 8); /* ClientChallenge (8 bytes) */
/* Reserved3 (4 bytes) */
CopyMemory(&blob[28], TargetInfo->pvBuffer, TargetInfo->cbBuffer);
-
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "NTLMv2 Response Temp Blob\n");
- winpr_HexDump(ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
- fprintf(stderr, "\n");
+ WLog_DBG(TAG, "NTLMv2 Response Temp Blob");
+ winpr_HexDump(TAG, WLOG_DEBUG, ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
#endif
/* Concatenate server challenge with temp */
blob = (BYTE*) ntlm_v2_temp_chal.pvBuffer;
CopyMemory(blob, context->ServerChallenge, 8);
CopyMemory(&blob[8], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
-
HMAC(EVP_md5(), (BYTE*) context->NtlmV2Hash, 16, (BYTE*) ntlm_v2_temp_chal.pvBuffer,
- ntlm_v2_temp_chal.cbBuffer, (BYTE*) nt_proof_str, NULL);
+ ntlm_v2_temp_chal.cbBuffer, (BYTE*) nt_proof_str, NULL);
/* NtChallengeResponse, Concatenate NTProofStr with temp */
-
+
if (!sspi_SecBufferAlloc(&context->NtChallengeResponse, ntlm_v2_temp.cbBuffer + 16))
return -1;
blob = (BYTE*) context->NtChallengeResponse.pvBuffer;
CopyMemory(blob, nt_proof_str, 16);
CopyMemory(&blob[16], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
-
/* Compute SessionBaseKey, the HMAC-MD5 hash of NTProofStr using the NTLMv2 hash as the key */
HMAC(EVP_md5(), (BYTE*) context->NtlmV2Hash, 16, (BYTE*) nt_proof_str, 16, (BYTE*) context->SessionBaseKey, NULL);
-
sspi_SecBufferFree(&ntlm_v2_temp);
sspi_SecBufferFree(&ntlm_v2_temp_chal);
-
return 1;
}
void ntlm_rc4k(BYTE* key, int length, BYTE* plaintext, BYTE* ciphertext)
{
RC4_KEY rc4;
-
/* Initialize RC4 cipher with key */
RC4_set_key(&rc4, 16, (void*) key);
-
/* Encrypt plaintext with key */
RC4(&rc4, length, (void*) plaintext, (void*) ciphertext);
}
void ntlm_generate_client_challenge(NTLM_CONTEXT* context)
{
/* ClientChallenge is used in computation of LMv2 and NTLMv2 responses */
-
if (memcmp(context->ClientChallenge, NTLM_NULL_BUFFER, 8) == 0)
RAND_bytes(context->ClientChallenge, 8);
}
}
/**
- * Generate KeyExchangeKey (the 128-bit SessionBaseKey).\n
+ * Generate KeyExchangeKey (the 128-bit SessionBaseKey).
* @msdn{cc236710}
* @param NTLM context
*/
* else
* Set RandomSessionKey to KeyExchangeKey
*/
-
if (context->NegotiateKeyExchange)
ntlm_rc4k(context->KeyExchangeKey, 16, context->EncryptedRandomSessionKey, context->RandomSessionKey);
else
}
/**
- * Generate signing key.\n
+ * Generate signing key.
* @msdn{cc236711}
* @param exported_session_key ExportedSessionKey
* @param sign_magic Sign magic string
int length;
BYTE* value;
MD5_CTX md5;
-
length = 16 + sign_magic->cbBuffer;
value = (BYTE*) malloc(length);
/* Concatenate ExportedSessionKey with sign magic */
CopyMemory(value, exported_session_key, 16);
CopyMemory(&value[16], sign_magic->pvBuffer, sign_magic->cbBuffer);
-
MD5_Init(&md5);
MD5_Update(&md5, value, length);
MD5_Final(signing_key, &md5);
-
free(value);
-
return 1;
}
/**
- * Generate client signing key (ClientSigningKey).\n
+ * Generate client signing key (ClientSigningKey).
* @msdn{cc236711}
* @param NTLM context
*/
void ntlm_generate_client_signing_key(NTLM_CONTEXT* context)
{
SecBuffer signMagic;
-
signMagic.pvBuffer = (void*) NTLM_CLIENT_SIGN_MAGIC;
signMagic.cbBuffer = sizeof(NTLM_CLIENT_SIGN_MAGIC);
-
ntlm_generate_signing_key(context->ExportedSessionKey, &signMagic, context->ClientSigningKey);
}
/**
- * Generate server signing key (ServerSigningKey).\n
+ * Generate server signing key (ServerSigningKey).
* @msdn{cc236711}
* @param NTLM context
*/
void ntlm_generate_server_signing_key(NTLM_CONTEXT* context)
{
SecBuffer signMagic;
-
signMagic.pvBuffer = (void*) NTLM_SERVER_SIGN_MAGIC;
signMagic.cbBuffer = sizeof(NTLM_SERVER_SIGN_MAGIC);
-
ntlm_generate_signing_key(context->ExportedSessionKey, &signMagic, context->ServerSigningKey);
}
/**
- * Generate sealing key.\n
+ * Generate sealing key.
* @msdn{cc236712}
* @param exported_session_key ExportedSessionKey
* @param seal_magic Seal magic string
return -1;
p = (BYTE*) buffer.pvBuffer;
-
/* Concatenate ExportedSessionKey with seal magic */
CopyMemory(p, exported_session_key, 16);
CopyMemory(&p[16], seal_magic->pvBuffer, seal_magic->cbBuffer);
-
MD5_Init(&md5);
MD5_Update(&md5, buffer.pvBuffer, buffer.cbBuffer);
MD5_Final(sealing_key, &md5);
-
sspi_SecBufferFree(&buffer);
-
return 1;
}
/**
- * Generate client sealing key (ClientSealingKey).\n
+ * Generate client sealing key (ClientSealingKey).
* @msdn{cc236712}
* @param NTLM context
*/
void ntlm_generate_client_sealing_key(NTLM_CONTEXT* context)
{
SecBuffer sealMagic;
-
sealMagic.pvBuffer = (void*) NTLM_CLIENT_SEAL_MAGIC;
sealMagic.cbBuffer = sizeof(NTLM_CLIENT_SEAL_MAGIC);
-
ntlm_generate_signing_key(context->ExportedSessionKey, &sealMagic, context->ClientSealingKey);
}
/**
- * Generate server sealing key (ServerSealingKey).\n
+ * Generate server sealing key (ServerSealingKey).
* @msdn{cc236712}
* @param NTLM context
*/
void ntlm_generate_server_sealing_key(NTLM_CONTEXT* context)
{
SecBuffer sealMagic;
-
sealMagic.pvBuffer = (void*) NTLM_SERVER_SEAL_MAGIC;
sealMagic.cbBuffer = sizeof(NTLM_SERVER_SEAL_MAGIC);
-
ntlm_generate_signing_key(context->ExportedSessionKey, &sealMagic, context->ServerSealingKey);
}
void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context)
{
HMAC_CTX hmac_ctx;
-
/*
* Compute the HMAC-MD5 hash of ConcatenationOf(NEGOTIATE_MESSAGE,
* CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey
*/
-
HMAC_CTX_init(&hmac_ctx);
HMAC_Init_ex(&hmac_ctx, context->ExportedSessionKey, 16, EVP_md5(), NULL);
HMAC_Update(&hmac_ctx, (BYTE*) context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer);
#include "ntlm_message.h"
+#include "../log.h"
+#define TAG WINPR_TAG("sspi.NTLM")
+
static const char NTLM_SIGNATURE[8] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0' };
static const char* const NTLM_NEGOTIATE_STRINGS[] =
{
int i;
const char* str;
-
- fprintf(stderr, "negotiateFlags \"0x%08X\"{\n", flags);
+ WLog_INFO(TAG, "negotiateFlags \"0x%08X\"", flags);
for (i = 31; i >= 0; i--)
{
if ((flags >> i) & 1)
{
str = NTLM_NEGOTIATE_STRINGS[(31 - i)];
- fprintf(stderr, "\t%s (%d),\n", str, (31 - i));
+ WLog_INFO(TAG, "\t%s (%d),", str, (31 - i));
}
}
-
- fprintf(stderr, "}\n");
}
int ntlm_read_message_header(wStream* s, NTLM_MESSAGE_HEADER* header)
Stream_Read_UINT16(s, fields->Len); /* Len (2 bytes) */
Stream_Read_UINT16(s, fields->MaxLen); /* MaxLen (2 bytes) */
Stream_Read_UINT32(s, fields->BufferOffset); /* BufferOffset (4 bytes) */
-
return 1;
}
if (fields->Buffer)
{
free(fields->Buffer);
-
fields->Len = 0;
fields->MaxLen = 0;
fields->Buffer = NULL;
void ntlm_print_message_fields(NTLM_MESSAGE_FIELDS* fields, const char* name)
{
- fprintf(stderr, "%s (Len: %d MaxLen: %d BufferOffset: %d)\n",
- name, fields->Len, fields->MaxLen, fields->BufferOffset);
+ WLog_DBG(TAG, "%s (Len: %d MaxLen: %d BufferOffset: %d)",
+ name, fields->Len, fields->MaxLen, fields->BufferOffset);
if (fields->Len > 0)
- winpr_HexDump(fields->Buffer, fields->Len);
-
- fprintf(stderr, "\n");
+ winpr_HexDump(TAG, WLOG_DEBUG, fields->Buffer, fields->Len);
}
SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buffer)
wStream* s;
int length;
NTLM_NEGOTIATE_MESSAGE* message;
-
message = &context->NEGOTIATE_MESSAGE;
ZeroMemory(message, sizeof(NTLM_NEGOTIATE_MESSAGE));
-
s = Stream_New((BYTE*) buffer->pvBuffer, buffer->cbBuffer);
if (!s)
CopyMemory(context->NegotiateMessage.pvBuffer, buffer->pvBuffer, buffer->cbBuffer);
context->NegotiateMessage.BufferType = buffer->BufferType;
-
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "NEGOTIATE_MESSAGE (length = %d)\n", (int) context->NegotiateMessage.cbBuffer);
- winpr_HexDump(context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer);
- fprintf(stderr, "\n");
-
+ WLog_DBG(TAG, "NEGOTIATE_MESSAGE (length = %d)", (int) context->NegotiateMessage.cbBuffer);
+ winpr_HexDump(TAG, WLOG_DEBUG, context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer);
ntlm_print_negotiate_flags(message->NegotiateFlags);
if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
ntlm_print_version_info(&(message->Version));
-#endif
+#endif
context->state = NTLM_STATE_CHALLENGE;
-
Stream_Free(s, FALSE);
-
return SEC_I_CONTINUE_NEEDED;
}
wStream* s;
int length;
NTLM_NEGOTIATE_MESSAGE* message;
-
message = &context->NEGOTIATE_MESSAGE;
ZeroMemory(message, sizeof(NTLM_NEGOTIATE_MESSAGE));
-
s = Stream_New((BYTE*) buffer->pvBuffer, buffer->cbBuffer);
if (!s)
ntlm_get_version_info(&(message->Version));
context->NegotiateFlags = message->NegotiateFlags;
-
/* Message Header (12 bytes) */
ntlm_write_message_header(s, (NTLM_MESSAGE_HEADER*) message);
-
Stream_Write_UINT32(s, message->NegotiateFlags); /* NegotiateFlags (4 bytes) */
-
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
-
/* DomainNameFields (8 bytes) */
ntlm_write_message_fields(s, &(message->DomainName));
-
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
-
/* WorkstationFields (8 bytes) */
ntlm_write_message_fields(s, &(message->Workstation));
CopyMemory(context->NegotiateMessage.pvBuffer, buffer->pvBuffer, buffer->cbBuffer);
context->NegotiateMessage.BufferType = buffer->BufferType;
-
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "NEGOTIATE_MESSAGE (length = %d)\n", length);
- winpr_HexDump(Stream_Buffer(s), length);
- fprintf(stderr, "\n");
+ WLog_DBG(TAG, "NEGOTIATE_MESSAGE (length = %d)", length);
+ winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), length);
if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
ntlm_print_version_info(&(message->Version));
-#endif
+#endif
context->state = NTLM_STATE_CHALLENGE;
-
Stream_Free(s, FALSE);
-
return SEC_I_CONTINUE_NEEDED;
}
PBYTE PayloadOffset;
NTLM_AV_PAIR* AvTimestamp;
NTLM_CHALLENGE_MESSAGE* message;
-
ntlm_generate_client_challenge(context);
-
message = &context->CHALLENGE_MESSAGE;
ZeroMemory(message, sizeof(NTLM_CHALLENGE_MESSAGE));
-
s = Stream_New((BYTE*) buffer->pvBuffer, buffer->cbBuffer);
if (!s)
context->ChallengeTargetInfo.pvBuffer = message->TargetInfo.Buffer;
context->ChallengeTargetInfo.cbBuffer = message->TargetInfo.Len;
-
AvTimestamp = ntlm_av_pair_get((NTLM_AV_PAIR*) message->TargetInfo.Buffer, MsvAvTimestamp);
if (AvTimestamp)
return SEC_E_INTERNAL_ERROR;
CopyMemory(context->ChallengeMessage.pvBuffer, StartOffset, length);
-
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "CHALLENGE_MESSAGE (length = %d)\n", length);
- winpr_HexDump(context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
- fprintf(stderr, "\n");
-
+ WLog_DBG(TAG, "CHALLENGE_MESSAGE (length = %d)", length);
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
ntlm_print_negotiate_flags(context->NegotiateFlags);
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
if (context->ChallengeTargetInfo.cbBuffer > 0)
{
- fprintf(stderr, "ChallengeTargetInfo (%d):\n", (int) context->ChallengeTargetInfo.cbBuffer);
+ WLog_ERR(TAG, "ChallengeTargetInfo (%d):", (int) context->ChallengeTargetInfo.cbBuffer);
ntlm_print_av_pair_list(context->ChallengeTargetInfo.pvBuffer);
}
+
#endif
/* AV_PAIRs */
return SEC_E_INTERNAL_ERROR;
ntlm_generate_key_exchange_key(context); /* KeyExchangeKey */
-
ntlm_generate_random_session_key(context); /* RandomSessionKey */
-
ntlm_generate_exported_session_key(context); /* ExportedSessionKey */
-
ntlm_encrypt_random_session_key(context); /* EncryptedRandomSessionKey */
-
/* Generate signing keys */
ntlm_generate_client_signing_key(context);
ntlm_generate_server_signing_key(context);
-
/* Generate sealing keys */
ntlm_generate_client_sealing_key(context);
ntlm_generate_server_sealing_key(context);
-
/* Initialize RC4 seal state using client sealing key */
ntlm_init_rc4_seal_states(context);
-
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "ClientChallenge\n");
- winpr_HexDump(context->ClientChallenge, 8);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ServerChallenge\n");
- winpr_HexDump(context->ServerChallenge, 8);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "SessionBaseKey\n");
- winpr_HexDump(context->SessionBaseKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "KeyExchangeKey\n");
- winpr_HexDump(context->KeyExchangeKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ExportedSessionKey\n");
- winpr_HexDump(context->ExportedSessionKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "RandomSessionKey\n");
- winpr_HexDump(context->RandomSessionKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ClientSigningKey\n");
- winpr_HexDump(context->ClientSigningKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ClientSealingKey\n");
- winpr_HexDump(context->ClientSealingKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ServerSigningKey\n");
- winpr_HexDump(context->ServerSigningKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ServerSealingKey\n");
- winpr_HexDump(context->ServerSealingKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Timestamp\n");
- winpr_HexDump(context->Timestamp, 8);
- fprintf(stderr, "\n");
+ WLog_DBG(TAG, "ClientChallenge");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ClientChallenge, 8);
+ WLog_DBG(TAG, "ServerChallenge");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ServerChallenge, 8);
+ WLog_DBG(TAG, "SessionBaseKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->SessionBaseKey, 16);
+ WLog_DBG(TAG, "KeyExchangeKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->KeyExchangeKey, 16);
+ WLog_DBG(TAG, "ExportedSessionKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ExportedSessionKey, 16);
+ WLog_DBG(TAG, "RandomSessionKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->RandomSessionKey, 16);
+ WLog_DBG(TAG, "ClientSigningKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ClientSigningKey, 16);
+ WLog_DBG(TAG, "ClientSealingKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ClientSealingKey, 16);
+ WLog_DBG(TAG, "ServerSigningKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ServerSigningKey, 16);
+ WLog_DBG(TAG, "ServerSealingKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ServerSealingKey, 16);
+ WLog_DBG(TAG, "Timestamp");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->Timestamp, 8);
#endif
-
context->state = NTLM_STATE_AUTHENTICATE;
-
ntlm_free_message_fields_buffer(&(message->TargetName));
-
Stream_Free(s, FALSE);
-
return SEC_I_CONTINUE_NEEDED;
}
int length;
UINT32 PayloadOffset;
NTLM_CHALLENGE_MESSAGE* message;
-
message = &context->CHALLENGE_MESSAGE;
ZeroMemory(message, sizeof(NTLM_CHALLENGE_MESSAGE));
-
s = Stream_New((BYTE*) buffer->pvBuffer, buffer->cbBuffer);
if (!s)
return SEC_E_INTERNAL_ERROR;
ntlm_get_version_info(&(message->Version)); /* Version */
-
ntlm_generate_server_challenge(context); /* Server Challenge */
-
ntlm_generate_timestamp(context); /* Timestamp */
if (ntlm_construct_challenge_target_info(context) < 0) /* TargetInfo */
return SEC_E_INTERNAL_ERROR;
CopyMemory(message->ServerChallenge, context->ServerChallenge, 8); /* ServerChallenge */
-
message->NegotiateFlags = context->NegotiateFlags;
-
ntlm_populate_message_header((NTLM_MESSAGE_HEADER*) message, MESSAGE_TYPE_CHALLENGE);
-
/* Message Header (12 bytes) */
ntlm_write_message_header(s, (NTLM_MESSAGE_HEADER*) message);
message->TargetName.BufferOffset = PayloadOffset;
message->TargetInfo.BufferOffset = message->TargetName.BufferOffset + message->TargetName.Len;
-
/* TargetNameFields (8 bytes) */
ntlm_write_message_fields(s, &(message->TargetName));
-
Stream_Write_UINT32(s, message->NegotiateFlags); /* NegotiateFlags (4 bytes) */
-
Stream_Write(s, message->ServerChallenge, 8); /* ServerChallenge (8 bytes) */
Stream_Write(s, message->Reserved, 8); /* Reserved (8 bytes), should be ignored */
-
/* TargetInfoFields (8 bytes) */
ntlm_write_message_fields(s, &(message->TargetInfo));
return SEC_E_INTERNAL_ERROR;
CopyMemory(context->ChallengeMessage.pvBuffer, Stream_Buffer(s), length);
-
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "CHALLENGE_MESSAGE (length = %d)\n", length);
- winpr_HexDump(context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
- fprintf(stderr, "\n");
-
+ WLog_DBG(TAG, "CHALLENGE_MESSAGE (length = %d)", length);
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
ntlm_print_negotiate_flags(message->NegotiateFlags);
if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
ntlm_print_message_fields(&(message->TargetName), "TargetName");
ntlm_print_message_fields(&(message->TargetInfo), "TargetInfo");
#endif
-
context->state = NTLM_STATE_AUTHENTICATE;
-
Stream_Free(s, FALSE);
-
return SEC_I_CONTINUE_NEEDED;
}
UINT32 PayloadBufferOffset;
NTLM_AUTHENTICATE_MESSAGE* message;
SSPI_CREDENTIALS* credentials = context->credentials;
-
flags = 0;
AvFlags = NULL;
-
message = &context->AUTHENTICATE_MESSAGE;
ZeroMemory(message, sizeof(NTLM_AUTHENTICATE_MESSAGE));
-
s = Stream_New((BYTE*) buffer->pvBuffer, buffer->cbBuffer);
if (!s)
return SEC_E_INVALID_TOKEN;
Stream_Read_UINT32(s, message->NegotiateFlags); /* NegotiateFlags (4 bytes) */
-
context->NegotiateKeyExchange = (message->NegotiateFlags & NTLMSSP_NEGOTIATE_KEY_EXCH) ? TRUE : FALSE;
if ((context->NegotiateKeyExchange && !message->EncryptedRandomSessionKey.Len) ||
- (!context->NegotiateKeyExchange && message->EncryptedRandomSessionKey.Len))
+ (!context->NegotiateKeyExchange && message->EncryptedRandomSessionKey.Len))
return SEC_E_INVALID_TOKEN;
if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
return SEC_E_INVALID_TOKEN;
Stream_Free(snt, FALSE);
-
context->NtChallengeResponse.pvBuffer = message->NtChallengeResponse.Buffer;
context->NtChallengeResponse.cbBuffer = message->NtChallengeResponse.Len;
-
sspi_SecBufferFree(&(context->ChallengeTargetInfo));
context->ChallengeTargetInfo.pvBuffer = (void*) context->NTLMv2Response.Challenge.AvPairs;
context->ChallengeTargetInfo.cbBuffer = message->NtChallengeResponse.Len - (28 + 16);
-
CopyMemory(context->ClientChallenge, context->NTLMv2Response.Challenge.ClientChallenge, 8);
-
AvFlags = ntlm_av_pair_get(context->NTLMv2Response.Challenge.AvPairs, MsvAvFlags);
if (AvFlags)
if (!sspi_SecBufferAlloc(&context->AuthenticateMessage, length))
return SEC_E_INTERNAL_ERROR;
-
+
CopyMemory(context->AuthenticateMessage.pvBuffer, Stream_Buffer(s), length);
buffer->cbBuffer = length;
-
Stream_SetPosition(s, PayloadBufferOffset);
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
}
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "AUTHENTICATE_MESSAGE (length = %d)\n", (int) context->AuthenticateMessage.cbBuffer);
- winpr_HexDump(context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer);
- fprintf(stderr, "\n");
+ WLog_DBG(TAG, "AUTHENTICATE_MESSAGE (length = %d)", (int) context->AuthenticateMessage.cbBuffer);
+ winpr_HexDump(TAG, WLOG_DEBUG, context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer);
if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
ntlm_print_version_info(&(message->Version));
ntlm_print_message_fields(&(message->LmChallengeResponse), "LmChallengeResponse");
ntlm_print_message_fields(&(message->NtChallengeResponse), "NtChallengeResponse");
ntlm_print_message_fields(&(message->EncryptedRandomSessionKey), "EncryptedRandomSessionKey");
-
ntlm_print_av_pair_list(context->NTLMv2Response.Challenge.AvPairs);
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
{
- fprintf(stderr, "MessageIntegrityCheck:\n");
- winpr_HexDump(message->MessageIntegrityCheck, 16);
+ WLog_DBG(TAG, "MessageIntegrityCheck:");
+ winpr_HexDump(TAG, WLOG_DEBUG, message->MessageIntegrityCheck, 16);
}
+
#endif
if (message->UserName.Len > 0)
}
Stream_Free(s, FALSE);
-
/* Computations beyond this point require the NTLM hash of the password */
-
context->state = NTLM_STATE_COMPLETION;
-
return SEC_I_COMPLETE_NEEDED;
}
UINT32 PayloadBufferOffset;
NTLM_AUTHENTICATE_MESSAGE* message;
SSPI_CREDENTIALS* credentials = context->credentials;
-
message = &context->AUTHENTICATE_MESSAGE;
ZeroMemory(message, sizeof(NTLM_AUTHENTICATE_MESSAGE));
-
s = Stream_New((BYTE*) buffer->pvBuffer, buffer->cbBuffer);
if (!s)
message->UserName.Len = (UINT16) credentials->identity.UserLength * 2;
message->UserName.Buffer = (BYTE*) credentials->identity.User;
-
message->LmChallengeResponse.Len = (UINT16) context->LmChallengeResponse.cbBuffer;
message->LmChallengeResponse.Buffer = (BYTE*) context->LmChallengeResponse.pvBuffer;
-
message->NtChallengeResponse.Len = (UINT16) context->NtChallengeResponse.cbBuffer;
message->NtChallengeResponse.Buffer = (BYTE*) context->NtChallengeResponse.pvBuffer;
message->LmChallengeResponse.BufferOffset = message->Workstation.BufferOffset + message->Workstation.Len;
message->NtChallengeResponse.BufferOffset = message->LmChallengeResponse.BufferOffset + message->LmChallengeResponse.Len;
message->EncryptedRandomSessionKey.BufferOffset = message->NtChallengeResponse.BufferOffset + message->NtChallengeResponse.Len;
-
ntlm_populate_message_header((NTLM_MESSAGE_HEADER*) message, MESSAGE_TYPE_AUTHENTICATE);
-
- ntlm_write_message_header(s, (NTLM_MESSAGE_HEADER*) message); /* Message Header (12 bytes) */
-
+ ntlm_write_message_header(s, (NTLM_MESSAGE_HEADER*) message); /* Message Header (12 bytes) */
ntlm_write_message_fields(s, &(message->LmChallengeResponse)); /* LmChallengeResponseFields (8 bytes) */
-
ntlm_write_message_fields(s, &(message->NtChallengeResponse)); /* NtChallengeResponseFields (8 bytes) */
-
ntlm_write_message_fields(s, &(message->DomainName)); /* DomainNameFields (8 bytes) */
-
ntlm_write_message_fields(s, &(message->UserName)); /* UserNameFields (8 bytes) */
-
ntlm_write_message_fields(s, &(message->Workstation)); /* WorkstationFields (8 bytes) */
-
ntlm_write_message_fields(s, &(message->EncryptedRandomSessionKey)); /* EncryptedRandomSessionKeyFields (8 bytes) */
-
Stream_Write_UINT32(s, message->NegotiateFlags); /* NegotiateFlags (4 bytes) */
if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
ntlm_write_message_fields_buffer(s, &(message->Workstation)); /* Workstation */
ntlm_write_message_fields_buffer(s, &(message->LmChallengeResponse)); /* LmChallengeResponse */
-
ntlm_write_message_fields_buffer(s, &(message->NtChallengeResponse)); /* NtChallengeResponse */
if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_KEY_EXCH)
ntlm_write_message_fields_buffer(s, &(message->EncryptedRandomSessionKey)); /* EncryptedRandomSessionKey */
length = Stream_GetPosition(s);
-
+
if (!sspi_SecBufferAlloc(&context->AuthenticateMessage, length))
return SEC_E_INTERNAL_ERROR;
{
/* Message Integrity Check */
ntlm_compute_message_integrity_check(context);
-
Stream_SetPosition(s, context->MessageIntegrityCheckOffset);
Stream_Write(s, context->MessageIntegrityCheck, 16);
Stream_SetPosition(s, length);
}
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "AUTHENTICATE_MESSAGE (length = %d)\n", length);
- winpr_HexDump(Stream_Buffer(s), length);
- fprintf(stderr, "\n");
-
+ WLog_DBG(TAG, "AUTHENTICATE_MESSAGE (length = %d)", length);
+ winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), length);
ntlm_print_negotiate_flags(message->NegotiateFlags);
if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
if (context->AuthenticateTargetInfo.cbBuffer > 0)
{
- fprintf(stderr, "AuthenticateTargetInfo (%d):\n", (int) context->AuthenticateTargetInfo.cbBuffer);
+ WLog_ERR(TAG, "AuthenticateTargetInfo (%d):", (int) context->AuthenticateTargetInfo.cbBuffer);
ntlm_print_av_pair_list(context->AuthenticateTargetInfo.pvBuffer);
}
if (context->UseMIC)
{
- fprintf(stderr, "MessageIntegrityCheck (length = 16)\n");
- winpr_HexDump(context->MessageIntegrityCheck, 16);
- fprintf(stderr, "\n");
+ WLog_DBG(TAG, "MessageIntegrityCheck (length = 16)");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->MessageIntegrityCheck, 16);
}
-#endif
+#endif
context->state = NTLM_STATE_FINAL;
-
Stream_Free(s, FALSE);
-
return SEC_I_COMPLETE_NEEDED;
}
return SEC_E_OUT_OF_SEQUENCE;
message = &context->AUTHENTICATE_MESSAGE;
-
AvFlags = ntlm_av_pair_get(context->NTLMv2Response.Challenge.AvPairs, MsvAvFlags);
if (AvFlags)
/* KeyExchangeKey */
ntlm_generate_key_exchange_key(context);
-
/* EncryptedRandomSessionKey */
ntlm_decrypt_random_session_key(context);
-
/* ExportedSessionKey */
ntlm_generate_exported_session_key(context);
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
{
ZeroMemory(&((PBYTE) context->AuthenticateMessage.pvBuffer)[context->MessageIntegrityCheckOffset], 16);
-
ntlm_compute_message_integrity_check(context);
-
CopyMemory(&((PBYTE) context->AuthenticateMessage.pvBuffer)[context->MessageIntegrityCheckOffset],
- message->MessageIntegrityCheck, 16);
+ message->MessageIntegrityCheck, 16);
if (memcmp(context->MessageIntegrityCheck, message->MessageIntegrityCheck, 16) != 0)
{
- fprintf(stderr, "Message Integrity Check (MIC) verification failed!\n");
-
- fprintf(stderr, "Expected MIC:\n");
- winpr_HexDump(context->MessageIntegrityCheck, 16);
- fprintf(stderr, "Actual MIC:\n");
- winpr_HexDump(message->MessageIntegrityCheck, 16);
-
+ WLog_ERR(TAG, "Message Integrity Check (MIC) verification failed!");
+ WLog_ERR(TAG, "Expected MIC:");
+ winpr_HexDump(TAG, WLOG_ERROR, context->MessageIntegrityCheck, 16);
+ WLog_ERR(TAG, "Actual MIC:");
+ winpr_HexDump(TAG, WLOG_ERROR, message->MessageIntegrityCheck, 16);
return SEC_E_MESSAGE_ALTERED;
}
}
/* Generate signing keys */
ntlm_generate_client_signing_key(context);
ntlm_generate_server_signing_key(context);
-
/* Generate sealing keys */
ntlm_generate_client_sealing_key(context);
ntlm_generate_server_sealing_key(context);
-
/* Initialize RC4 seal state */
ntlm_init_rc4_seal_states(context);
-
#ifdef WITH_DEBUG_NTLM
- fprintf(stderr, "ClientChallenge\n");
- winpr_HexDump(context->ClientChallenge, 8);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ServerChallenge\n");
- winpr_HexDump(context->ServerChallenge, 8);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "SessionBaseKey\n");
- winpr_HexDump(context->SessionBaseKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "KeyExchangeKey\n");
- winpr_HexDump(context->KeyExchangeKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ExportedSessionKey\n");
- winpr_HexDump(context->ExportedSessionKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "RandomSessionKey\n");
- winpr_HexDump(context->RandomSessionKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ClientSigningKey\n");
- winpr_HexDump(context->ClientSigningKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ClientSealingKey\n");
- winpr_HexDump(context->ClientSealingKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ServerSigningKey\n");
- winpr_HexDump(context->ServerSigningKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "ServerSealingKey\n");
- winpr_HexDump(context->ServerSealingKey, 16);
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Timestamp\n");
- winpr_HexDump(context->Timestamp, 8);
- fprintf(stderr, "\n");
+ WLog_DBG(TAG, "ClientChallenge");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ClientChallenge, 8);
+ WLog_DBG(TAG, "ServerChallenge");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ServerChallenge, 8);
+ WLog_DBG(TAG, "SessionBaseKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->SessionBaseKey, 16);
+ WLog_DBG(TAG, "KeyExchangeKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->KeyExchangeKey, 16);
+ WLog_DBG(TAG, "ExportedSessionKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ExportedSessionKey, 16);
+ WLog_DBG(TAG, "RandomSessionKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->RandomSessionKey, 16);
+ WLog_DBG(TAG, "ClientSigningKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ClientSigningKey, 16);
+ WLog_DBG(TAG, "ClientSealingKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ClientSealingKey, 16);
+ WLog_DBG(TAG, "ServerSigningKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ServerSigningKey, 16);
+ WLog_DBG(TAG, "ServerSealingKey");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->ServerSealingKey, 16);
+ WLog_DBG(TAG, "Timestamp");
+ winpr_HexDump(TAG, WLOG_DEBUG, context->Timestamp, 8);
#endif
-
context->state = NTLM_STATE_FINAL;
-
ntlm_free_message_fields_buffer(&(message->DomainName));
ntlm_free_message_fields_buffer(&(message->UserName));
ntlm_free_message_fields_buffer(&(message->Workstation));
ntlm_free_message_fields_buffer(&(message->LmChallengeResponse));
ntlm_free_message_fields_buffer(&(message->NtChallengeResponse));
ntlm_free_message_fields_buffer(&(message->EncryptedRandomSessionKey));
-
return SEC_E_OK;
}
* Schannel Security Package (OpenSSL)
*
* Copyright 2012-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
#include "schannel_openssl.h"
+#include "../../log.h"
+#define TAG WINPR_TAG("sspi.schannel")
+
char* openssl_get_ssl_error_string(int ssl_error)
{
switch (ssl_error)
{
int status;
long options = 0;
-
context->ctx = SSL_CTX_new(TLSv1_client_method());
if (!context->ctx)
{
- fprintf(stderr, "SSL_CTX_new failed\n");
+ WLog_ERR(TAG, "SSL_CTX_new failed");
return -1;
}
#ifdef SSL_OP_NO_COMPRESSION
options |= SSL_OP_NO_COMPRESSION;
#endif
-
/**
* SSL_OP_TLS_BLOCK_PADDING_BUG:
*
* It absolutely needs to be disabled otherwise it won't work.
*/
options |= SSL_OP_TLS_BLOCK_PADDING_BUG;
-
/**
* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
*
* support empty fragments. This needs to be disabled.
*/
options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
-
SSL_CTX_set_options(context->ctx, options);
-
context->ssl = SSL_new(context->ctx);
if (!context->ssl)
{
- fprintf(stderr, "SSL_new failed\n");
+ WLog_ERR(TAG, "SSL_new failed");
return -1;
}
if (!context->bioRead)
{
- fprintf(stderr, "BIO_new failed\n");
+ WLog_ERR(TAG, "BIO_new failed");
return -1;
}
status = BIO_set_write_buf_size(context->bioRead, SCHANNEL_CB_MAX_TOKEN);
-
context->bioWrite = BIO_new(BIO_s_mem());
if (!context->bioWrite)
{
- fprintf(stderr, "BIO_new failed\n");
+ WLog_ERR(TAG, "BIO_new failed");
return -1;
}
status = BIO_set_write_buf_size(context->bioWrite, SCHANNEL_CB_MAX_TOKEN);
-
status = BIO_make_bio_pair(context->bioRead, context->bioWrite);
-
SSL_set_bio(context->ssl, context->bioRead, context->bioWrite);
-
context->ReadBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
context->WriteBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
-
return 0;
}
{
int status;
long options = 0;
-
//context->ctx = SSL_CTX_new(SSLv23_server_method());
context->ctx = SSL_CTX_new(TLSv1_server_method());
if (!context->ctx)
{
- fprintf(stderr, "SSL_CTX_new failed\n");
+ WLog_ERR(TAG, "SSL_CTX_new failed");
return -1;
}
* SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
*/
options |= SSL_OP_NO_SSLv2;
-
/**
* SSL_OP_NO_COMPRESSION:
*
#ifdef SSL_OP_NO_COMPRESSION
options |= SSL_OP_NO_COMPRESSION;
#endif
-
/**
* SSL_OP_TLS_BLOCK_PADDING_BUG:
*
* It absolutely needs to be disabled otherwise it won't work.
*/
options |= SSL_OP_TLS_BLOCK_PADDING_BUG;
-
/**
* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
*
* support empty fragments. This needs to be disabled.
*/
options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
-
SSL_CTX_set_options(context->ctx, options);
if (SSL_CTX_use_RSAPrivateKey_file(context->ctx, "/tmp/localhost.key", SSL_FILETYPE_PEM) <= 0)
{
- fprintf(stderr, "SSL_CTX_use_RSAPrivateKey_file failed\n");
+ WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed");
return -1;
}
if (!context->ssl)
{
- fprintf(stderr, "SSL_new failed\n");
+ WLog_ERR(TAG, "SSL_new failed");
return -1;
}
if (SSL_use_certificate_file(context->ssl, "/tmp/localhost.crt", SSL_FILETYPE_PEM) <= 0)
{
- fprintf(stderr, "SSL_use_certificate_file failed\n");
+ WLog_ERR(TAG, "SSL_use_certificate_file failed");
return -1;
}
if (!context->bioRead)
{
- fprintf(stderr, "BIO_new failed\n");
+ WLog_ERR(TAG, "BIO_new failed");
return -1;
}
status = BIO_set_write_buf_size(context->bioRead, SCHANNEL_CB_MAX_TOKEN);
-
context->bioWrite = BIO_new(BIO_s_mem());
if (!context->bioWrite)
{
- fprintf(stderr, "BIO_new failed\n");
+ WLog_ERR(TAG, "BIO_new failed");
return -1;
}
status = BIO_set_write_buf_size(context->bioWrite, SCHANNEL_CB_MAX_TOKEN);
-
status = BIO_make_bio_pair(context->bioRead, context->bioWrite);
-
SSL_set_bio(context->ssl, context->bioRead, context->bioWrite);
-
context->ReadBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
context->WriteBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
-
return 0;
}
if (status < 0)
{
ssl_error = SSL_get_error(context->ssl, status);
- fprintf(stderr, "SSL_connect error: %s\n", openssl_get_ssl_error_string(ssl_error));
+ WLog_ERR(TAG, "SSL_connect error: %s", openssl_get_ssl_error_string(ssl_error));
}
if (status == 1)
CopyMemory(pBuffer->pvBuffer, context->ReadBuffer, status);
pBuffer->cbBuffer = status;
-
return (context->connected) ? SEC_E_OK : SEC_I_CONTINUE_NEEDED;
}
else
return SEC_E_INVALID_TOKEN;
status = BIO_write(context->bioRead, pBuffer->pvBuffer, pBuffer->cbBuffer);
-
status = SSL_accept(context->ssl);
if (status < 0)
{
ssl_error = SSL_get_error(context->ssl, status);
- fprintf(stderr, "SSL_accept error: %s\n", openssl_get_ssl_error_string(ssl_error));
+ WLog_ERR(TAG, "SSL_accept error: %s", openssl_get_ssl_error_string(ssl_error));
}
if (status == 1)
CopyMemory(pBuffer->pvBuffer, context->ReadBuffer, status);
pBuffer->cbBuffer = status;
-
return (context->connected) ? SEC_E_OK : SEC_I_CONTINUE_NEEDED;
}
else
PSecBuffer pStreamBodyBuffer;
PSecBuffer pStreamHeaderBuffer;
PSecBuffer pStreamTrailerBuffer;
-
pStreamHeaderBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_STREAM_HEADER);
pStreamBodyBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_DATA);
pStreamTrailerBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_STREAM_TRAILER);
if (status < 0)
{
ssl_error = SSL_get_error(context->ssl, status);
- fprintf(stderr, "SSL_write: %s\n", openssl_get_ssl_error_string(ssl_error));
+ WLog_ERR(TAG, "SSL_write: %s", openssl_get_ssl_error_string(ssl_error));
}
status = BIO_read(context->bioWrite, context->ReadBuffer, SCHANNEL_CB_MAX_TOKEN);
length = (pStreamHeaderBuffer->cbBuffer > (unsigned long) status) ? status : pStreamHeaderBuffer->cbBuffer;
CopyMemory(pStreamHeaderBuffer->pvBuffer, &context->ReadBuffer[offset], length);
status -= length;
-
offset += length;
length = (pStreamBodyBuffer->cbBuffer > (unsigned long) status) ? status : pStreamBodyBuffer->cbBuffer;
CopyMemory(pStreamBodyBuffer->pvBuffer, &context->ReadBuffer[offset], length);
status -= length;
-
offset += length;
length = (pStreamTrailerBuffer->cbBuffer > (unsigned long) status) ? status : pStreamTrailerBuffer->cbBuffer;
CopyMemory(pStreamTrailerBuffer->pvBuffer, &context->ReadBuffer[offset], length);
BYTE* buffer;
int ssl_error;
PSecBuffer pBuffer;
-
pBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_DATA);
if (!pBuffer)
return SEC_E_INVALID_TOKEN;
status = BIO_write(context->bioRead, pBuffer->pvBuffer, pBuffer->cbBuffer);
-
status = SSL_read(context->ssl, pBuffer->pvBuffer, pBuffer->cbBuffer);
if (status < 0)
{
ssl_error = SSL_get_error(context->ssl, status);
- fprintf(stderr, "SSL_read: %s\n", openssl_get_ssl_error_string(ssl_error));
+ WLog_ERR(TAG, "SSL_read: %s", openssl_get_ssl_error_string(ssl_error));
}
length = status;
buffer = pBuffer->pvBuffer;
-
pMessage->pBuffers[0].BufferType = SECBUFFER_STREAM_HEADER;
pMessage->pBuffers[0].cbBuffer = 5;
-
pMessage->pBuffers[1].BufferType = SECBUFFER_DATA;
pMessage->pBuffers[1].pvBuffer = buffer;
pMessage->pBuffers[1].cbBuffer = length;
-
pMessage->pBuffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
pMessage->pBuffers[2].cbBuffer = 36;
-
pMessage->pBuffers[3].BufferType = SECBUFFER_EMPTY;
pMessage->pBuffers[3].cbBuffer = 0;
-
return SEC_E_OK;
}
SCHANNEL_OPENSSL* schannel_openssl_new()
{
SCHANNEL_OPENSSL* context;
-
context = (SCHANNEL_OPENSSL*) malloc(sizeof(SCHANNEL_OPENSSL));
if (context != NULL)
{
free(context->ReadBuffer);
free(context->WriteBuffer);
-
free(context);
}
}
#include <winpr/crt.h>
#include <winpr/sspi.h>
#include <winpr/print.h>
+#include <winpr/wlog.h>
static BYTE TEST_NTLM_TIMESTAMP[8] = { 0x33, 0x57, 0xbd, 0xb1, 0x07, 0x8b, 0xcf, 0x01 };
//static const char* TEST_NTLM_HASH_STRING = "d5922a65c4d5c082ca444af1be0001db";
static const BYTE TEST_NTLM_HASH[16] =
- { 0xd5, 0x92, 0x2a, 0x65, 0xc4, 0xd5, 0xc0, 0x82, 0xca, 0x44, 0x4a, 0xf1, 0xbe, 0x00, 0x01, 0xdb };
+{ 0xd5, 0x92, 0x2a, 0x65, 0xc4, 0xd5, 0xc0, 0x82, 0xca, 0x44, 0x4a, 0xf1, 0xbe, 0x00, 0x01, 0xdb };
//static const char* TEST_NTLM_HASH_V2_STRING = "4c7f706f7dde05a9d1a0f4e7ffe3bfb8";
static const BYTE TEST_NTLM_V2_HASH[16] =
- { 0x4c, 0x7f, 0x70, 0x6f, 0x7d, 0xde, 0x05, 0xa9, 0xd1, 0xa0, 0xf4, 0xe7, 0xff, 0xe3, 0xbf, 0xb8 };
+{ 0x4c, 0x7f, 0x70, 0x6f, 0x7d, 0xde, 0x05, 0xa9, 0xd1, 0xa0, 0xf4, 0xe7, 0xff, 0xe3, 0xbf, 0xb8 };
//#define NTLM_PACKAGE_NAME NEGOSSP_NAME
#define NTLM_PACKAGE_NAME NTLMSP_NAME
int test_ntlm_client_init(TEST_NTLM_CLIENT* ntlm, const char* user, const char* domain, const char* password)
{
SECURITY_STATUS status;
-
SecInvalidateHandle(&(ntlm->context));
-
ntlm->table = InitSecurityInterfaceEx(TEST_SSPI_INTERFACE);
-
sspi_SetAuthIdentity(&(ntlm->identity), user, domain, password);
-
status = ntlm->table->QuerySecurityPackageInfo(NTLM_PACKAGE_NAME, &ntlm->pPackageInfo);
if (status != SEC_E_OK)
}
ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken;
-
status = ntlm->table->AcquireCredentialsHandle(NULL, NTLM_PACKAGE_NAME,
- SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL, &ntlm->credentials, &ntlm->expiration);
+ SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL, &ntlm->credentials, &ntlm->expiration);
if (status != SEC_E_OK)
{
ntlm->haveInputBuffer = FALSE;
ZeroMemory(&ntlm->inputBuffer, sizeof(SecBuffer));
ZeroMemory(&ntlm->outputBuffer, sizeof(SecBuffer));
-
ntlm->fContextReq = 0;
-
#if 0
/* HTTP authentication flags */
ntlm->fContextReq |= ISC_REQ_CONFIDENTIALITY;
#endif
-
/* NLA authentication flags */
ntlm->fContextReq |= ISC_REQ_MUTUAL_AUTH;
ntlm->fContextReq |= ISC_REQ_CONFIDENTIALITY;
ntlm->fContextReq |= ISC_REQ_USE_SESSION_KEY;
-
return 1;
}
}
status = ntlm->table->InitializeSecurityContext(&ntlm->credentials,
- (ntlm->haveContext) ? &ntlm->context : NULL,
- (ntlm->ServicePrincipalName) ? ntlm->ServicePrincipalName : NULL,
- ntlm->fContextReq, 0, SECURITY_NATIVE_DREP,
- (ntlm->haveInputBuffer) ? &ntlm->inputBufferDesc : NULL,
- 0, &ntlm->context, &ntlm->outputBufferDesc,
- &ntlm->pfContextAttr, &ntlm->expiration);
+ (ntlm->haveContext) ? &ntlm->context : NULL,
+ (ntlm->ServicePrincipalName) ? ntlm->ServicePrincipalName : NULL,
+ ntlm->fContextReq, 0, SECURITY_NATIVE_DREP,
+ (ntlm->haveInputBuffer) ? &ntlm->inputBufferDesc : NULL,
+ 0, &ntlm->context, &ntlm->outputBufferDesc,
+ &ntlm->pfContextAttr, &ntlm->expiration);
if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED))
{
ntlm->haveInputBuffer = TRUE;
ntlm->haveContext = TRUE;
-
return (status == SEC_I_CONTINUE_NEEDED) ? 1 : 0;
}
TEST_NTLM_CLIENT* test_ntlm_client_new()
{
TEST_NTLM_CLIENT* ntlm;
-
ntlm = (TEST_NTLM_CLIENT*) calloc(1, sizeof(TEST_NTLM_CLIENT));
if (!ntlm)
return;
test_ntlm_client_uninit(ntlm);
-
free(ntlm);
}
int test_ntlm_server_init(TEST_NTLM_SERVER* ntlm)
{
SECURITY_STATUS status;
-
ntlm->UseNtlmV2Hash = TRUE;
-
SecInvalidateHandle(&(ntlm->context));
-
ntlm->table = InitSecurityInterfaceEx(TEST_SSPI_INTERFACE);
-
status = ntlm->table->QuerySecurityPackageInfo(NTLM_PACKAGE_NAME, &ntlm->pPackageInfo);
if (status != SEC_E_OK)
}
ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken;
-
status = ntlm->table->AcquireCredentialsHandle(NULL, NTLM_PACKAGE_NAME,
- SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL,
- &ntlm->credentials, &ntlm->expiration);
+ SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL,
+ &ntlm->credentials, &ntlm->expiration);
if (status != SEC_E_OK)
{
ntlm->haveInputBuffer = FALSE;
ZeroMemory(&ntlm->inputBuffer, sizeof(SecBuffer));
ZeroMemory(&ntlm->outputBuffer, sizeof(SecBuffer));
-
ntlm->fContextReq = 0;
-
/* NLA authentication flags */
ntlm->fContextReq |= ASC_REQ_MUTUAL_AUTH;
ntlm->fContextReq |= ASC_REQ_CONFIDENTIALITY;
ntlm->fContextReq |= ASC_REQ_REPLAY_DETECT;
ntlm->fContextReq |= ASC_REQ_SEQUENCE_DETECT;
ntlm->fContextReq |= ASC_REQ_EXTENDED_ERROR;
-
return 1;
}
int test_ntlm_server_authenticate(TEST_NTLM_SERVER* ntlm)
{
SECURITY_STATUS status;
-
ntlm->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
ntlm->inputBufferDesc.cBuffers = 1;
ntlm->inputBufferDesc.pBuffers = ntlm->inputBuffer;
ntlm->inputBuffer[0].BufferType = SECBUFFER_TOKEN;
-
ntlm->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
ntlm->outputBufferDesc.cBuffers = 1;
ntlm->outputBufferDesc.pBuffers = &ntlm->outputBuffer[0];
ntlm->outputBuffer[0].BufferType = SECBUFFER_TOKEN;
ntlm->outputBuffer[0].cbBuffer = ntlm->cbMaxToken;
ntlm->outputBuffer[0].pvBuffer = malloc(ntlm->outputBuffer[0].cbBuffer);
-
status = ntlm->table->AcceptSecurityContext(&ntlm->credentials,
- ntlm->haveContext? &ntlm->context: NULL,
- &ntlm->inputBufferDesc, ntlm->fContextReq, SECURITY_NATIVE_DREP, &ntlm->context,
- &ntlm->outputBufferDesc, &ntlm->pfContextAttr, &ntlm->expiration);
+ ntlm->haveContext? &ntlm->context: NULL,
+ &ntlm->inputBufferDesc, ntlm->fContextReq, SECURITY_NATIVE_DREP, &ntlm->context,
+ &ntlm->outputBufferDesc, &ntlm->pfContextAttr, &ntlm->expiration);
if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED))
{
SecPkgContext_AuthIdentity AuthIdentity;
SecPkgContext_AuthNtlmHash AuthNtlmHash;
-
ZeroMemory(&AuthIdentity, sizeof(SecPkgContext_AuthIdentity));
ZeroMemory(&AuthNtlmHash, sizeof(SecPkgContext_AuthNtlmHash));
-
status = ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_AUTH_IDENTITY, &AuthIdentity);
if (status == SEC_E_OK)
}
status = ntlm->table->SetContextAttributes(&ntlm->context,
- SECPKG_ATTR_AUTH_NTLM_HASH, &AuthNtlmHash, sizeof(SecPkgContext_AuthNtlmHash));
+ SECPKG_ATTR_AUTH_NTLM_HASH, &AuthNtlmHash, sizeof(SecPkgContext_AuthNtlmHash));
}
}
}
ntlm->haveContext = TRUE;
-
return (status == SEC_I_CONTINUE_NEEDED) ? 1 : 0;
}
TEST_NTLM_SERVER* test_ntlm_server_new()
{
TEST_NTLM_SERVER* ntlm;
-
ntlm = (TEST_NTLM_SERVER*) calloc(1, sizeof(TEST_NTLM_SERVER));
if (!ntlm)
return;
test_ntlm_server_uninit(ntlm);
-
free(ntlm);
}
TEST_NTLM_CLIENT* client;
TEST_NTLM_SERVER* server;
BOOL DynamicTest = TRUE;
-
/**
* Client Initialization
*/
-
client = test_ntlm_client_new();
-
status = test_ntlm_client_init(client, TEST_NTLM_USER, TEST_NTLM_DOMAIN, TEST_NTLM_PASSWORD);
if (status < 0)
/**
* Server Initialization
*/
-
server = test_ntlm_server_new();
-
status = test_ntlm_server_init(server);
if (status < 0)
/**
* Client -> Negotiate Message
*/
-
status = test_ntlm_client_authenticate(client);
if (status < 0)
SecPkgContext_AuthNtlmTimestamp AuthNtlmTimestamp;
SecPkgContext_AuthNtlmClientChallenge AuthNtlmClientChallenge;
SecPkgContext_AuthNtlmServerChallenge AuthNtlmServerChallenge;
-
CopyMemory(AuthNtlmTimestamp.Timestamp, TEST_NTLM_TIMESTAMP, 8);
-
AuthNtlmTimestamp.ChallengeOrResponse = TRUE;
client->table->SetContextAttributes(&client->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP,
- &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
-
+ &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
AuthNtlmTimestamp.ChallengeOrResponse = FALSE;
client->table->SetContextAttributes(&client->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP,
- &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
-
+ &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
CopyMemory(AuthNtlmClientChallenge.ClientChallenge, TEST_NTLM_CLIENT_CHALLENGE, 8);
CopyMemory(AuthNtlmServerChallenge.ServerChallenge, TEST_NTLM_SERVER_CHALLENGE, 8);
-
client->table->SetContextAttributes(&client->context, SECPKG_ATTR_AUTH_NTLM_CLIENT_CHALLENGE,
- &AuthNtlmClientChallenge, sizeof(SecPkgContext_AuthNtlmClientChallenge));
+ &AuthNtlmClientChallenge, sizeof(SecPkgContext_AuthNtlmClientChallenge));
client->table->SetContextAttributes(&client->context, SECPKG_ATTR_AUTH_NTLM_SERVER_CHALLENGE,
- &AuthNtlmServerChallenge, sizeof(SecPkgContext_AuthNtlmServerChallenge));
+ &AuthNtlmServerChallenge, sizeof(SecPkgContext_AuthNtlmServerChallenge));
}
pSecBuffer = &(client->outputBuffer[0]);
}
fprintf(stderr, "NTLM_NEGOTIATE (length = %d):\n", pSecBuffer->cbBuffer);
- winpr_HexDump((BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
-
+ winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
/**
* Server <- Negotiate Message
* Server -> Challenge Message
*/
-
server->haveInputBuffer = TRUE;
server->inputBuffer[0].BufferType = SECBUFFER_TOKEN;
server->inputBuffer[0].pvBuffer = pSecBuffer->pvBuffer;
server->inputBuffer[0].cbBuffer = pSecBuffer->cbBuffer;
-
status = test_ntlm_server_authenticate(server);
if (status < 0)
SecPkgContext_AuthNtlmTimestamp AuthNtlmTimestamp;
SecPkgContext_AuthNtlmClientChallenge AuthNtlmClientChallenge;
SecPkgContext_AuthNtlmServerChallenge AuthNtlmServerChallenge;
-
CopyMemory(AuthNtlmTimestamp.Timestamp, TEST_NTLM_TIMESTAMP, 8);
-
AuthNtlmTimestamp.ChallengeOrResponse = TRUE;
client->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP,
- &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
-
+ &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
AuthNtlmTimestamp.ChallengeOrResponse = FALSE;
client->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP,
- &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
-
+ &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
CopyMemory(AuthNtlmClientChallenge.ClientChallenge, TEST_NTLM_CLIENT_CHALLENGE, 8);
CopyMemory(AuthNtlmServerChallenge.ServerChallenge, TEST_NTLM_SERVER_CHALLENGE, 8);
-
server->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_CLIENT_CHALLENGE,
- &AuthNtlmClientChallenge, sizeof(SecPkgContext_AuthNtlmClientChallenge));
+ &AuthNtlmClientChallenge, sizeof(SecPkgContext_AuthNtlmClientChallenge));
server->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_SERVER_CHALLENGE,
- &AuthNtlmServerChallenge, sizeof(SecPkgContext_AuthNtlmServerChallenge));
+ &AuthNtlmServerChallenge, sizeof(SecPkgContext_AuthNtlmServerChallenge));
}
pSecBuffer = &(server->outputBuffer[0]);
if (!DynamicTest)
{
SecPkgContext_AuthNtlmMessage AuthNtlmMessage;
-
pSecBuffer->cbBuffer = sizeof(TEST_NTLM_CHALLENGE) -1;
pSecBuffer->pvBuffer = (void*) malloc(pSecBuffer->cbBuffer);
CopyMemory(pSecBuffer->pvBuffer, TEST_NTLM_CHALLENGE, pSecBuffer->cbBuffer);
-
AuthNtlmMessage.type = 2;
AuthNtlmMessage.length = pSecBuffer->cbBuffer;
AuthNtlmMessage.buffer = (BYTE*) pSecBuffer->pvBuffer;
-
server->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_MESSAGE,
- &AuthNtlmMessage, sizeof(SecPkgContext_AuthNtlmMessage));
+ &AuthNtlmMessage, sizeof(SecPkgContext_AuthNtlmMessage));
}
fprintf(stderr, "NTLM_CHALLENGE (length = %d):\n", pSecBuffer->cbBuffer);
- winpr_HexDump((BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
-
+ winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
/**
* Client <- Challenge Message
* Client -> Authenticate Message
*/
-
client->haveInputBuffer = TRUE;
client->inputBuffer[0].BufferType = SECBUFFER_TOKEN;
client->inputBuffer[0].pvBuffer = pSecBuffer->pvBuffer;
client->inputBuffer[0].cbBuffer = pSecBuffer->cbBuffer;
-
status = test_ntlm_client_authenticate(client);
if (status < 0)
}
pSecBuffer = &(client->outputBuffer[0]);
+
if (!DynamicTest)
{
pSecBuffer->cbBuffer = sizeof(TEST_NTLM_AUTHENTICATE) -1;
}
fprintf(stderr, "NTLM_AUTHENTICATE (length = %d):\n", pSecBuffer->cbBuffer);
- winpr_HexDump((BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
-
+ winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
/**
* Server <- Authenticate Message
*/
-
server->haveInputBuffer = TRUE;
server->inputBuffer[0].BufferType = SECBUFFER_TOKEN;
server->inputBuffer[0].pvBuffer = pSecBuffer->pvBuffer;
server->inputBuffer[0].cbBuffer = pSecBuffer->cbBuffer;
-
status = test_ntlm_server_authenticate(server);
if (status < 0)
/**
* Cleanup & Termination
*/
-
test_ntlm_client_free(client);
test_ntlm_server_free(server);
-
return 0;
}
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/crypto.h>
+#include <winpr/wlog.h>
#include <winpr/schannel.h>
BOOL g_ClientWait = FALSE;
BYTE test_localhost_crt[1029] =
{
- 0x2D,0x2D,0x2D,0x2D,0x2D,0x42,0x45,0x47,0x49,0x4E,0x20,0x43,0x45,0x52,0x54,
- 0x49,0x46,0x49,0x43,0x41,0x54,0x45,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,0x4D,0x49,
- 0x49,0x43,0x79,0x6A,0x43,0x43,0x41,0x62,0x4B,0x67,0x41,0x77,0x49,0x42,0x41,
- 0x67,0x49,0x45,0x63,0x61,0x64,0x63,0x72,0x7A,0x41,0x4E,0x42,0x67,0x6B,0x71,
- 0x68,0x6B,0x69,0x47,0x39,0x77,0x30,0x42,0x41,0x51,0x55,0x46,0x41,0x44,0x41,
- 0x55,0x4D,0x52,0x49,0x77,0x45,0x41,0x59,0x44,0x56,0x51,0x51,0x44,0x45,0x77,
- 0x6C,0x73,0x0A,0x62,0x32,0x4E,0x68,0x62,0x47,0x68,0x76,0x63,0x33,0x51,0x77,
- 0x48,0x68,0x63,0x4E,0x4D,0x54,0x4D,0x78,0x4D,0x44,0x45,0x78,0x4D,0x44,0x59,
- 0x78,0x4E,0x7A,0x55,0x31,0x57,0x68,0x63,0x4E,0x4D,0x54,0x51,0x78,0x4D,0x44,
- 0x45,0x78,0x4D,0x44,0x59,0x78,0x4E,0x7A,0x55,0x31,0x57,0x6A,0x41,0x55,0x4D,
- 0x52,0x49,0x77,0x45,0x41,0x59,0x44,0x0A,0x56,0x51,0x51,0x44,0x45,0x77,0x6C,
- 0x73,0x62,0x32,0x4E,0x68,0x62,0x47,0x68,0x76,0x63,0x33,0x51,0x77,0x67,0x67,
- 0x45,0x69,0x4D,0x41,0x30,0x47,0x43,0x53,0x71,0x47,0x53,0x49,0x62,0x33,0x44,
- 0x51,0x45,0x42,0x41,0x51,0x55,0x41,0x41,0x34,0x49,0x42,0x44,0x77,0x41,0x77,
- 0x67,0x67,0x45,0x4B,0x41,0x6F,0x49,0x42,0x41,0x51,0x43,0x33,0x0A,0x65,0x6E,
- 0x33,0x68,0x5A,0x4F,0x53,0x33,0x6B,0x51,0x2F,0x55,0x54,0x30,0x53,0x45,0x6C,
- 0x30,0x48,0x6E,0x50,0x79,0x64,0x48,0x75,0x35,0x39,0x61,0x69,0x71,0x64,0x73,
- 0x64,0x53,0x55,0x74,0x6E,0x43,0x41,0x37,0x46,0x66,0x74,0x30,0x4F,0x36,0x51,
- 0x79,0x68,0x49,0x71,0x58,0x7A,0x30,0x47,0x32,0x53,0x76,0x77,0x4C,0x54,0x62,
- 0x79,0x68,0x0A,0x59,0x54,0x68,0x31,0x36,0x78,0x31,0x72,0x45,0x48,0x68,0x31,
- 0x57,0x47,0x5A,0x6D,0x36,0x77,0x64,0x2B,0x4B,0x76,0x38,0x6B,0x31,0x6B,0x2F,
- 0x36,0x6F,0x41,0x2F,0x4F,0x51,0x76,0x65,0x61,0x38,0x6B,0x63,0x45,0x64,0x53,
- 0x72,0x54,0x64,0x75,0x71,0x4A,0x33,0x65,0x66,0x74,0x48,0x4A,0x4A,0x6E,0x43,
- 0x4B,0x30,0x41,0x62,0x68,0x34,0x39,0x0A,0x41,0x47,0x41,0x50,0x39,0x79,0x58,
- 0x77,0x77,0x59,0x41,0x6A,0x51,0x49,0x52,0x6E,0x38,0x2B,0x4F,0x63,0x63,0x48,
- 0x74,0x6F,0x4E,0x75,0x75,0x79,0x52,0x63,0x6B,0x49,0x50,0x71,0x75,0x70,0x78,
- 0x79,0x31,0x4A,0x5A,0x4B,0x39,0x64,0x76,0x76,0x62,0x34,0x79,0x53,0x6B,0x49,
- 0x75,0x7A,0x62,0x79,0x50,0x6F,0x54,0x41,0x79,0x61,0x55,0x2B,0x0A,0x51,0x72,
- 0x70,0x34,0x78,0x67,0x64,0x4B,0x46,0x54,0x70,0x6B,0x50,0x46,0x34,0x33,0x6A,
- 0x32,0x4D,0x6D,0x5A,0x72,0x46,0x63,0x42,0x76,0x79,0x6A,0x69,0x35,0x6A,0x4F,
- 0x37,0x74,0x66,0x6F,0x56,0x61,0x6B,0x59,0x47,0x53,0x2F,0x4C,0x63,0x78,0x77,
- 0x47,0x2B,0x77,0x51,0x77,0x63,0x4F,0x43,0x54,0x42,0x45,0x78,0x2F,0x7A,0x31,
- 0x53,0x30,0x0A,0x37,0x49,0x2F,0x6A,0x62,0x44,0x79,0x53,0x4E,0x68,0x44,0x35,
- 0x63,0x61,0x63,0x54,0x75,0x4E,0x36,0x50,0x68,0x33,0x58,0x30,0x71,0x70,0x47,
- 0x73,0x37,0x79,0x50,0x6B,0x4E,0x79,0x69,0x4A,0x33,0x57,0x52,0x69,0x6C,0x35,
- 0x75,0x57,0x73,0x4B,0x65,0x79,0x63,0x64,0x71,0x42,0x4E,0x72,0x34,0x75,0x32,
- 0x62,0x49,0x52,0x6E,0x63,0x54,0x51,0x0A,0x46,0x72,0x68,0x73,0x58,0x39,0x69,
- 0x77,0x37,0x35,0x76,0x75,0x53,0x64,0x35,0x46,0x39,0x37,0x56,0x70,0x41,0x67,
- 0x4D,0x42,0x41,0x41,0x47,0x6A,0x4A,0x44,0x41,0x69,0x4D,0x42,0x4D,0x47,0x41,
- 0x31,0x55,0x64,0x4A,0x51,0x51,0x4D,0x4D,0x41,0x6F,0x47,0x43,0x43,0x73,0x47,
- 0x41,0x51,0x55,0x46,0x42,0x77,0x4D,0x42,0x4D,0x41,0x73,0x47,0x0A,0x41,0x31,
- 0x55,0x64,0x44,0x77,0x51,0x45,0x41,0x77,0x49,0x45,0x4D,0x44,0x41,0x4E,0x42,
- 0x67,0x6B,0x71,0x68,0x6B,0x69,0x47,0x39,0x77,0x30,0x42,0x41,0x51,0x55,0x46,
- 0x41,0x41,0x4F,0x43,0x41,0x51,0x45,0x41,0x49,0x51,0x66,0x75,0x2F,0x77,0x39,
- 0x45,0x34,0x4C,0x6F,0x67,0x30,0x71,0x35,0x4B,0x53,0x38,0x71,0x46,0x78,0x62,
- 0x36,0x6F,0x0A,0x36,0x31,0x62,0x35,0x37,0x6F,0x6D,0x6E,0x46,0x59,0x52,0x34,
- 0x47,0x43,0x67,0x33,0x6F,0x6A,0x4F,0x4C,0x54,0x66,0x38,0x7A,0x6A,0x4D,0x43,
- 0x52,0x6D,0x75,0x59,0x32,0x76,0x30,0x4E,0x34,0x78,0x66,0x68,0x69,0x35,0x4B,
- 0x69,0x59,0x67,0x64,0x76,0x4E,0x4C,0x4F,0x33,0x52,0x42,0x6D,0x4E,0x50,0x76,
- 0x59,0x58,0x50,0x52,0x46,0x41,0x76,0x0A,0x66,0x61,0x76,0x66,0x57,0x75,0x6C,
- 0x44,0x31,0x64,0x50,0x36,0x31,0x69,0x35,0x62,0x36,0x59,0x66,0x56,0x6C,0x78,
- 0x62,0x31,0x61,0x57,0x46,0x37,0x4C,0x5A,0x44,0x32,0x55,0x6E,0x63,0x41,0x6A,
- 0x37,0x4E,0x38,0x78,0x38,0x2B,0x36,0x58,0x6B,0x30,0x6B,0x63,0x70,0x58,0x46,
- 0x38,0x6C,0x77,0x58,0x48,0x55,0x57,0x57,0x55,0x6D,0x73,0x2B,0x0A,0x4B,0x56,
- 0x44,0x34,0x34,0x39,0x68,0x6F,0x4D,0x2B,0x77,0x4E,0x4A,0x49,0x61,0x4F,0x52,
- 0x39,0x4C,0x46,0x2B,0x6B,0x6F,0x32,0x32,0x37,0x7A,0x74,0x37,0x54,0x41,0x47,
- 0x64,0x56,0x35,0x4A,0x75,0x7A,0x71,0x38,0x32,0x2F,0x6B,0x75,0x73,0x6F,0x65,
- 0x32,0x69,0x75,0x57,0x77,0x54,0x65,0x42,0x6C,0x53,0x5A,0x6E,0x6B,0x42,0x38,
- 0x63,0x64,0x0A,0x77,0x4D,0x30,0x5A,0x42,0x58,0x6D,0x34,0x35,0x48,0x38,0x6F,
- 0x79,0x75,0x36,0x4A,0x71,0x59,0x71,0x45,0x6D,0x75,0x4A,0x51,0x64,0x67,0x79,
- 0x52,0x2B,0x63,0x53,0x53,0x41,0x7A,0x2B,0x4F,0x32,0x6D,0x61,0x62,0x68,0x50,
- 0x5A,0x65,0x49,0x76,0x78,0x65,0x67,0x6A,0x6A,0x61,0x5A,0x61,0x46,0x4F,0x71,
- 0x74,0x73,0x2B,0x64,0x33,0x72,0x39,0x0A,0x79,0x71,0x4A,0x78,0x67,0x75,0x39,
- 0x43,0x38,0x39,0x5A,0x69,0x33,0x39,0x57,0x34,0x38,0x46,0x66,0x46,0x63,0x49,
- 0x58,0x4A,0x4F,0x6B,0x39,0x43,0x4E,0x46,0x41,0x2F,0x69,0x70,0x54,0x57,0x6A,
- 0x74,0x74,0x4E,0x2F,0x6B,0x4F,0x6B,0x5A,0x42,0x70,0x6F,0x6A,0x2F,0x32,0x6A,
- 0x4E,0x45,0x62,0x4F,0x59,0x7A,0x7A,0x6E,0x4B,0x77,0x3D,0x3D,0x0A,0x2D,0x2D,
- 0x2D,0x2D,0x2D,0x45,0x4E,0x44,0x20,0x43,0x45,0x52,0x54,0x49,0x46,0x49,0x43,
- 0x41,0x54,0x45,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x42,0x45,0x47,0x49,0x4E,0x20,0x43,0x45,0x52,0x54,
+ 0x49,0x46,0x49,0x43,0x41,0x54,0x45,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,0x4D,0x49,
+ 0x49,0x43,0x79,0x6A,0x43,0x43,0x41,0x62,0x4B,0x67,0x41,0x77,0x49,0x42,0x41,
+ 0x67,0x49,0x45,0x63,0x61,0x64,0x63,0x72,0x7A,0x41,0x4E,0x42,0x67,0x6B,0x71,
+ 0x68,0x6B,0x69,0x47,0x39,0x77,0x30,0x42,0x41,0x51,0x55,0x46,0x41,0x44,0x41,
+ 0x55,0x4D,0x52,0x49,0x77,0x45,0x41,0x59,0x44,0x56,0x51,0x51,0x44,0x45,0x77,
+ 0x6C,0x73,0x0A,0x62,0x32,0x4E,0x68,0x62,0x47,0x68,0x76,0x63,0x33,0x51,0x77,
+ 0x48,0x68,0x63,0x4E,0x4D,0x54,0x4D,0x78,0x4D,0x44,0x45,0x78,0x4D,0x44,0x59,
+ 0x78,0x4E,0x7A,0x55,0x31,0x57,0x68,0x63,0x4E,0x4D,0x54,0x51,0x78,0x4D,0x44,
+ 0x45,0x78,0x4D,0x44,0x59,0x78,0x4E,0x7A,0x55,0x31,0x57,0x6A,0x41,0x55,0x4D,
+ 0x52,0x49,0x77,0x45,0x41,0x59,0x44,0x0A,0x56,0x51,0x51,0x44,0x45,0x77,0x6C,
+ 0x73,0x62,0x32,0x4E,0x68,0x62,0x47,0x68,0x76,0x63,0x33,0x51,0x77,0x67,0x67,
+ 0x45,0x69,0x4D,0x41,0x30,0x47,0x43,0x53,0x71,0x47,0x53,0x49,0x62,0x33,0x44,
+ 0x51,0x45,0x42,0x41,0x51,0x55,0x41,0x41,0x34,0x49,0x42,0x44,0x77,0x41,0x77,
+ 0x67,0x67,0x45,0x4B,0x41,0x6F,0x49,0x42,0x41,0x51,0x43,0x33,0x0A,0x65,0x6E,
+ 0x33,0x68,0x5A,0x4F,0x53,0x33,0x6B,0x51,0x2F,0x55,0x54,0x30,0x53,0x45,0x6C,
+ 0x30,0x48,0x6E,0x50,0x79,0x64,0x48,0x75,0x35,0x39,0x61,0x69,0x71,0x64,0x73,
+ 0x64,0x53,0x55,0x74,0x6E,0x43,0x41,0x37,0x46,0x66,0x74,0x30,0x4F,0x36,0x51,
+ 0x79,0x68,0x49,0x71,0x58,0x7A,0x30,0x47,0x32,0x53,0x76,0x77,0x4C,0x54,0x62,
+ 0x79,0x68,0x0A,0x59,0x54,0x68,0x31,0x36,0x78,0x31,0x72,0x45,0x48,0x68,0x31,
+ 0x57,0x47,0x5A,0x6D,0x36,0x77,0x64,0x2B,0x4B,0x76,0x38,0x6B,0x31,0x6B,0x2F,
+ 0x36,0x6F,0x41,0x2F,0x4F,0x51,0x76,0x65,0x61,0x38,0x6B,0x63,0x45,0x64,0x53,
+ 0x72,0x54,0x64,0x75,0x71,0x4A,0x33,0x65,0x66,0x74,0x48,0x4A,0x4A,0x6E,0x43,
+ 0x4B,0x30,0x41,0x62,0x68,0x34,0x39,0x0A,0x41,0x47,0x41,0x50,0x39,0x79,0x58,
+ 0x77,0x77,0x59,0x41,0x6A,0x51,0x49,0x52,0x6E,0x38,0x2B,0x4F,0x63,0x63,0x48,
+ 0x74,0x6F,0x4E,0x75,0x75,0x79,0x52,0x63,0x6B,0x49,0x50,0x71,0x75,0x70,0x78,
+ 0x79,0x31,0x4A,0x5A,0x4B,0x39,0x64,0x76,0x76,0x62,0x34,0x79,0x53,0x6B,0x49,
+ 0x75,0x7A,0x62,0x79,0x50,0x6F,0x54,0x41,0x79,0x61,0x55,0x2B,0x0A,0x51,0x72,
+ 0x70,0x34,0x78,0x67,0x64,0x4B,0x46,0x54,0x70,0x6B,0x50,0x46,0x34,0x33,0x6A,
+ 0x32,0x4D,0x6D,0x5A,0x72,0x46,0x63,0x42,0x76,0x79,0x6A,0x69,0x35,0x6A,0x4F,
+ 0x37,0x74,0x66,0x6F,0x56,0x61,0x6B,0x59,0x47,0x53,0x2F,0x4C,0x63,0x78,0x77,
+ 0x47,0x2B,0x77,0x51,0x77,0x63,0x4F,0x43,0x54,0x42,0x45,0x78,0x2F,0x7A,0x31,
+ 0x53,0x30,0x0A,0x37,0x49,0x2F,0x6A,0x62,0x44,0x79,0x53,0x4E,0x68,0x44,0x35,
+ 0x63,0x61,0x63,0x54,0x75,0x4E,0x36,0x50,0x68,0x33,0x58,0x30,0x71,0x70,0x47,
+ 0x73,0x37,0x79,0x50,0x6B,0x4E,0x79,0x69,0x4A,0x33,0x57,0x52,0x69,0x6C,0x35,
+ 0x75,0x57,0x73,0x4B,0x65,0x79,0x63,0x64,0x71,0x42,0x4E,0x72,0x34,0x75,0x32,
+ 0x62,0x49,0x52,0x6E,0x63,0x54,0x51,0x0A,0x46,0x72,0x68,0x73,0x58,0x39,0x69,
+ 0x77,0x37,0x35,0x76,0x75,0x53,0x64,0x35,0x46,0x39,0x37,0x56,0x70,0x41,0x67,
+ 0x4D,0x42,0x41,0x41,0x47,0x6A,0x4A,0x44,0x41,0x69,0x4D,0x42,0x4D,0x47,0x41,
+ 0x31,0x55,0x64,0x4A,0x51,0x51,0x4D,0x4D,0x41,0x6F,0x47,0x43,0x43,0x73,0x47,
+ 0x41,0x51,0x55,0x46,0x42,0x77,0x4D,0x42,0x4D,0x41,0x73,0x47,0x0A,0x41,0x31,
+ 0x55,0x64,0x44,0x77,0x51,0x45,0x41,0x77,0x49,0x45,0x4D,0x44,0x41,0x4E,0x42,
+ 0x67,0x6B,0x71,0x68,0x6B,0x69,0x47,0x39,0x77,0x30,0x42,0x41,0x51,0x55,0x46,
+ 0x41,0x41,0x4F,0x43,0x41,0x51,0x45,0x41,0x49,0x51,0x66,0x75,0x2F,0x77,0x39,
+ 0x45,0x34,0x4C,0x6F,0x67,0x30,0x71,0x35,0x4B,0x53,0x38,0x71,0x46,0x78,0x62,
+ 0x36,0x6F,0x0A,0x36,0x31,0x62,0x35,0x37,0x6F,0x6D,0x6E,0x46,0x59,0x52,0x34,
+ 0x47,0x43,0x67,0x33,0x6F,0x6A,0x4F,0x4C,0x54,0x66,0x38,0x7A,0x6A,0x4D,0x43,
+ 0x52,0x6D,0x75,0x59,0x32,0x76,0x30,0x4E,0x34,0x78,0x66,0x68,0x69,0x35,0x4B,
+ 0x69,0x59,0x67,0x64,0x76,0x4E,0x4C,0x4F,0x33,0x52,0x42,0x6D,0x4E,0x50,0x76,
+ 0x59,0x58,0x50,0x52,0x46,0x41,0x76,0x0A,0x66,0x61,0x76,0x66,0x57,0x75,0x6C,
+ 0x44,0x31,0x64,0x50,0x36,0x31,0x69,0x35,0x62,0x36,0x59,0x66,0x56,0x6C,0x78,
+ 0x62,0x31,0x61,0x57,0x46,0x37,0x4C,0x5A,0x44,0x32,0x55,0x6E,0x63,0x41,0x6A,
+ 0x37,0x4E,0x38,0x78,0x38,0x2B,0x36,0x58,0x6B,0x30,0x6B,0x63,0x70,0x58,0x46,
+ 0x38,0x6C,0x77,0x58,0x48,0x55,0x57,0x57,0x55,0x6D,0x73,0x2B,0x0A,0x4B,0x56,
+ 0x44,0x34,0x34,0x39,0x68,0x6F,0x4D,0x2B,0x77,0x4E,0x4A,0x49,0x61,0x4F,0x52,
+ 0x39,0x4C,0x46,0x2B,0x6B,0x6F,0x32,0x32,0x37,0x7A,0x74,0x37,0x54,0x41,0x47,
+ 0x64,0x56,0x35,0x4A,0x75,0x7A,0x71,0x38,0x32,0x2F,0x6B,0x75,0x73,0x6F,0x65,
+ 0x32,0x69,0x75,0x57,0x77,0x54,0x65,0x42,0x6C,0x53,0x5A,0x6E,0x6B,0x42,0x38,
+ 0x63,0x64,0x0A,0x77,0x4D,0x30,0x5A,0x42,0x58,0x6D,0x34,0x35,0x48,0x38,0x6F,
+ 0x79,0x75,0x36,0x4A,0x71,0x59,0x71,0x45,0x6D,0x75,0x4A,0x51,0x64,0x67,0x79,
+ 0x52,0x2B,0x63,0x53,0x53,0x41,0x7A,0x2B,0x4F,0x32,0x6D,0x61,0x62,0x68,0x50,
+ 0x5A,0x65,0x49,0x76,0x78,0x65,0x67,0x6A,0x6A,0x61,0x5A,0x61,0x46,0x4F,0x71,
+ 0x74,0x73,0x2B,0x64,0x33,0x72,0x39,0x0A,0x79,0x71,0x4A,0x78,0x67,0x75,0x39,
+ 0x43,0x38,0x39,0x5A,0x69,0x33,0x39,0x57,0x34,0x38,0x46,0x66,0x46,0x63,0x49,
+ 0x58,0x4A,0x4F,0x6B,0x39,0x43,0x4E,0x46,0x41,0x2F,0x69,0x70,0x54,0x57,0x6A,
+ 0x74,0x74,0x4E,0x2F,0x6B,0x4F,0x6B,0x5A,0x42,0x70,0x6F,0x6A,0x2F,0x32,0x6A,
+ 0x4E,0x45,0x62,0x4F,0x59,0x7A,0x7A,0x6E,0x4B,0x77,0x3D,0x3D,0x0A,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x45,0x4E,0x44,0x20,0x43,0x45,0x52,0x54,0x49,0x46,0x49,0x43,
+ 0x41,0x54,0x45,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A
};
BYTE test_localhost_key[1704] =
{
- 0x2D,0x2D,0x2D,0x2D,0x2D,0x42,0x45,0x47,0x49,0x4E,0x20,0x50,0x52,0x49,0x56,
- 0x41,0x54,0x45,0x20,0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,0x4D,0x49,
- 0x49,0x45,0x76,0x51,0x49,0x42,0x41,0x44,0x41,0x4E,0x42,0x67,0x6B,0x71,0x68,
- 0x6B,0x69,0x47,0x39,0x77,0x30,0x42,0x41,0x51,0x45,0x46,0x41,0x41,0x53,0x43,
- 0x42,0x4B,0x63,0x77,0x67,0x67,0x53,0x6A,0x41,0x67,0x45,0x41,0x41,0x6F,0x49,
- 0x42,0x41,0x51,0x43,0x33,0x65,0x6E,0x33,0x68,0x5A,0x4F,0x53,0x33,0x6B,0x51,
- 0x2F,0x55,0x0A,0x54,0x30,0x53,0x45,0x6C,0x30,0x48,0x6E,0x50,0x79,0x64,0x48,
- 0x75,0x35,0x39,0x61,0x69,0x71,0x64,0x73,0x64,0x53,0x55,0x74,0x6E,0x43,0x41,
- 0x37,0x46,0x66,0x74,0x30,0x4F,0x36,0x51,0x79,0x68,0x49,0x71,0x58,0x7A,0x30,
- 0x47,0x32,0x53,0x76,0x77,0x4C,0x54,0x62,0x79,0x68,0x59,0x54,0x68,0x31,0x36,
- 0x78,0x31,0x72,0x45,0x48,0x68,0x31,0x0A,0x57,0x47,0x5A,0x6D,0x36,0x77,0x64,
- 0x2B,0x4B,0x76,0x38,0x6B,0x31,0x6B,0x2F,0x36,0x6F,0x41,0x2F,0x4F,0x51,0x76,
- 0x65,0x61,0x38,0x6B,0x63,0x45,0x64,0x53,0x72,0x54,0x64,0x75,0x71,0x4A,0x33,
- 0x65,0x66,0x74,0x48,0x4A,0x4A,0x6E,0x43,0x4B,0x30,0x41,0x62,0x68,0x34,0x39,
- 0x41,0x47,0x41,0x50,0x39,0x79,0x58,0x77,0x77,0x59,0x41,0x6A,0x0A,0x51,0x49,
- 0x52,0x6E,0x38,0x2B,0x4F,0x63,0x63,0x48,0x74,0x6F,0x4E,0x75,0x75,0x79,0x52,
- 0x63,0x6B,0x49,0x50,0x71,0x75,0x70,0x78,0x79,0x31,0x4A,0x5A,0x4B,0x39,0x64,
- 0x76,0x76,0x62,0x34,0x79,0x53,0x6B,0x49,0x75,0x7A,0x62,0x79,0x50,0x6F,0x54,
- 0x41,0x79,0x61,0x55,0x2B,0x51,0x72,0x70,0x34,0x78,0x67,0x64,0x4B,0x46,0x54,
- 0x70,0x6B,0x0A,0x50,0x46,0x34,0x33,0x6A,0x32,0x4D,0x6D,0x5A,0x72,0x46,0x63,
- 0x42,0x76,0x79,0x6A,0x69,0x35,0x6A,0x4F,0x37,0x74,0x66,0x6F,0x56,0x61,0x6B,
- 0x59,0x47,0x53,0x2F,0x4C,0x63,0x78,0x77,0x47,0x2B,0x77,0x51,0x77,0x63,0x4F,
- 0x43,0x54,0x42,0x45,0x78,0x2F,0x7A,0x31,0x53,0x30,0x37,0x49,0x2F,0x6A,0x62,
- 0x44,0x79,0x53,0x4E,0x68,0x44,0x35,0x0A,0x63,0x61,0x63,0x54,0x75,0x4E,0x36,
- 0x50,0x68,0x33,0x58,0x30,0x71,0x70,0x47,0x73,0x37,0x79,0x50,0x6B,0x4E,0x79,
- 0x69,0x4A,0x33,0x57,0x52,0x69,0x6C,0x35,0x75,0x57,0x73,0x4B,0x65,0x79,0x63,
- 0x64,0x71,0x42,0x4E,0x72,0x34,0x75,0x32,0x62,0x49,0x52,0x6E,0x63,0x54,0x51,
- 0x46,0x72,0x68,0x73,0x58,0x39,0x69,0x77,0x37,0x35,0x76,0x75,0x0A,0x53,0x64,
- 0x35,0x46,0x39,0x37,0x56,0x70,0x41,0x67,0x4D,0x42,0x41,0x41,0x45,0x43,0x67,
- 0x67,0x45,0x41,0x42,0x36,0x6A,0x6C,0x65,0x48,0x4E,0x74,0x32,0x50,0x77,0x46,
- 0x58,0x53,0x65,0x79,0x42,0x4A,0x63,0x4C,0x2B,0x55,0x74,0x35,0x71,0x46,0x54,
- 0x38,0x34,0x68,0x72,0x48,0x77,0x6F,0x39,0x68,0x62,0x66,0x59,0x47,0x6F,0x6E,
- 0x44,0x59,0x0A,0x66,0x70,0x47,0x2B,0x32,0x52,0x30,0x50,0x62,0x43,0x63,0x4B,
- 0x35,0x30,0x46,0x61,0x4A,0x46,0x36,0x71,0x63,0x56,0x4A,0x4E,0x75,0x52,0x36,
- 0x48,0x71,0x2B,0x43,0x55,0x4A,0x74,0x48,0x35,0x39,0x48,0x48,0x37,0x62,0x68,
- 0x6A,0x39,0x62,0x64,0x78,0x45,0x6D,0x6F,0x48,0x30,0x4A,0x76,0x68,0x45,0x76,
- 0x67,0x4D,0x2F,0x55,0x38,0x42,0x51,0x0A,0x65,0x57,0x4F,0x4E,0x68,0x78,0x50,
- 0x73,0x69,0x73,0x6D,0x57,0x6B,0x78,0x61,0x5A,0x6F,0x6C,0x72,0x32,0x69,0x44,
- 0x56,0x72,0x7A,0x54,0x37,0x55,0x4A,0x71,0x6A,0x74,0x59,0x49,0x74,0x67,0x2B,
- 0x37,0x59,0x43,0x32,0x70,0x55,0x58,0x6B,0x64,0x49,0x35,0x4A,0x4D,0x67,0x6C,
- 0x44,0x47,0x4D,0x52,0x5A,0x35,0x55,0x5A,0x48,0x75,0x63,0x7A,0x0A,0x41,0x56,
- 0x2B,0x71,0x77,0x77,0x33,0x65,0x45,0x52,0x74,0x78,0x44,0x50,0x61,0x61,0x61,
- 0x34,0x54,0x39,0x50,0x64,0x33,0x44,0x31,0x6D,0x62,0x71,0x58,0x66,0x75,0x45,
- 0x68,0x42,0x6D,0x33,0x51,0x6F,0x2B,0x75,0x7A,0x51,0x32,0x36,0x76,0x73,0x66,
- 0x48,0x75,0x56,0x76,0x61,0x39,0x38,0x32,0x4F,0x6A,0x41,0x55,0x6A,0x6E,0x64,
- 0x30,0x70,0x0A,0x77,0x43,0x53,0x6E,0x42,0x49,0x48,0x67,0x70,0x73,0x30,0x79,
- 0x61,0x45,0x50,0x63,0x37,0x46,0x78,0x39,0x71,0x45,0x63,0x6D,0x33,0x70,0x7A,
- 0x41,0x56,0x31,0x69,0x72,0x31,0x4E,0x4E,0x63,0x51,0x47,0x55,0x45,0x75,0x45,
- 0x6C,0x4A,0x78,0x76,0x2B,0x69,0x57,0x34,0x6D,0x35,0x70,0x7A,0x4C,0x6A,0x64,
- 0x53,0x63,0x49,0x30,0x59,0x45,0x73,0x0A,0x4D,0x61,0x33,0x78,0x32,0x79,0x48,
- 0x74,0x6E,0x77,0x79,0x65,0x4C,0x4D,0x54,0x4B,0x6C,0x72,0x46,0x4B,0x70,0x55,
- 0x4E,0x4A,0x62,0x78,0x73,0x35,0x32,0x62,0x5A,0x4B,0x71,0x49,0x56,0x33,0x33,
- 0x4A,0x53,0x34,0x41,0x51,0x4B,0x42,0x67,0x51,0x44,0x73,0x4C,0x54,0x49,0x68,
- 0x35,0x59,0x38,0x4C,0x2F,0x48,0x33,0x64,0x74,0x68,0x63,0x62,0x0A,0x53,0x43,
- 0x45,0x77,0x32,0x64,0x42,0x49,0x76,0x49,0x79,0x54,0x7A,0x39,0x53,0x72,0x62,
- 0x33,0x58,0x37,0x37,0x41,0x77,0x57,0x45,0x4C,0x53,0x4D,0x49,0x57,0x53,0x50,
- 0x55,0x43,0x4B,0x54,0x49,0x70,0x6A,0x4D,0x73,0x6E,0x7A,0x6B,0x46,0x67,0x32,
- 0x32,0x59,0x32,0x53,0x75,0x47,0x38,0x4C,0x72,0x50,0x6D,0x76,0x73,0x46,0x4A,
- 0x34,0x30,0x0A,0x32,0x67,0x35,0x44,0x55,0x6C,0x59,0x33,0x59,0x6D,0x53,0x4F,
- 0x46,0x61,0x45,0x4A,0x54,0x70,0x55,0x47,0x44,0x4D,0x79,0x65,0x33,0x74,0x36,
- 0x4F,0x30,0x6C,0x63,0x51,0x41,0x66,0x79,0x6D,0x58,0x66,0x41,0x38,0x74,0x50,
- 0x42,0x48,0x6A,0x5A,0x78,0x56,0x61,0x38,0x78,0x78,0x52,0x5A,0x6E,0x56,0x43,
- 0x31,0x41,0x62,0x75,0x49,0x49,0x52,0x0A,0x6E,0x77,0x72,0x4E,0x46,0x2B,0x42,
- 0x6F,0x53,0x4B,0x55,0x41,0x73,0x78,0x2B,0x46,0x75,0x35,0x5A,0x4A,0x4B,0x4F,
- 0x66,0x79,0x4D,0x51,0x4B,0x42,0x67,0x51,0x44,0x47,0x34,0x50,0x52,0x39,0x2F,
- 0x58,0x58,0x6B,0x51,0x54,0x36,0x6B,0x7A,0x4B,0x64,0x34,0x50,0x6C,0x50,0x4D,
- 0x63,0x2B,0x4B,0x51,0x79,0x4C,0x45,0x6C,0x4B,0x39,0x71,0x47,0x0A,0x41,0x6D,
- 0x6E,0x2F,0x31,0x68,0x64,0x69,0x57,0x57,0x4F,0x52,0x57,0x46,0x62,0x32,0x38,
- 0x30,0x4D,0x77,0x76,0x77,0x41,0x64,0x78,0x72,0x66,0x65,0x4C,0x57,0x4D,0x57,
- 0x32,0x66,0x76,0x4C,0x59,0x4B,0x66,0x6C,0x4F,0x35,0x50,0x51,0x44,0x59,0x67,
- 0x4B,0x4A,0x78,0x35,0x79,0x50,0x37,0x52,0x64,0x38,0x2F,0x64,0x50,0x79,0x5A,
- 0x59,0x36,0x0A,0x7A,0x56,0x37,0x47,0x47,0x6B,0x51,0x5A,0x42,0x4B,0x36,0x79,
- 0x74,0x61,0x66,0x32,0x35,0x44,0x50,0x67,0x50,0x72,0x32,0x77,0x73,0x59,0x4D,
- 0x43,0x6C,0x53,0x74,0x6C,0x56,0x74,0x72,0x6D,0x4F,0x78,0x59,0x55,0x56,0x77,
- 0x42,0x59,0x4F,0x69,0x36,0x45,0x62,0x50,0x69,0x6B,0x78,0x47,0x48,0x5A,0x70,
- 0x59,0x6F,0x5A,0x5A,0x70,0x68,0x4A,0x0A,0x4E,0x61,0x38,0x4F,0x4C,0x31,0x69,
- 0x77,0x75,0x51,0x4B,0x42,0x67,0x51,0x44,0x42,0x55,0x55,0x31,0x54,0x79,0x5A,
- 0x2B,0x4A,0x5A,0x43,0x64,0x79,0x72,0x33,0x58,0x43,0x63,0x77,0x77,0x58,0x2F,
- 0x48,0x49,0x73,0x31,0x34,0x6B,0x4B,0x42,0x48,0x68,0x44,0x79,0x33,0x78,0x37,
- 0x74,0x50,0x38,0x2F,0x6F,0x48,0x54,0x6F,0x72,0x76,0x79,0x74,0x0A,0x41,0x68,
- 0x38,0x4B,0x36,0x4B,0x72,0x43,0x41,0x75,0x65,0x50,0x6D,0x79,0x32,0x6D,0x4F,
- 0x54,0x31,0x54,0x39,0x6F,0x31,0x61,0x47,0x55,0x49,0x6C,0x66,0x38,0x72,0x76,
- 0x33,0x2F,0x30,0x45,0x78,0x67,0x53,0x6B,0x57,0x50,0x6D,0x4F,0x41,0x38,0x35,
- 0x49,0x32,0x2F,0x58,0x48,0x65,0x66,0x71,0x54,0x6F,0x45,0x48,0x30,0x44,0x65,
- 0x41,0x4E,0x0A,0x7A,0x6C,0x4B,0x4C,0x71,0x79,0x44,0x56,0x30,0x42,0x56,0x4E,
- 0x76,0x48,0x42,0x57,0x79,0x32,0x49,0x51,0x35,0x62,0x50,0x42,0x57,0x76,0x30,
- 0x37,0x63,0x34,0x2B,0x6A,0x39,0x4E,0x62,0x57,0x67,0x64,0x44,0x43,0x43,0x35,
- 0x52,0x6B,0x4F,0x6A,0x70,0x33,0x4D,0x4E,0x45,0x58,0x47,0x56,0x43,0x69,0x51,
- 0x51,0x4B,0x42,0x67,0x43,0x7A,0x4D,0x0A,0x77,0x65,0x61,0x62,0x73,0x50,0x48,
- 0x68,0x44,0x4B,0x5A,0x38,0x2F,0x34,0x43,0x6A,0x73,0x61,0x62,0x4E,0x75,0x41,
- 0x7A,0x62,0x57,0x4B,0x52,0x42,0x38,0x37,0x44,0x61,0x58,0x46,0x78,0x6F,0x4D,
- 0x73,0x35,0x52,0x79,0x6F,0x38,0x55,0x4D,0x6B,0x72,0x67,0x30,0x35,0x4C,0x6F,
- 0x67,0x37,0x4D,0x78,0x62,0x33,0x76,0x61,0x42,0x34,0x63,0x2F,0x0A,0x52,0x57,
- 0x77,0x7A,0x38,0x72,0x34,0x39,0x70,0x48,0x64,0x71,0x68,0x4F,0x6D,0x63,0x6C,
- 0x45,0x77,0x79,0x4D,0x34,0x51,0x79,0x6A,0x39,0x52,0x6D,0x57,0x62,0x51,0x58,
- 0x54,0x54,0x45,0x63,0x2B,0x35,0x67,0x54,0x4B,0x50,0x4E,0x53,0x33,0x6D,0x70,
- 0x4D,0x54,0x36,0x39,0x46,0x45,0x74,0x2F,0x35,0x72,0x4D,0x52,0x70,0x4B,0x2B,
- 0x52,0x68,0x0A,0x49,0x32,0x42,0x58,0x6B,0x51,0x71,0x31,0x36,0x6E,0x72,0x31,
- 0x61,0x45,0x4D,0x6D,0x64,0x51,0x42,0x51,0x79,0x4B,0x59,0x4A,0x6C,0x30,0x6C,
- 0x50,0x68,0x69,0x42,0x2F,0x75,0x6C,0x5A,0x63,0x72,0x67,0x4C,0x70,0x41,0x6F,
- 0x47,0x41,0x65,0x30,0x65,0x74,0x50,0x4A,0x77,0x6D,0x51,0x46,0x6B,0x6A,0x4D,
- 0x70,0x66,0x4D,0x44,0x61,0x4E,0x34,0x0A,0x70,0x7A,0x71,0x45,0x51,0x72,0x52,
- 0x35,0x4B,0x35,0x4D,0x6E,0x54,0x48,0x76,0x47,0x67,0x2F,0x70,0x6A,0x57,0x6A,
- 0x43,0x57,0x58,0x56,0x48,0x67,0x35,0x76,0x36,0x46,0x6F,0x5A,0x48,0x35,0x6E,
- 0x59,0x2B,0x56,0x2F,0x57,0x75,0x57,0x38,0x38,0x6A,0x6C,0x4B,0x53,0x50,0x6C,
- 0x77,0x6A,0x50,0x7A,0x41,0x67,0x7A,0x47,0x33,0x45,0x41,0x55,0x0A,0x71,0x57,
- 0x6B,0x42,0x67,0x30,0x71,0x75,0x50,0x4D,0x72,0x54,0x6B,0x73,0x69,0x6E,0x58,
- 0x50,0x2B,0x58,0x6B,0x51,0x65,0x46,0x66,0x58,0x61,0x33,0x38,0x6A,0x72,0x70,
- 0x62,0x4B,0x46,0x4F,0x72,0x7A,0x49,0x6F,0x6A,0x69,0x65,0x6C,0x4B,0x55,0x4D,
- 0x50,0x4D,0x78,0x2F,0x78,0x70,0x53,0x6A,0x63,0x55,0x42,0x68,0x62,0x4E,0x34,
- 0x45,0x54,0x0A,0x4F,0x30,0x66,0x63,0x57,0x47,0x6F,0x61,0x56,0x50,0x72,0x63,
- 0x6E,0x38,0x62,0x58,0x4D,0x54,0x45,0x4E,0x53,0x31,0x41,0x3D,0x0A,0x2D,0x2D,
- 0x2D,0x2D,0x2D,0x45,0x4E,0x44,0x20,0x50,0x52,0x49,0x56,0x41,0x54,0x45,0x20,
- 0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x42,0x45,0x47,0x49,0x4E,0x20,0x50,0x52,0x49,0x56,
+ 0x41,0x54,0x45,0x20,0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,0x4D,0x49,
+ 0x49,0x45,0x76,0x51,0x49,0x42,0x41,0x44,0x41,0x4E,0x42,0x67,0x6B,0x71,0x68,
+ 0x6B,0x69,0x47,0x39,0x77,0x30,0x42,0x41,0x51,0x45,0x46,0x41,0x41,0x53,0x43,
+ 0x42,0x4B,0x63,0x77,0x67,0x67,0x53,0x6A,0x41,0x67,0x45,0x41,0x41,0x6F,0x49,
+ 0x42,0x41,0x51,0x43,0x33,0x65,0x6E,0x33,0x68,0x5A,0x4F,0x53,0x33,0x6B,0x51,
+ 0x2F,0x55,0x0A,0x54,0x30,0x53,0x45,0x6C,0x30,0x48,0x6E,0x50,0x79,0x64,0x48,
+ 0x75,0x35,0x39,0x61,0x69,0x71,0x64,0x73,0x64,0x53,0x55,0x74,0x6E,0x43,0x41,
+ 0x37,0x46,0x66,0x74,0x30,0x4F,0x36,0x51,0x79,0x68,0x49,0x71,0x58,0x7A,0x30,
+ 0x47,0x32,0x53,0x76,0x77,0x4C,0x54,0x62,0x79,0x68,0x59,0x54,0x68,0x31,0x36,
+ 0x78,0x31,0x72,0x45,0x48,0x68,0x31,0x0A,0x57,0x47,0x5A,0x6D,0x36,0x77,0x64,
+ 0x2B,0x4B,0x76,0x38,0x6B,0x31,0x6B,0x2F,0x36,0x6F,0x41,0x2F,0x4F,0x51,0x76,
+ 0x65,0x61,0x38,0x6B,0x63,0x45,0x64,0x53,0x72,0x54,0x64,0x75,0x71,0x4A,0x33,
+ 0x65,0x66,0x74,0x48,0x4A,0x4A,0x6E,0x43,0x4B,0x30,0x41,0x62,0x68,0x34,0x39,
+ 0x41,0x47,0x41,0x50,0x39,0x79,0x58,0x77,0x77,0x59,0x41,0x6A,0x0A,0x51,0x49,
+ 0x52,0x6E,0x38,0x2B,0x4F,0x63,0x63,0x48,0x74,0x6F,0x4E,0x75,0x75,0x79,0x52,
+ 0x63,0x6B,0x49,0x50,0x71,0x75,0x70,0x78,0x79,0x31,0x4A,0x5A,0x4B,0x39,0x64,
+ 0x76,0x76,0x62,0x34,0x79,0x53,0x6B,0x49,0x75,0x7A,0x62,0x79,0x50,0x6F,0x54,
+ 0x41,0x79,0x61,0x55,0x2B,0x51,0x72,0x70,0x34,0x78,0x67,0x64,0x4B,0x46,0x54,
+ 0x70,0x6B,0x0A,0x50,0x46,0x34,0x33,0x6A,0x32,0x4D,0x6D,0x5A,0x72,0x46,0x63,
+ 0x42,0x76,0x79,0x6A,0x69,0x35,0x6A,0x4F,0x37,0x74,0x66,0x6F,0x56,0x61,0x6B,
+ 0x59,0x47,0x53,0x2F,0x4C,0x63,0x78,0x77,0x47,0x2B,0x77,0x51,0x77,0x63,0x4F,
+ 0x43,0x54,0x42,0x45,0x78,0x2F,0x7A,0x31,0x53,0x30,0x37,0x49,0x2F,0x6A,0x62,
+ 0x44,0x79,0x53,0x4E,0x68,0x44,0x35,0x0A,0x63,0x61,0x63,0x54,0x75,0x4E,0x36,
+ 0x50,0x68,0x33,0x58,0x30,0x71,0x70,0x47,0x73,0x37,0x79,0x50,0x6B,0x4E,0x79,
+ 0x69,0x4A,0x33,0x57,0x52,0x69,0x6C,0x35,0x75,0x57,0x73,0x4B,0x65,0x79,0x63,
+ 0x64,0x71,0x42,0x4E,0x72,0x34,0x75,0x32,0x62,0x49,0x52,0x6E,0x63,0x54,0x51,
+ 0x46,0x72,0x68,0x73,0x58,0x39,0x69,0x77,0x37,0x35,0x76,0x75,0x0A,0x53,0x64,
+ 0x35,0x46,0x39,0x37,0x56,0x70,0x41,0x67,0x4D,0x42,0x41,0x41,0x45,0x43,0x67,
+ 0x67,0x45,0x41,0x42,0x36,0x6A,0x6C,0x65,0x48,0x4E,0x74,0x32,0x50,0x77,0x46,
+ 0x58,0x53,0x65,0x79,0x42,0x4A,0x63,0x4C,0x2B,0x55,0x74,0x35,0x71,0x46,0x54,
+ 0x38,0x34,0x68,0x72,0x48,0x77,0x6F,0x39,0x68,0x62,0x66,0x59,0x47,0x6F,0x6E,
+ 0x44,0x59,0x0A,0x66,0x70,0x47,0x2B,0x32,0x52,0x30,0x50,0x62,0x43,0x63,0x4B,
+ 0x35,0x30,0x46,0x61,0x4A,0x46,0x36,0x71,0x63,0x56,0x4A,0x4E,0x75,0x52,0x36,
+ 0x48,0x71,0x2B,0x43,0x55,0x4A,0x74,0x48,0x35,0x39,0x48,0x48,0x37,0x62,0x68,
+ 0x6A,0x39,0x62,0x64,0x78,0x45,0x6D,0x6F,0x48,0x30,0x4A,0x76,0x68,0x45,0x76,
+ 0x67,0x4D,0x2F,0x55,0x38,0x42,0x51,0x0A,0x65,0x57,0x4F,0x4E,0x68,0x78,0x50,
+ 0x73,0x69,0x73,0x6D,0x57,0x6B,0x78,0x61,0x5A,0x6F,0x6C,0x72,0x32,0x69,0x44,
+ 0x56,0x72,0x7A,0x54,0x37,0x55,0x4A,0x71,0x6A,0x74,0x59,0x49,0x74,0x67,0x2B,
+ 0x37,0x59,0x43,0x32,0x70,0x55,0x58,0x6B,0x64,0x49,0x35,0x4A,0x4D,0x67,0x6C,
+ 0x44,0x47,0x4D,0x52,0x5A,0x35,0x55,0x5A,0x48,0x75,0x63,0x7A,0x0A,0x41,0x56,
+ 0x2B,0x71,0x77,0x77,0x33,0x65,0x45,0x52,0x74,0x78,0x44,0x50,0x61,0x61,0x61,
+ 0x34,0x54,0x39,0x50,0x64,0x33,0x44,0x31,0x6D,0x62,0x71,0x58,0x66,0x75,0x45,
+ 0x68,0x42,0x6D,0x33,0x51,0x6F,0x2B,0x75,0x7A,0x51,0x32,0x36,0x76,0x73,0x66,
+ 0x48,0x75,0x56,0x76,0x61,0x39,0x38,0x32,0x4F,0x6A,0x41,0x55,0x6A,0x6E,0x64,
+ 0x30,0x70,0x0A,0x77,0x43,0x53,0x6E,0x42,0x49,0x48,0x67,0x70,0x73,0x30,0x79,
+ 0x61,0x45,0x50,0x63,0x37,0x46,0x78,0x39,0x71,0x45,0x63,0x6D,0x33,0x70,0x7A,
+ 0x41,0x56,0x31,0x69,0x72,0x31,0x4E,0x4E,0x63,0x51,0x47,0x55,0x45,0x75,0x45,
+ 0x6C,0x4A,0x78,0x76,0x2B,0x69,0x57,0x34,0x6D,0x35,0x70,0x7A,0x4C,0x6A,0x64,
+ 0x53,0x63,0x49,0x30,0x59,0x45,0x73,0x0A,0x4D,0x61,0x33,0x78,0x32,0x79,0x48,
+ 0x74,0x6E,0x77,0x79,0x65,0x4C,0x4D,0x54,0x4B,0x6C,0x72,0x46,0x4B,0x70,0x55,
+ 0x4E,0x4A,0x62,0x78,0x73,0x35,0x32,0x62,0x5A,0x4B,0x71,0x49,0x56,0x33,0x33,
+ 0x4A,0x53,0x34,0x41,0x51,0x4B,0x42,0x67,0x51,0x44,0x73,0x4C,0x54,0x49,0x68,
+ 0x35,0x59,0x38,0x4C,0x2F,0x48,0x33,0x64,0x74,0x68,0x63,0x62,0x0A,0x53,0x43,
+ 0x45,0x77,0x32,0x64,0x42,0x49,0x76,0x49,0x79,0x54,0x7A,0x39,0x53,0x72,0x62,
+ 0x33,0x58,0x37,0x37,0x41,0x77,0x57,0x45,0x4C,0x53,0x4D,0x49,0x57,0x53,0x50,
+ 0x55,0x43,0x4B,0x54,0x49,0x70,0x6A,0x4D,0x73,0x6E,0x7A,0x6B,0x46,0x67,0x32,
+ 0x32,0x59,0x32,0x53,0x75,0x47,0x38,0x4C,0x72,0x50,0x6D,0x76,0x73,0x46,0x4A,
+ 0x34,0x30,0x0A,0x32,0x67,0x35,0x44,0x55,0x6C,0x59,0x33,0x59,0x6D,0x53,0x4F,
+ 0x46,0x61,0x45,0x4A,0x54,0x70,0x55,0x47,0x44,0x4D,0x79,0x65,0x33,0x74,0x36,
+ 0x4F,0x30,0x6C,0x63,0x51,0x41,0x66,0x79,0x6D,0x58,0x66,0x41,0x38,0x74,0x50,
+ 0x42,0x48,0x6A,0x5A,0x78,0x56,0x61,0x38,0x78,0x78,0x52,0x5A,0x6E,0x56,0x43,
+ 0x31,0x41,0x62,0x75,0x49,0x49,0x52,0x0A,0x6E,0x77,0x72,0x4E,0x46,0x2B,0x42,
+ 0x6F,0x53,0x4B,0x55,0x41,0x73,0x78,0x2B,0x46,0x75,0x35,0x5A,0x4A,0x4B,0x4F,
+ 0x66,0x79,0x4D,0x51,0x4B,0x42,0x67,0x51,0x44,0x47,0x34,0x50,0x52,0x39,0x2F,
+ 0x58,0x58,0x6B,0x51,0x54,0x36,0x6B,0x7A,0x4B,0x64,0x34,0x50,0x6C,0x50,0x4D,
+ 0x63,0x2B,0x4B,0x51,0x79,0x4C,0x45,0x6C,0x4B,0x39,0x71,0x47,0x0A,0x41,0x6D,
+ 0x6E,0x2F,0x31,0x68,0x64,0x69,0x57,0x57,0x4F,0x52,0x57,0x46,0x62,0x32,0x38,
+ 0x30,0x4D,0x77,0x76,0x77,0x41,0x64,0x78,0x72,0x66,0x65,0x4C,0x57,0x4D,0x57,
+ 0x32,0x66,0x76,0x4C,0x59,0x4B,0x66,0x6C,0x4F,0x35,0x50,0x51,0x44,0x59,0x67,
+ 0x4B,0x4A,0x78,0x35,0x79,0x50,0x37,0x52,0x64,0x38,0x2F,0x64,0x50,0x79,0x5A,
+ 0x59,0x36,0x0A,0x7A,0x56,0x37,0x47,0x47,0x6B,0x51,0x5A,0x42,0x4B,0x36,0x79,
+ 0x74,0x61,0x66,0x32,0x35,0x44,0x50,0x67,0x50,0x72,0x32,0x77,0x73,0x59,0x4D,
+ 0x43,0x6C,0x53,0x74,0x6C,0x56,0x74,0x72,0x6D,0x4F,0x78,0x59,0x55,0x56,0x77,
+ 0x42,0x59,0x4F,0x69,0x36,0x45,0x62,0x50,0x69,0x6B,0x78,0x47,0x48,0x5A,0x70,
+ 0x59,0x6F,0x5A,0x5A,0x70,0x68,0x4A,0x0A,0x4E,0x61,0x38,0x4F,0x4C,0x31,0x69,
+ 0x77,0x75,0x51,0x4B,0x42,0x67,0x51,0x44,0x42,0x55,0x55,0x31,0x54,0x79,0x5A,
+ 0x2B,0x4A,0x5A,0x43,0x64,0x79,0x72,0x33,0x58,0x43,0x63,0x77,0x77,0x58,0x2F,
+ 0x48,0x49,0x73,0x31,0x34,0x6B,0x4B,0x42,0x48,0x68,0x44,0x79,0x33,0x78,0x37,
+ 0x74,0x50,0x38,0x2F,0x6F,0x48,0x54,0x6F,0x72,0x76,0x79,0x74,0x0A,0x41,0x68,
+ 0x38,0x4B,0x36,0x4B,0x72,0x43,0x41,0x75,0x65,0x50,0x6D,0x79,0x32,0x6D,0x4F,
+ 0x54,0x31,0x54,0x39,0x6F,0x31,0x61,0x47,0x55,0x49,0x6C,0x66,0x38,0x72,0x76,
+ 0x33,0x2F,0x30,0x45,0x78,0x67,0x53,0x6B,0x57,0x50,0x6D,0x4F,0x41,0x38,0x35,
+ 0x49,0x32,0x2F,0x58,0x48,0x65,0x66,0x71,0x54,0x6F,0x45,0x48,0x30,0x44,0x65,
+ 0x41,0x4E,0x0A,0x7A,0x6C,0x4B,0x4C,0x71,0x79,0x44,0x56,0x30,0x42,0x56,0x4E,
+ 0x76,0x48,0x42,0x57,0x79,0x32,0x49,0x51,0x35,0x62,0x50,0x42,0x57,0x76,0x30,
+ 0x37,0x63,0x34,0x2B,0x6A,0x39,0x4E,0x62,0x57,0x67,0x64,0x44,0x43,0x43,0x35,
+ 0x52,0x6B,0x4F,0x6A,0x70,0x33,0x4D,0x4E,0x45,0x58,0x47,0x56,0x43,0x69,0x51,
+ 0x51,0x4B,0x42,0x67,0x43,0x7A,0x4D,0x0A,0x77,0x65,0x61,0x62,0x73,0x50,0x48,
+ 0x68,0x44,0x4B,0x5A,0x38,0x2F,0x34,0x43,0x6A,0x73,0x61,0x62,0x4E,0x75,0x41,
+ 0x7A,0x62,0x57,0x4B,0x52,0x42,0x38,0x37,0x44,0x61,0x58,0x46,0x78,0x6F,0x4D,
+ 0x73,0x35,0x52,0x79,0x6F,0x38,0x55,0x4D,0x6B,0x72,0x67,0x30,0x35,0x4C,0x6F,
+ 0x67,0x37,0x4D,0x78,0x62,0x33,0x76,0x61,0x42,0x34,0x63,0x2F,0x0A,0x52,0x57,
+ 0x77,0x7A,0x38,0x72,0x34,0x39,0x70,0x48,0x64,0x71,0x68,0x4F,0x6D,0x63,0x6C,
+ 0x45,0x77,0x79,0x4D,0x34,0x51,0x79,0x6A,0x39,0x52,0x6D,0x57,0x62,0x51,0x58,
+ 0x54,0x54,0x45,0x63,0x2B,0x35,0x67,0x54,0x4B,0x50,0x4E,0x53,0x33,0x6D,0x70,
+ 0x4D,0x54,0x36,0x39,0x46,0x45,0x74,0x2F,0x35,0x72,0x4D,0x52,0x70,0x4B,0x2B,
+ 0x52,0x68,0x0A,0x49,0x32,0x42,0x58,0x6B,0x51,0x71,0x31,0x36,0x6E,0x72,0x31,
+ 0x61,0x45,0x4D,0x6D,0x64,0x51,0x42,0x51,0x79,0x4B,0x59,0x4A,0x6C,0x30,0x6C,
+ 0x50,0x68,0x69,0x42,0x2F,0x75,0x6C,0x5A,0x63,0x72,0x67,0x4C,0x70,0x41,0x6F,
+ 0x47,0x41,0x65,0x30,0x65,0x74,0x50,0x4A,0x77,0x6D,0x51,0x46,0x6B,0x6A,0x4D,
+ 0x70,0x66,0x4D,0x44,0x61,0x4E,0x34,0x0A,0x70,0x7A,0x71,0x45,0x51,0x72,0x52,
+ 0x35,0x4B,0x35,0x4D,0x6E,0x54,0x48,0x76,0x47,0x67,0x2F,0x70,0x6A,0x57,0x6A,
+ 0x43,0x57,0x58,0x56,0x48,0x67,0x35,0x76,0x36,0x46,0x6F,0x5A,0x48,0x35,0x6E,
+ 0x59,0x2B,0x56,0x2F,0x57,0x75,0x57,0x38,0x38,0x6A,0x6C,0x4B,0x53,0x50,0x6C,
+ 0x77,0x6A,0x50,0x7A,0x41,0x67,0x7A,0x47,0x33,0x45,0x41,0x55,0x0A,0x71,0x57,
+ 0x6B,0x42,0x67,0x30,0x71,0x75,0x50,0x4D,0x72,0x54,0x6B,0x73,0x69,0x6E,0x58,
+ 0x50,0x2B,0x58,0x6B,0x51,0x65,0x46,0x66,0x58,0x61,0x33,0x38,0x6A,0x72,0x70,
+ 0x62,0x4B,0x46,0x4F,0x72,0x7A,0x49,0x6F,0x6A,0x69,0x65,0x6C,0x4B,0x55,0x4D,
+ 0x50,0x4D,0x78,0x2F,0x78,0x70,0x53,0x6A,0x63,0x55,0x42,0x68,0x62,0x4E,0x34,
+ 0x45,0x54,0x0A,0x4F,0x30,0x66,0x63,0x57,0x47,0x6F,0x61,0x56,0x50,0x72,0x63,
+ 0x6E,0x38,0x62,0x58,0x4D,0x54,0x45,0x4E,0x53,0x31,0x41,0x3D,0x0A,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x45,0x4E,0x44,0x20,0x50,0x52,0x49,0x56,0x41,0x54,0x45,0x20,
+ 0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A
};
BYTE test_DummyMessage[64] =
SECURITY_STATUS status;
DWORD NumberOfBytesWritten;
SecPkgContext_StreamSizes StreamSizes;
-
ZeroMemory(&StreamSizes, sizeof(SecPkgContext_StreamSizes));
status = table->QueryContextAttributes(phContext, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
-
ioBufferLength = StreamSizes.cbHeader + StreamSizes.cbMaximumMessage + StreamSizes.cbTrailer;
ioBuffer = (BYTE*) malloc(ioBufferLength);
ZeroMemory(ioBuffer, ioBufferLength);
-
pMessageBuffer = ioBuffer + StreamSizes.cbHeader;
CopyMemory(pMessageBuffer, buffer, length);
-
Buffers[0].pvBuffer = ioBuffer;
Buffers[0].cbBuffer = StreamSizes.cbHeader;
Buffers[0].BufferType = SECBUFFER_STREAM_HEADER;
-
Buffers[1].pvBuffer = pMessageBuffer;
Buffers[1].cbBuffer = length;
Buffers[1].BufferType = SECBUFFER_DATA;
-
Buffers[2].pvBuffer = pMessageBuffer + length;
Buffers[2].cbBuffer = StreamSizes.cbTrailer;
Buffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
-
Buffers[3].pvBuffer = NULL;
Buffers[3].cbBuffer = 0;
Buffers[3].BufferType = SECBUFFER_EMPTY;
-
Message.ulVersion = SECBUFFER_VERSION;
Message.cBuffers = 4;
Message.pBuffers = Buffers;
-
ioBufferLength = Message.pBuffers[0].cbBuffer + Message.pBuffers[1].cbBuffer + Message.pBuffers[2].cbBuffer;
-
status = table->EncryptMessage(phContext, 0, &Message, 0);
-
printf("EncryptMessage status: 0x%08X\n", status);
-
printf("EncryptMessage output: cBuffers: %d [0]: %u / %u [1]: %u / %u [2]: %u / %u [3]: %u / %u\n", Message.cBuffers,
- Message.pBuffers[0].cbBuffer, Message.pBuffers[0].BufferType,
- Message.pBuffers[1].cbBuffer, Message.pBuffers[1].BufferType,
- Message.pBuffers[2].cbBuffer, Message.pBuffers[2].BufferType,
- Message.pBuffers[3].cbBuffer, Message.pBuffers[3].BufferType);
+ Message.pBuffers[0].cbBuffer, Message.pBuffers[0].BufferType,
+ Message.pBuffers[1].cbBuffer, Message.pBuffers[1].BufferType,
+ Message.pBuffers[2].cbBuffer, Message.pBuffers[2].BufferType,
+ Message.pBuffers[3].cbBuffer, Message.pBuffers[3].BufferType);
if (status != SEC_E_OK)
return -1;
printf("Client > Server (%d)\n", ioBufferLength);
- winpr_HexDump(ioBuffer, ioBufferLength);
+ winpr_HexDump("sspi.test", WLOG_DEBUG, ioBuffer, ioBufferLength);
if (!WriteFile(hPipe, ioBuffer, ioBufferLength, &NumberOfBytesWritten, NULL))
{
SECURITY_STATUS status;
DWORD NumberOfBytesRead;
SecPkgContext_StreamSizes StreamSizes;
-
ZeroMemory(&StreamSizes, sizeof(SecPkgContext_StreamSizes));
status = table->QueryContextAttributes(phContext, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
-
ioBufferLength = StreamSizes.cbHeader + StreamSizes.cbMaximumMessage + StreamSizes.cbTrailer;
ioBuffer = (BYTE*) malloc(ioBufferLength);
ZeroMemory(ioBuffer, ioBufferLength);
Buffers[0].pvBuffer = ioBuffer;
Buffers[0].cbBuffer = NumberOfBytesRead;
Buffers[0].BufferType = SECBUFFER_DATA;
-
Buffers[1].pvBuffer = NULL;
Buffers[1].cbBuffer = 0;
Buffers[1].BufferType = SECBUFFER_EMPTY;
-
Buffers[2].pvBuffer = NULL;
Buffers[2].cbBuffer = 0;
Buffers[2].BufferType = SECBUFFER_EMPTY;
-
Buffers[3].pvBuffer = NULL;
Buffers[3].cbBuffer = 0;
Buffers[3].BufferType = SECBUFFER_EMPTY;
-
Message.ulVersion = SECBUFFER_VERSION;
Message.cBuffers = 4;
Message.pBuffers = Buffers;
-
status = table->DecryptMessage(phContext, &Message, 0, NULL);
-
printf("DecryptMessage status: 0x%08X\n", status);
-
printf("DecryptMessage output: cBuffers: %d [0]: %u / %u [1]: %u / %u [2]: %u / %u [3]: %u / %u\n", Message.cBuffers,
- Message.pBuffers[0].cbBuffer, Message.pBuffers[0].BufferType,
- Message.pBuffers[1].cbBuffer, Message.pBuffers[1].BufferType,
- Message.pBuffers[2].cbBuffer, Message.pBuffers[2].BufferType,
- Message.pBuffers[3].cbBuffer, Message.pBuffers[3].BufferType);
+ Message.pBuffers[0].cbBuffer, Message.pBuffers[0].BufferType,
+ Message.pBuffers[1].cbBuffer, Message.pBuffers[1].BufferType,
+ Message.pBuffers[2].cbBuffer, Message.pBuffers[2].BufferType,
+ Message.pBuffers[3].cbBuffer, Message.pBuffers[3].BufferType);
if (status != SEC_E_OK)
return -1;
printf("Decrypted Message (%d)\n", Message.pBuffers[1].cbBuffer);
- winpr_HexDump((BYTE*) Message.pBuffers[1].pvBuffer, Message.pBuffers[1].cbBuffer);
+ winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*) Message.pBuffers[1].pvBuffer, Message.pBuffers[1].cbBuffer);
if (memcmp(Message.pBuffers[1].pvBuffer, test_LastDummyMessage, sizeof(test_LastDummyMessage)) == 0)
return -1;
PSecPkgInfo pPackageInfo;
PSecurityFunctionTable table;
DWORD NumberOfBytesWritten;
-
printf("Starting Server\n");
-
SecInvalidateHandle(&context);
SecInvalidateHandle(&credentials);
-
table = InitSecurityInterface();
-
status = QuerySecurityPackageInfo(SCHANNEL_NAME, &pPackageInfo);
if (status != SEC_E_OK)
}
cbMaxToken = pPackageInfo->cbMaxToken;
-
hCertStore = CertOpenSystemStore(0, _T("MY"));
if (!hCertStore)
}
cchNameString = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);
-
pszNameString = (LPTSTR) malloc(cchNameString * sizeof(TCHAR));
cchNameString = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, cchNameString);
-
_tprintf(_T("Certificate Name: %s\n"), pszNameString);
-
ZeroMemory(&cred, sizeof(SCHANNEL_CRED));
cred.dwVersion = SCHANNEL_CRED_VERSION;
-
cred.cCreds = 1;
cred.paCred = &pCertContext;
-
cred.cSupportedAlgs = 0;
cred.palgSupportedAlgs = NULL;
-
cred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER;
-
cred.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER;
-
status = table->AcquireCredentialsHandle(NULL, SCHANNEL_NAME,
- SECPKG_CRED_INBOUND, NULL, &cred, NULL, NULL, &credentials, NULL);
+ SECPKG_CRED_INBOUND, NULL, &cred, NULL, NULL, &credentials, NULL);
if (status != SEC_E_OK)
{
extraData = FALSE;
g_ServerWait = TRUE;
-
lpTokenIn = (BYTE*) malloc(cbMaxToken);
lpTokenOut = (BYTE*) malloc(cbMaxToken);
-
fContextReq = ASC_REQ_STREAM |
- ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT |
- ASC_REQ_CONFIDENTIALITY | ASC_REQ_EXTENDED_ERROR;
+ ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT |
+ ASC_REQ_CONFIDENTIALITY | ASC_REQ_EXTENDED_ERROR;
do
{
extraData = FALSE;
g_ServerWait = TRUE;
-
SecBuffer_in[0].BufferType = SECBUFFER_TOKEN;
SecBuffer_in[0].pvBuffer = lpTokenIn;
SecBuffer_in[0].cbBuffer = NumberOfBytesRead;
-
SecBuffer_in[1].BufferType = SECBUFFER_EMPTY;
SecBuffer_in[1].pvBuffer = NULL;
SecBuffer_in[1].cbBuffer = 0;
-
SecBufferDesc_in.ulVersion = SECBUFFER_VERSION;
SecBufferDesc_in.cBuffers = 2;
SecBufferDesc_in.pBuffers = SecBuffer_in;
-
SecBuffer_out[0].BufferType = SECBUFFER_TOKEN;
SecBuffer_out[0].pvBuffer = lpTokenOut;
SecBuffer_out[0].cbBuffer = cbMaxToken;
-
SecBufferDesc_out.ulVersion = SECBUFFER_VERSION;
SecBufferDesc_out.cBuffers = 1;
SecBufferDesc_out.pBuffers = SecBuffer_out;
-
status = table->AcceptSecurityContext(&credentials, SecIsValidHandle(&context) ? &context : NULL,
- &SecBufferDesc_in, fContextReq, 0, &context, &SecBufferDesc_out, &fContextAttr, &expiry);
+ &SecBufferDesc_in, fContextReq, 0, &context, &SecBufferDesc_out, &fContextAttr, &expiry);
if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED) && (status != SEC_E_INCOMPLETE_MESSAGE))
{
printf("AcceptSecurityContext status: SEC_E_INCOMPLETE_MESSAGE\n");
printf("Server cBuffers: %u pBuffers[0]: %u type: %u\n",
- SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer, SecBufferDesc_out.pBuffers[0].BufferType);
+ SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer, SecBufferDesc_out.pBuffers[0].BufferType);
printf("Server Input cBuffers: %d pBuffers[0]: %u type: %u pBuffers[1]: %u type: %u\n", SecBufferDesc_in.cBuffers,
- SecBufferDesc_in.pBuffers[0].cbBuffer, SecBufferDesc_in.pBuffers[0].BufferType,
- SecBufferDesc_in.pBuffers[1].cbBuffer, SecBufferDesc_in.pBuffers[1].BufferType);
+ SecBufferDesc_in.pBuffers[0].cbBuffer, SecBufferDesc_in.pBuffers[0].BufferType,
+ SecBufferDesc_in.pBuffers[1].cbBuffer, SecBufferDesc_in.pBuffers[1].BufferType);
if (SecBufferDesc_in.pBuffers[1].BufferType == SECBUFFER_EXTRA)
{
if (pSecBuffer->cbBuffer > 0)
{
printf("Server > Client (%d)\n", pSecBuffer->cbBuffer);
- winpr_HexDump((BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
+ winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
if (!WriteFile(g_ClientWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer, &NumberOfBytesWritten, NULL))
{
if (schannel_recv(table, g_ServerReadPipe, &context) < 0)
break;
}
- while(1);
+ while (1);
return NULL;
}
{
FILE* fp;
char* fullpath;
-
/*
* Output Certificate File
*/
-
fullpath = GetCombinedPath("/tmp", "localhost.crt");
-
fp = fopen(fullpath, "w+");
if (fp)
}
free(fullpath);
-
/*
* Output Private Key File
*/
-
fullpath = GetCombinedPath("/tmp", "localhost.key");
-
fp = fopen(fullpath, "w+");
if (fp)
}
free(fullpath);
-
return 1;
}
SecPkgCred_SupportedAlgs SupportedAlgs;
SecPkgCred_CipherStrengths CipherStrengths;
SecPkgCred_SupportedProtocols SupportedProtocols;
-
return 0; /* disable by default - causes crash */
-
sspi_GlobalInit();
-
dump_test_certificate_files();
-
SecInvalidateHandle(&context);
SecInvalidateHandle(&credentials);
}
thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) schannel_test_server_thread, NULL, 0, NULL);
-
table = InitSecurityInterface();
-
status = QuerySecurityPackageInfo(SCHANNEL_NAME, &pPackageInfo);
if (status != SEC_E_OK)
}
cbMaxToken = pPackageInfo->cbMaxToken;
-
ZeroMemory(&cred, sizeof(SCHANNEL_CRED));
cred.dwVersion = SCHANNEL_CRED_VERSION;
-
cred.cCreds = 0;
cred.paCred = NULL;
-
cred.cSupportedAlgs = 0;
cred.palgSupportedAlgs = NULL;
-
cred.grbitEnabledProtocols = SP_PROT_SSL3TLS1_CLIENTS;
-
cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS;
cred.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION;
cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
-
status = table->AcquireCredentialsHandle(NULL, SCHANNEL_NAME,
- SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &credentials, NULL);
+ SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &credentials, NULL);
if (status != SEC_E_OK)
{
* 0x660E 0x6610 0x6801 0x6603 0x6601 0x8003 0x8004
* 0x800C 0x800D 0x800E 0x2400 0xAA02 0xAE06 0x2200 0x2203
*/
-
printf("SupportedAlgs: %d\n", SupportedAlgs.cSupportedAlgs);
for (index = 0; index < SupportedAlgs.cSupportedAlgs; index++)
{
algId = SupportedAlgs.palgSupportedAlgs[index];
printf("\t0x%04X CLASS: %d TYPE: %d SID: %d\n", algId,
- ((GET_ALG_CLASS(algId)) >> 13), ((GET_ALG_TYPE(algId)) >> 9), GET_ALG_SID(algId));
+ ((GET_ALG_CLASS(algId)) >> 13), ((GET_ALG_TYPE(algId)) >> 9), GET_ALG_SID(algId));
}
- printf("\n");
+ printf("\n");
ZeroMemory(&CipherStrengths, sizeof(SecPkgCred_CipherStrengths));
status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_CIPHER_STRENGTHS, &CipherStrengths);
}
/* CipherStrengths: Minimum: 40 Maximum: 256 */
-
printf("CipherStrengths: Minimum: %d Maximum: %d\n",
- CipherStrengths.dwMinimumCipherStrength, CipherStrengths.dwMaximumCipherStrength);
-
+ CipherStrengths.dwMinimumCipherStrength, CipherStrengths.dwMaximumCipherStrength);
ZeroMemory(&SupportedProtocols, sizeof(SecPkgCred_SupportedProtocols));
status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_PROTOCOLS, &SupportedProtocols);
}
/* SupportedProtocols: 0x208A0 */
-
printf("SupportedProtocols: 0x%04X\n", SupportedProtocols.grbitProtocol);
-
fContextReq = ISC_REQ_STREAM |
- ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
- ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR |
- ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY;
-
+ ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
+ ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR |
+ ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY;
lpTokenIn = (BYTE*) malloc(cbMaxToken);
lpTokenOut = (BYTE*) malloc(cbMaxToken);
-
ZeroMemory(&SecBuffer_in, sizeof(SecBuffer_in));
ZeroMemory(&SecBuffer_out, sizeof(SecBuffer_out));
ZeroMemory(&SecBufferDesc_in, sizeof(SecBufferDesc));
ZeroMemory(&SecBufferDesc_out, sizeof(SecBufferDesc));
-
g_ClientWait = FALSE;
do
g_ClientWait = TRUE;
printf("NumberOfBytesRead: %d\n", NumberOfBytesRead);
-
SecBuffer_in[0].BufferType = SECBUFFER_TOKEN;
SecBuffer_in[0].pvBuffer = lpTokenIn;
SecBuffer_in[0].cbBuffer = NumberOfBytesRead;
-
SecBuffer_in[1].pvBuffer = NULL;
SecBuffer_in[1].cbBuffer = 0;
SecBuffer_in[1].BufferType = SECBUFFER_EMPTY;
-
SecBufferDesc_in.ulVersion = SECBUFFER_VERSION;
SecBufferDesc_in.cBuffers = 2;
SecBufferDesc_in.pBuffers = SecBuffer_in;
-
SecBuffer_out[0].BufferType = SECBUFFER_TOKEN;
SecBuffer_out[0].pvBuffer = lpTokenOut;
SecBuffer_out[0].cbBuffer = cbMaxToken;
-
SecBufferDesc_out.ulVersion = SECBUFFER_VERSION;
SecBufferDesc_out.cBuffers = 1;
SecBufferDesc_out.pBuffers = SecBuffer_out;
-
status = table->InitializeSecurityContext(&credentials, SecIsValidHandle(&context) ? &context : NULL, _T("localhost"),
- fContextReq, 0, 0, &SecBufferDesc_in, 0, &context, &SecBufferDesc_out, &fContextAttr, &expiry);
+ fContextReq, 0, 0, &SecBufferDesc_in, 0, &context, &SecBufferDesc_out, &fContextAttr, &expiry);
if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED) && (status != SEC_E_INCOMPLETE_MESSAGE))
{
printf("InitializeSecurityContext status: SEC_E_INCOMPLETE_MESSAGE\n");
printf("Client Output cBuffers: %d pBuffers[0]: %d type: %d\n",
- SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer, SecBufferDesc_out.pBuffers[0].BufferType);
+ SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer, SecBufferDesc_out.pBuffers[0].BufferType);
printf("Client Input cBuffers: %d pBuffers[0]: %d type: %d pBuffers[1]: %d type: %d\n", SecBufferDesc_in.cBuffers,
- SecBufferDesc_in.pBuffers[0].cbBuffer, SecBufferDesc_in.pBuffers[0].BufferType,
- SecBufferDesc_in.pBuffers[1].cbBuffer, SecBufferDesc_in.pBuffers[1].BufferType);
+ SecBufferDesc_in.pBuffers[0].cbBuffer, SecBufferDesc_in.pBuffers[0].BufferType,
+ SecBufferDesc_in.pBuffers[1].cbBuffer, SecBufferDesc_in.pBuffers[1].BufferType);
if (status != SEC_E_INCOMPLETE_MESSAGE)
{
if (pSecBuffer->cbBuffer > 0)
{
printf("Client > Server (%d)\n", pSecBuffer->cbBuffer);
- winpr_HexDump((BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
+ winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
if (!WriteFile(g_ServerWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer, &NumberOfBytesWritten, NULL))
{
break;
}
}
- while(1);
+ while (1);
count = 0;
for (index = 0; index < sizeof(test_DummyMessage); index++)
{
BYTE b, ln, hn;
-
b = test_DummyMessage[index];
-
ln = (b & 0x0F);
hn = ((b & 0xF0) >> 4);
-
ln = (ln + 1) % 0xF;
hn = (ln + 1) % 0xF;
-
b = (ln | (hn << 4));
-
test_DummyMessage[index] = b;
}
Sleep(100);
count++;
}
- while(count < 3);
+ while (count < 3);
schannel_send(table, g_ServerWritePipe, &context, test_LastDummyMessage, sizeof(test_LastDummyMessage));
-
WaitForSingleObject(thread, INFINITE);
-
sspi_GlobalFinish();
-
return 0;
}
#include <winpr/synch.h>
-/**
- * InitializeSynchronizationBarrier
- * EnterSynchronizationBarrier
- * DeleteSynchronizationBarrier
- */
+#include "synch.h"
+
+#include <winpr/crt.h>
+
+#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0602))
+
+#include <winpr/library.h>
+#include <winpr/interlocked.h>
+
+#ifdef _WIN32
+
+static HMODULE g_Kernel32 = NULL;
+static BOOL g_NativeBarrier = FALSE;
+static INIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT;
-#ifndef _WIN32
+typedef BOOL (WINAPI * fnInitializeSynchronizationBarrier)(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount);
+typedef BOOL (WINAPI * fnEnterSynchronizationBarrier)(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags);
+typedef BOOL (WINAPI * fnDeleteSynchronizationBarrier)(LPSYNCHRONIZATION_BARRIER lpBarrier);
-BOOL InitializeSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount)
+static fnInitializeSynchronizationBarrier pfnInitializeSynchronizationBarrier = NULL;
+static fnEnterSynchronizationBarrier pfnEnterSynchronizationBarrier = NULL;
+static fnDeleteSynchronizationBarrier pfnDeleteSynchronizationBarrier = NULL;
+
+static BOOL CALLBACK InitOnce_Barrier(PINIT_ONCE once, PVOID param, PVOID *context)
{
+ g_Kernel32 = LoadLibraryA("kernel32.dll");
+
+ if (!g_Kernel32)
+ return TRUE;
+
+ pfnInitializeSynchronizationBarrier = (fnInitializeSynchronizationBarrier)
+ GetProcAddress(g_Kernel32, "InitializeSynchronizationBarrier");
+
+ pfnEnterSynchronizationBarrier = (fnEnterSynchronizationBarrier)
+ GetProcAddress(g_Kernel32, "EnterSynchronizationBarrier");
+
+ pfnDeleteSynchronizationBarrier = (fnDeleteSynchronizationBarrier)
+ GetProcAddress(g_Kernel32, "DeleteSynchronizationBarrier");
+
+ if (pfnInitializeSynchronizationBarrier && pfnEnterSynchronizationBarrier
+ && pfnDeleteSynchronizationBarrier)
+ {
+ g_NativeBarrier = TRUE;
+ }
+
return TRUE;
}
-BOOL EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags)
+#endif
+
+BOOL WINAPI InitializeSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount)
{
+ WINPR_BARRIER* pBarrier;
+
+#ifdef _WIN32
+ InitOnceExecuteOnce(&g_InitOnce, InitOnce_Barrier, NULL, NULL);
+
+ if (g_NativeBarrier)
+ return pfnInitializeSynchronizationBarrier(lpBarrier, lTotalThreads, lSpinCount);
+#endif
+
+ if (!lpBarrier)
+ return FALSE;
+
+ ZeroMemory(lpBarrier, sizeof(SYNCHRONIZATION_BARRIER));
+
+ pBarrier = (WINPR_BARRIER*) calloc(1, sizeof(WINPR_BARRIER));
+
+ if (!pBarrier)
+ return FALSE;
+
+ if (lSpinCount < 0)
+ lSpinCount = 2000;
+
+ pBarrier->lTotalThreads = lTotalThreads;
+ pBarrier->lSpinCount = lSpinCount;
+ pBarrier->count = 0;
+
+ pBarrier->event = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ if (!pBarrier->event)
+ {
+ free(pBarrier);
+ return FALSE;
+ }
+
+ lpBarrier->Reserved3[0] = (ULONG_PTR) pBarrier;
+
return TRUE;
}
-BOOL DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier)
+BOOL WINAPI EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags)
+{
+ LONG count;
+ BOOL status = FALSE;
+ WINPR_BARRIER* pBarrier;
+
+#ifdef _WIN32
+ if (g_NativeBarrier)
+ return pfnEnterSynchronizationBarrier(lpBarrier, dwFlags);
+#endif
+
+ if (!lpBarrier)
+ return FALSE;
+
+ pBarrier = (WINPR_BARRIER*) lpBarrier->Reserved3[0];
+
+ if (!pBarrier)
+ return FALSE;
+
+ count = InterlockedIncrement(&(pBarrier->count));
+
+ if (count < pBarrier->lTotalThreads)
+ {
+ WaitForSingleObject(pBarrier->event, INFINITE);
+ }
+ else
+ {
+ SetEvent(pBarrier->event);
+ status = TRUE;
+ }
+
+ return status;
+}
+
+BOOL WINAPI DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier)
{
+ WINPR_BARRIER* pBarrier;
+
+#ifdef _WIN32
+ if (g_NativeBarrier)
+ return pfnDeleteSynchronizationBarrier(lpBarrier);
+#endif
+
+ if (!lpBarrier)
+ return TRUE;
+
+ pBarrier = (WINPR_BARRIER*) lpBarrier->Reserved3[0];
+
+ if (!pBarrier)
+ return TRUE;
+
+ CloseHandle(pBarrier->event);
+
+ free(pBarrier);
+
+ ZeroMemory(lpBarrier, sizeof(SYNCHRONIZATION_BARRIER));
+
return TRUE;
}
#ifndef _WIN32
+#include "../log.h"
+#define TAG WINPR_TAG("synch.critical")
+
VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
InitializeCriticalSectionEx(lpCriticalSection, 0, 0);
* - The RecursionCount field indicates the number of times that the owning
* thread has called EnterCriticalSection for this critical section.
*/
-
- if (Flags != 0) {
- fprintf(stderr, "warning: InitializeCriticalSectionEx Flags unimplemented\n");
+ if (Flags != 0)
+ {
+ WLog_WARN(TAG, "Flags unimplemented");
}
lpCriticalSection->DebugInfo = NULL;
lpCriticalSection->SpinCount = 0;
lpCriticalSection->RecursionCount = 0;
lpCriticalSection->OwningThread = NULL;
-
lpCriticalSection->LockSemaphore = (winpr_sem_t*) malloc(sizeof(winpr_sem_t));
#if defined(__APPLE__)
semaphore_create(mach_task_self(), lpCriticalSection->LockSemaphore, SYNC_POLICY_FIFO, 0);
#else
sem_init(lpCriticalSection->LockSemaphore, 0, 0);
#endif
-
SetCriticalSectionSpinCount(lpCriticalSection, dwSpinCount);
-
return TRUE;
}
{
/* Don't spin on uniprocessor systems! */
GetNativeSystemInfo(&sysinfo);
+
if (sysinfo.dwNumberOfProcessors < 2)
dwSpinCount = 0;
}
+
lpCriticalSection->SpinCount = dwSpinCount;
return dwPreviousSpinCount;
#else
#endif
}
-VOID _WaitForCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
+static VOID _WaitForCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
#if defined(__APPLE__)
semaphore_wait(*((winpr_sem_t*) lpCriticalSection->LockSemaphore));
#endif
}
-VOID _UnWaitCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
+static VOID _UnWaitCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
#if defined __APPLE__
semaphore_signal(*((winpr_sem_t*) lpCriticalSection->LockSemaphore));
if (InterlockedCompareExchange(&lpCriticalSection->LockCount, 0, -1) == -1)
{
lpCriticalSection->RecursionCount = 1;
- lpCriticalSection->OwningThread = (HANDLE) (ULONG_PTR) GetCurrentThreadId();
+ lpCriticalSection->OwningThread = (HANDLE)(ULONG_PTR) GetCurrentThreadId();
return;
}
+
/* Failed to get the lock. Let the scheduler know that we're spinning. */
if (sched_yield()!=0)
{
if (InterlockedIncrement(&lpCriticalSection->LockCount))
{
/* Section is already locked. Check if it is owned by the current thread. */
- if (lpCriticalSection->OwningThread == (HANDLE) (ULONG_PTR) GetCurrentThreadId())
+ if (lpCriticalSection->OwningThread == (HANDLE)(ULONG_PTR) GetCurrentThreadId())
{
/* Recursion. No need to wait. */
lpCriticalSection->RecursionCount++;
/* Section is locked by another thread. We have to wait. */
_WaitForCriticalSection(lpCriticalSection);
}
+
/* We got the lock. Own it ... */
lpCriticalSection->RecursionCount = 1;
- lpCriticalSection->OwningThread = (HANDLE) (ULONG_PTR) GetCurrentThreadId();
+ lpCriticalSection->OwningThread = (HANDLE)(ULONG_PTR) GetCurrentThreadId();
}
BOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
- HANDLE current_thread = (HANDLE) (ULONG_PTR) GetCurrentThreadId();
+ HANDLE current_thread = (HANDLE)(ULONG_PTR) GetCurrentThreadId();
/* Atomically acquire the the lock if the section is free. */
- if (InterlockedCompareExchange(&lpCriticalSection->LockCount, 0, -1 ) == -1)
+ if (InterlockedCompareExchange(&lpCriticalSection->LockCount, 0, -1) == -1)
{
lpCriticalSection->RecursionCount = 1;
lpCriticalSection->OwningThread = current_thread;
{
/* Last recursion, clear owner, unlock and if there are other waiting threads ... */
lpCriticalSection->OwningThread = NULL;
+
if (InterlockedDecrement(&lpCriticalSection->LockCount) >= 0)
{
/* ...signal the semaphore to unblock the next waiting thread */
#if (defined(_WIN32) && (_WIN32_WINNT < 0x0600))
-typedef BOOL (WINAPI * PINITIALIZE_CRITICAL_SECTION_EX_FN)(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags);
+typedef BOOL (WINAPI* PINITIALIZE_CRITICAL_SECTION_EX_FN)(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags);
static HMODULE g_KERNEL32_Library = NULL;
static BOOL g_InitializeCriticalSectionEx_Detected = FALSE;
if (g_KERNEL32_Library)
{
g_pInitializeCriticalSectionEx = (PINITIALIZE_CRITICAL_SECTION_EX_FN)
- GetProcAddress(g_KERNEL32_Library, "InitializeCriticalSectionEx");
-
+ GetProcAddress(g_KERNEL32_Library, "InitializeCriticalSectionEx");
g_InitializeCriticalSectionEx_Available = (g_pInitializeCriticalSectionEx) ? TRUE : FALSE;
}
else
#include "../handle/handle.h"
#include "../pipe/pipe.h"
+#include "../log.h"
+#define TAG WINPR_TAG("synch.event")
+
CRITICAL_SECTION cs = { NULL, 0, 0, NULL, NULL, 0 };
HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName)
{
WINPR_EVENT* event;
HANDLE handle = NULL;
-
event = (WINPR_EVENT*) malloc(sizeof(WINPR_EVENT));
if (event)
if (!event->bManualReset)
{
- fprintf(stderr, "CreateEventW: auto-reset events not yet implemented\n");
+ WLog_ERR(TAG, "auto-reset events not yet implemented");
}
event->pipe_fd[0] = -1;
event->pipe_fd[1] = -1;
-
#ifdef HAVE_EVENTFD_H
event->pipe_fd[0] = eventfd(0, EFD_NONBLOCK);
if (event->pipe_fd[0] < 0)
{
- fprintf(stderr, "CreateEventW: failed to create event\n");
+ WLog_ERR(TAG, "failed to create event");
free(event);
return NULL;
}
+
#else
+
if (pipe(event->pipe_fd) < 0)
{
- fprintf(stderr, "CreateEventW: failed to create event\n");
+ WLog_ERR(TAG, "failed to create event");
free(event);
return NULL;
}
-#endif
+#endif
WINPR_HANDLE_SET_TYPE(event, HANDLE_TYPE_EVENT);
handle = (HANDLE) event;
return NULL;
}
+#ifdef HAVE_EVENTFD_H
+#if defined(__UCLIBC__)
+static int eventfd_read(int fd, eventfd_t* value)
+{
+ return (read(fd, value, sizeof(*value)) == sizeof(*value)) ? 0 : -1;
+}
+
+static int eventfd_write(int fd, eventfd_t value)
+{
+ return (write(fd, &value, sizeof(value)) == sizeof(value)) ? 0 : -1;
+}
+#endif
+#endif
+
BOOL SetEvent(HANDLE hEvent)
{
ULONG Type;
int length;
BOOL status;
WINPR_EVENT* event;
-
status = FALSE;
if (winpr_Handle_GetInfo(hEvent, &Type, &Object))
{
event = (WINPR_EVENT*) Object;
-
#ifdef HAVE_EVENTFD_H
eventfd_t val = 1;
status = (length == 0) ? TRUE : FALSE;
#else
+
if (WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0)
{
length = write(event->pipe_fd[1], "-", 1);
{
status = TRUE;
}
+
#endif
}
int length;
BOOL status;
WINPR_EVENT* event;
-
status = FALSE;
if (winpr_Handle_GetInfo(hEvent, &Type, &Object))
if ((length > 0) && (!status))
status = TRUE;
+
#else
length = read(event->pipe_fd[0], &length, 1);
if ((length == 1) && (!status))
status = TRUE;
+
#endif
}
}
#ifndef _WIN32
WINPR_EVENT* event;
HANDLE handle = NULL;
-
event = (WINPR_EVENT*) malloc(sizeof(WINPR_EVENT));
if (event)
{
event->bAttached = TRUE;
event->bManualReset = bManualReset;
-
event->pipe_fd[0] = FileDescriptor;
event->pipe_fd[1] = -1;
-
WINPR_HANDLE_SET_TYPE(event, HANDLE_TYPE_EVENT);
handle = (HANDLE) event;
}
* Returns an event based on the handle returned by GetEventWaitObject()
*/
HANDLE CreateWaitObjectEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,
- BOOL bManualReset, BOOL bInitialState, void* pObject)
+ BOOL bManualReset, BOOL bInitialState, void* pObject)
{
#ifndef _WIN32
- return CreateFileDescriptorEventW(lpEventAttributes, bManualReset, bInitialState, (int) (ULONG_PTR) pObject);
+ return CreateFileDescriptorEventW(lpEventAttributes, bManualReset, bInitialState, (int)(ULONG_PTR) pObject);
#else
HANDLE hEvent = NULL;
-
DuplicateHandle(GetCurrentProcess(), pObject, GetCurrentProcess(), &hEvent, 0, FALSE, DUPLICATE_SAME_ACCESS);
-
return hEvent;
#endif
}
return -1;
event = (WINPR_EVENT*) Object;
+
if (Type == HANDLE_TYPE_NAMED_PIPE)
{
- WINPR_NAMED_PIPE *named = (WINPR_NAMED_PIPE *)hEvent;
- if (named->ServerMode) {
+ WINPR_NAMED_PIPE* named = (WINPR_NAMED_PIPE*)hEvent;
+
+ if (named->ServerMode)
+ {
return named->serverfd;
- } else {
+ }
+ else
+ {
return named->clientfd;
}
}
return -1;
event = (WINPR_EVENT*) Object;
-
event->pipe_fd[0] = FileDescriptor;
-
return 0;
#else
return -1;
#ifndef _WIN32
int fd;
void* obj;
-
fd = GetEventFileDescriptor(hEvent);
-
- obj = ((void*) (long) fd);
-
+ obj = ((void*)(long) fd);
return obj;
#else
return hEvent;
#include <winpr/synch.h>
#include <winpr/interlocked.h>
+#include "../log.h"
+#define TAG WINPR_TAG("sync")
+
#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0600))
BOOL InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL fPending, LPVOID* lpContext)
{
- fprintf(stderr, "%s: not implemented\n", __FUNCTION__);
+ WLog_ERR(TAG, "not implemented");
return FALSE;
}
BOOL InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpContext)
{
- fprintf(stderr, "%s: not implemented\n", __FUNCTION__);
+ WLog_ERR(TAG, "not implemented");
return FALSE;
}
VOID InitOnceInitialize(PINIT_ONCE InitOnce)
{
- fprintf(stderr, "%s: not implemented\n", __FUNCTION__);
+ WLog_ERR(TAG, "not implemented");
}
BOOL InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, PVOID Parameter, LPVOID* Context)
{
for (;;)
{
- switch((ULONG_PTR)InitOnce->Ptr & 3)
+ switch ((ULONG_PTR)InitOnce->Ptr & 3)
{
case 2:
/* already completed successfully */
return TRUE;
case 0:
+
/* first time */
if (InterlockedCompareExchangePointer(&InitOnce->Ptr, (PVOID)1, (PVOID)0) != (PVOID)0)
{
break;
default:
- fprintf(stderr, "%s: internal error\n", __FUNCTION__);
+ WLog_ERR(TAG, "internal error");
return FALSE;
}
#ifndef _WIN32
#include "../handle/handle.h"
+#include "../log.h"
+#define TAG WINPR_TAG("synch.semaphore")
HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName)
{
HANDLE handle;
WINPR_SEMAPHORE* semaphore;
-
semaphore = (WINPR_SEMAPHORE*) malloc(sizeof(WINPR_SEMAPHORE));
+
if (!semaphore)
return NULL;
if (pipe(semaphore->pipe_fd) < 0)
{
- fprintf(stderr, "CreateSemaphoreW: failed to create semaphore\n");
+ WLog_ERR(TAG, "failed to create semaphore");
free(semaphore);
return NULL;
}
#else
sem_init(semaphore->sem, 0, lMaximumCount);
#endif
-
#endif
}
WINPR_HANDLE_SET_TYPE(semaphore, HANDLE_TYPE_SEMAPHORE);
handle = (HANDLE) semaphore;
-
return handle;
}
HANDLE OpenSemaphoreW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
{
+ WLog_ERR(TAG, "not implemented");
return NULL;
}
HANDLE OpenSemaphoreA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
{
+ WLog_ERR(TAG, "not implemented");
return NULL;
}
if (Type == HANDLE_TYPE_SEMAPHORE)
{
semaphore = (WINPR_SEMAPHORE*) Object;
-
#ifdef WINPR_PIPE_SEMAPHORE
if (semaphore->pipe_fd[0] != -1)
}
#else
-
#if defined __APPLE__
semaphore_signal(*((winpr_sem_t*) semaphore->sem));
#else
sem_post((winpr_sem_t*) semaphore->sem);
#endif
-
#endif
return TRUE;
}
#define WITH_POSIX_TIMER 1
#endif
-#ifndef _WIN32
-
#include "../handle/handle.h"
+#ifndef _WIN32
+
#define WINPR_PIPE_SEMAPHORE 1
#if defined __APPLE__
#endif
+struct winpr_barrier
+{
+ DECLSPEC_ALIGN(4) LONG count;
+ LONG lTotalThreads;
+ LONG lSpinCount;
+ HANDLE event;
+};
+typedef struct winpr_barrier WINPR_BARRIER;
+
#endif /* WINPR_SYNCH_PRIVATE_H */
TestSynchInit.c
TestSynchEvent.c
TestSynchMutex.c
+ TestSynchBarrier.c
TestSynchCritical.c
TestSynchSemaphore.c
TestSynchThread.c
--- /dev/null
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+
+static int g_Count;
+static HANDLE g_Event;
+static CRITICAL_SECTION g_Lock;
+static SYNCHRONIZATION_BARRIER g_Barrier;
+
+static void* test_synch_barrier_thread_func(void* arg)
+{
+ BOOL status;
+ int count;
+
+ EnterCriticalSection(&g_Lock);
+ count = g_Count++;
+ LeaveCriticalSection(&g_Lock);
+ status = EnterSynchronizationBarrier(&g_Barrier, 0);
+
+ printf("Thread #%d status: %s\n", count,
+ status ? "TRUE" : "FALSE");
+
+ if (status)
+ {
+ SetEvent(g_Event);
+ }
+
+ return NULL;
+}
+
+int TestSynchBarrier(int argc, char* argv[])
+{
+ int index;
+ HANDLE threads[5];
+
+ g_Count = 0;
+
+ g_Event = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ InitializeCriticalSectionAndSpinCount(&g_Lock, 4000);
+
+ if (!InitializeSynchronizationBarrier(&g_Barrier, 5, -1))
+ return -1;
+
+ for (index = 0; index < 5; index++)
+ {
+ threads[index] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
+ test_synch_barrier_thread_func, NULL, 0, NULL);
+ }
+
+ WaitForSingleObject(g_Event, INFINITE);
+
+ if (g_Count != 5)
+ return -1;
+
+ printf("All threads have reached the barrier\n");
+
+ for (index = 0; index < 5; index++)
+ {
+ CloseHandle(threads[index]);
+ }
+
+ DeleteSynchronizationBarrier(&g_Barrier);
+
+ DeleteCriticalSection(&g_Lock);
+
+ CloseHandle(g_Event);
+
+ return 0;
+}
+
#include "../handle/handle.h"
+#include "../log.h"
+#define TAG WINPR_TAG("synch.timer")
+
#ifdef WITH_POSIX_TIMER
static BOOL g_WaitableTimerSignalHandlerInstalled = FALSE;
if ((timer_settime(timer->tid, 0, &(timer->timeout), NULL)) != 0)
{
- perror("timer_settime");
+ WLog_ERR(TAG,"timer_settime");
}
}
}
if (!g_WaitableTimerSignalHandlerInstalled)
{
struct sigaction action;
-
sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask, SIGALRM);
-
action.sa_flags = SA_RESTART | SA_SIGINFO;
action.sa_sigaction = (void*) &WaitableTimerSignalHandler;
-
sigaction(SIGALRM, &action, NULL);
-
g_WaitableTimerSignalHandlerInstalled = TRUE;
}
{
#ifdef HAVE_TIMERFD_H
int status;
-
timer->fd = timerfd_create(CLOCK_MONOTONIC, 0);
if (timer->fd <= 0)
close(timer->fd);
return -1;
}
+
#endif
}
else
{
#ifdef WITH_POSIX_TIMER
struct sigevent sigev;
-
InstallWaitableTimerSignalHandler();
-
ZeroMemory(&sigev, sizeof(struct sigevent));
-
sigev.sigev_notify = SIGEV_SIGNAL;
sigev.sigev_signo = SIGALRM;
sigev.sigev_value.sival_ptr = (void*) timer;
if ((timer_create(CLOCK_MONOTONIC, &sigev, &(timer->tid))) != 0)
{
- perror("timer_create");
+ WLog_ERR(TAG,"timer_create");
return -1;
}
+
#endif
}
timer->bInit = TRUE;
-
return 0;
}
{
HANDLE handle = NULL;
WINPR_TIMER* timer;
-
timer = (WINPR_TIMER*) malloc(sizeof(WINPR_TIMER));
if (timer)
{
WINPR_HANDLE_SET_TYPE(timer, HANDLE_TYPE_TIMER);
handle = (HANDLE) timer;
-
timer->fd = -1;
timer->lPeriod = 0;
timer->bManualReset = bManualReset;
HANDLE CreateWaitableTimerExA(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess)
{
BOOL bManualReset;
-
bManualReset = (dwFlags & CREATE_WAITABLE_TIMER_MANUAL_RESET) ? TRUE : FALSE;
-
return CreateWaitableTimerA(lpTimerAttributes, bManualReset, lpTimerName);
}
}
BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPeriod,
- PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, BOOL fResume)
+ PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, BOOL fResume)
{
ULONG Type;
PVOID Object;
- int status = 0;
WINPR_TIMER* timer;
+#ifdef WITH_POSIX_TIMER
LONGLONG seconds = 0;
LONGLONG nanoseconds = 0;
+#ifdef HAVE_TIMERFD_H
+ int status = 0;
+#endif /* HAVE_TIMERFD_H */
+#endif /* WITH_POSIX_TIMER */
if (!winpr_Handle_GetInfo(hTimer, &Type, &Object))
return FALSE;
return FALSE;
timer = (WINPR_TIMER*) Object;
-
timer->lPeriod = lPeriod; /* milliseconds */
timer->pfnCompletionRoutine = pfnCompletionRoutine;
timer->lpArgToCompletionRoutine = lpArgToCompletionRoutine;
}
#ifdef WITH_POSIX_TIMER
-
ZeroMemory(&(timer->timeout), sizeof(struct itimerspec));
if (lpDueTime->QuadPart < 0)
{
LONGLONG due = lpDueTime->QuadPart * (-1);
-
/* due time is in 100 nanosecond intervals */
-
seconds = (due / 10000000);
nanoseconds = ((due % 10000000) * 100);
}
}
else
{
- printf("SetWaitableTimer: implement absolute time\n");
+ WLog_ERR(TAG, "absolute time not implemented");
return FALSE;
}
if (status)
{
- printf("SetWaitableTimer timerfd_settime failure: %d\n", status);
+ WLog_ERR(TAG, "timerfd_settime failure: %d", status);
return FALSE;
}
+
#endif
}
else
{
if ((timer_settime(timer->tid, 0, &(timer->timeout), NULL)) != 0)
{
- perror("timer_settime");
+ WLog_ERR(TAG,"timer_settime");
return FALSE;
}
}
#endif
-
return TRUE;
}
BOOL SetWaitableTimerEx(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPeriod,
- PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay)
+ PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay)
{
ULONG Type;
PVOID Object;
void InsertTimerQueueTimer(WINPR_TIMER_QUEUE_TIMER** pHead, WINPR_TIMER_QUEUE_TIMER* timer)
{
WINPR_TIMER_QUEUE_TIMER* node;
-
+
if (!(*pHead))
{
*pHead = timer;
}
node = *pHead;
-
+
while (node->next)
{
if (timespec_compare(&(timer->ExpirationTime), &(node->ExpirationTime)) > 0)
prevNode = node;
node = node->next;
}
-
+
if (found)
{
if (prevNode)
{
prevNode->next = timer->next;
}
-
+
timer->next = NULL;
}
}
return 0;
timespec_gettimeofday(&CurrentTime);
-
node = timerQueue->activeHead;
while (node)
{
node->Callback(node->Parameter, TRUE);
node->FireCount++;
-
timerQueue->activeHead = node->next;
node->next = NULL;
{
InsertTimerQueueTimer(&(timerQueue->inactiveHead), node);
}
-
+
node = timerQueue->activeHead;
}
else
while (1)
{
pthread_mutex_lock(&(timerQueue->cond_mutex));
-
timespec_gettimeofday(&timeout);
if (!timerQueue->activeHead)
}
status = pthread_cond_timedwait(&(timerQueue->cond), &(timerQueue->cond_mutex), &timeout);
-
FireExpiredTimerQueueTimers(timerQueue);
-
pthread_mutex_unlock(&(timerQueue->cond_mutex));
if (timerQueue->bCancelled)
{
pthread_cond_init(&(timerQueue->cond), NULL);
pthread_mutex_init(&(timerQueue->cond_mutex), NULL);
-
pthread_mutex_init(&(timerQueue->mutex), NULL);
-
pthread_attr_init(&(timerQueue->attr));
timerQueue->param.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_attr_setschedparam(&(timerQueue->attr), &(timerQueue->param));
pthread_attr_setschedpolicy(&(timerQueue->attr), SCHED_FIFO);
pthread_create(&(timerQueue->thread), &(timerQueue->attr), TimerQueueThread, timerQueue);
-
return 0;
}
{
HANDLE handle = NULL;
WINPR_TIMER_QUEUE* timerQueue;
-
timerQueue = (WINPR_TIMER_QUEUE*) malloc(sizeof(WINPR_TIMER_QUEUE));
if (timerQueue)
{
ZeroMemory(timerQueue, sizeof(WINPR_TIMER_QUEUE));
-
WINPR_HANDLE_SET_TYPE(timerQueue, HANDLE_TYPE_TIMER_QUEUE);
handle = (HANDLE) timerQueue;
-
timerQueue->activeHead = NULL;
timerQueue->inactiveHead = NULL;
timerQueue->bCancelled = FALSE;
-
StartTimerQueueThread(timerQueue);
}
return FALSE;
timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue;
-
/* Cancel and delete timer queue timers */
-
pthread_mutex_lock(&(timerQueue->cond_mutex));
-
timerQueue->bCancelled = TRUE;
-
pthread_cond_signal(&(timerQueue->cond));
pthread_mutex_unlock(&(timerQueue->cond_mutex));
-
pthread_join(timerQueue->thread, &rvalue);
if (CompletionEvent == INVALID_HANDLE_VALUE)
else
{
/* Cancel all timers and return immediately */
-
/* Move all active timers to the inactive timer list */
-
node = timerQueue->activeHead;
while (node)
}
timerQueue->activeHead = NULL;
-
/* Once all timers are inactive, free them */
-
node = timerQueue->inactiveHead;
while (node)
{
nextNode = node->next;
-
free(node);
-
node = nextNode;
}
}
/* Delete timer queue */
-
pthread_cond_destroy(&(timerQueue->cond));
pthread_mutex_destroy(&(timerQueue->cond_mutex));
-
pthread_mutex_destroy(&(timerQueue->mutex));
-
pthread_attr_destroy(&(timerQueue->attr));
-
free(timerQueue);
if (CompletionEvent && (CompletionEvent != INVALID_HANDLE_VALUE))
}
BOOL CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue,
- WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags)
+ WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags)
{
struct timespec CurrentTime;
WINPR_TIMER_QUEUE* timerQueue;
return FALSE;
timespec_gettimeofday(&CurrentTime);
-
timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue;
timer = (WINPR_TIMER_QUEUE_TIMER*) malloc(sizeof(WINPR_TIMER_QUEUE_TIMER));
return FALSE;
WINPR_HANDLE_SET_TYPE(timer, HANDLE_TYPE_TIMER_QUEUE_TIMER);
- *((UINT_PTR*) phNewTimer) = (UINT_PTR) (HANDLE) timer;
-
+ *((UINT_PTR*) phNewTimer) = (UINT_PTR)(HANDLE) timer;
timespec_copy(&(timer->StartTime), &CurrentTime);
timespec_add_ms(&(timer->StartTime), DueTime);
timespec_copy(&(timer->ExpirationTime), &(timer->StartTime));
-
timer->Flags = Flags;
timer->DueTime = DueTime;
timer->Period = Period;
timer->Callback = Callback;
timer->Parameter = Parameter;
-
timer->timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue;
-
timer->FireCount = 0;
timer->next = NULL;
-
pthread_mutex_lock(&(timerQueue->cond_mutex));
-
InsertTimerQueueTimer(&(timerQueue->activeHead), timer);
-
pthread_cond_signal(&(timerQueue->cond));
pthread_mutex_unlock(&(timerQueue->cond_mutex));
-
return TRUE;
}
return FALSE;
timespec_gettimeofday(&CurrentTime);
-
timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue;
timer = (WINPR_TIMER_QUEUE_TIMER*) Timer;
-
pthread_mutex_lock(&(timerQueue->cond_mutex));
-
RemoveTimerQueueTimer(&(timerQueue->activeHead), timer);
RemoveTimerQueueTimer(&(timerQueue->inactiveHead), timer);
-
timer->DueTime = DueTime;
timer->Period = Period;
timer->next = NULL;
-
timespec_copy(&(timer->StartTime), &CurrentTime);
timespec_add_ms(&(timer->StartTime), DueTime);
timespec_copy(&(timer->ExpirationTime), &(timer->StartTime));
-
InsertTimerQueueTimer(&(timerQueue->activeHead), timer);
-
pthread_cond_signal(&(timerQueue->cond));
pthread_mutex_unlock(&(timerQueue->cond_mutex));
-
return TRUE;
}
timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue;
timer = (WINPR_TIMER_QUEUE_TIMER*) Timer;
-
pthread_mutex_lock(&(timerQueue->cond_mutex));
if (CompletionEvent == INVALID_HANDLE_VALUE)
else
{
/* Cancel timer and return immediately */
-
RemoveTimerQueueTimer(&(timerQueue->activeHead), timer);
}
pthread_cond_signal(&(timerQueue->cond));
pthread_mutex_unlock(&(timerQueue->cond_mutex));
-
free(timer);
if (CompletionEvent && (CompletionEvent != INVALID_HANDLE_VALUE))
#include "../thread/thread.h"
#include <winpr/thread.h>
+#include "../log.h"
+#define TAG WINPR_TAG("sync.wait")
+
/**
* WaitForSingleObject
* WaitForSingleObjectEx
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 0
-int clock_gettime(int clk_id, struct timespec *t)
+int clock_gettime(int clk_id, struct timespec* t)
{
UINT64 time;
double seconds;
double nseconds;
mach_timebase_info_data_t timebase;
-
mach_timebase_info(&timebase);
time = mach_absolute_time();
-
nseconds = ((double) time * (double) timebase.numer) / ((double) timebase.denom);
seconds = ((double) time * (double) timebase.numer) / ((double) timebase.denom * 1e9);
-
t->tv_sec = seconds;
t->tv_nsec = nseconds;
-
return 0;
}
#if !defined(HAVE_PTHREAD_GNU_EXT)
#include <pthread.h>
-static long long ts_difftime(const struct timespec *o,
- const struct timespec *n)
+static long long ts_difftime(const struct timespec* o,
+ const struct timespec* n)
{
long long oldValue = o->tv_sec * 1000000000LL + o->tv_nsec;
long long newValue = n->tv_sec * 1000000000LL + n->tv_nsec;
-
return newValue - oldValue;
}
-static int pthread_timedjoin_np(pthread_t td, void **res,
- struct timespec *timeout)
+static int pthread_timedjoin_np(pthread_t td, void** res,
+ struct timespec* timeout)
{
struct timespec timenow;
struct timespec sleepytime;
return pthread_join(td, res);
nanosleep(&sleepytime, NULL);
-
clock_gettime(CLOCK_MONOTONIC, &timenow);
if (ts_difftime(timeout, &timenow) >= 0)
}
#if defined(__FreeBSD__)
- /*the only way to get it work is to remove the static*/
- int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *timeout)
+/*the only way to get it work is to remove the static*/
+int pthread_mutex_timedlock(pthread_mutex_t* mutex, const struct timespec* timeout)
#else
- static int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *timeout)
+static int pthread_mutex_timedlock(pthread_mutex_t* mutex, const struct timespec* timeout)
#endif
{
struct timespec timenow;
struct timespec sleepytime;
int retcode;
-
/* This is just to avoid a completely busy wait */
sleepytime.tv_sec = 0;
sleepytime.tv_nsec = 10000000; /* 10ms */
- while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY)
+ while ((retcode = pthread_mutex_trylock(mutex)) == EBUSY)
{
clock_gettime(CLOCK_MONOTONIC, &timenow);
return ETIMEDOUT;
}
- nanosleep (&sleepytime, NULL);
+ nanosleep(&sleepytime, NULL);
}
return retcode;
}
#endif
-static void ts_add_ms(struct timespec *ts, DWORD dwMilliseconds)
+static void ts_add_ms(struct timespec* ts, DWORD dwMilliseconds)
{
ts->tv_sec += dwMilliseconds / 1000L;
ts->tv_nsec += (dwMilliseconds % 1000L) * 1000000L;
-
ts->tv_sec += ts->tv_nsec / 1000000000L;
ts->tv_nsec = ts->tv_nsec % 1000000000L;
}
static int waitOnFd(int fd, DWORD dwMilliseconds)
{
int status;
-
#ifdef HAVE_POLL_H
struct pollfd pollfds;
-
pollfds.fd = fd;
pollfds.events = POLLIN;
pollfds.revents = 0;
#else
struct timeval timeout;
fd_set rfds;
-
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
ZeroMemory(&timeout, sizeof(timeout));
status = select(fd + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout);
}
while (status < 0 && (errno == EINTR));
-#endif
+#endif
return status;
}
if (!winpr_Handle_GetInfo(hHandle, &Type, &Object))
{
- fprintf(stderr, "WaitForSingleObject failed: invalid hHandle.\n");
+ WLog_ERR(TAG, "invalid hHandle.");
return WAIT_FAILED;
}
int status = 0;
WINPR_THREAD* thread;
void* thread_status = NULL;
-
thread = (WINPR_THREAD*) Object;
if (thread->started)
clock_gettime(CLOCK_MONOTONIC, &timeout);
ts_add_ms(&timeout, dwMilliseconds);
-
status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout);
if (ETIMEDOUT == status)
if (status != 0)
{
- fprintf(stderr, "WaitForSingleObject: pthread_join failure: [%d] %s\n",
- status, strerror(status));
+ WLog_ERR(TAG, "pthread_join failure: [%d] %s",
+ status, strerror(status));
}
if (thread_status)
- thread->dwExitCode = ((DWORD) (size_t) thread_status);
+ thread->dwExitCode = ((DWORD)(size_t) thread_status);
}
}
else if (Type == HANDLE_TYPE_PROCESS)
{
WINPR_PROCESS* process;
-
process = (WINPR_PROCESS*) Object;
if (waitpid(process->pid, &(process->status), 0) != -1)
{
- fprintf(stderr, "WaitForSingleObject: waitpid failure [%d] %s\n", errno, strerror(errno));
+ WLog_ERR(TAG, "waitpid failure [%d] %s", errno, strerror(errno));
return WAIT_FAILED;
}
else if (Type == HANDLE_TYPE_MUTEX)
{
WINPR_MUTEX* mutex;
-
mutex = (WINPR_MUTEX*) Object;
if (dwMilliseconds != INFINITE)
{
int status;
struct timespec timeout;
-
clock_gettime(CLOCK_MONOTONIC, &timeout);
- ts_add_ms(&timeout, dwMilliseconds);
-
+ ts_add_ms(&timeout, dwMilliseconds);
status = pthread_mutex_timedlock(&mutex->mutex, &timeout);
if (ETIMEDOUT == status)
{
int status;
WINPR_EVENT* event;
-
event = (WINPR_EVENT*) Object;
-
status = waitOnFd(event->pipe_fd[0], dwMilliseconds);
+
if (status < 0)
{
- fprintf(stderr, "WaitForSingleObject: event select() failure [%d] %s\n", errno, strerror(errno));
+ WLog_ERR(TAG, "event select() failure [%d] %s", errno, strerror(errno));
return WAIT_FAILED;
}
else if (Type == HANDLE_TYPE_SEMAPHORE)
{
WINPR_SEMAPHORE* semaphore;
-
semaphore = (WINPR_SEMAPHORE*) Object;
-
#ifdef WINPR_PIPE_SEMAPHORE
+
if (semaphore->pipe_fd[0] != -1)
{
int status;
int length;
-
status = waitOnFd(semaphore->pipe_fd[0], dwMilliseconds);
+
if (status < 0)
{
- fprintf(stderr, "WaitForSingleObject: semaphore select() failure [%d] %s\n", errno, strerror(errno));
+ WLog_ERR(TAG, "semaphore select() failure [%d] %s", errno, strerror(errno));
return WAIT_FAILED;
}
if (length != 1)
{
- fprintf(stderr, "WaitForSingleObject: semaphore read failure [%d] %s\n", errno, strerror(errno));
+ WLog_ERR(TAG, "semaphore read failure [%d] %s", errno, strerror(errno));
return WAIT_FAILED;
}
}
-#else
+#else
#if defined __APPLE__
semaphore_wait(*((winpr_sem_t*) semaphore->sem));
#else
sem_wait((winpr_sem_t*) semaphore->sem);
#endif
-
#endif
}
else if (Type == HANDLE_TYPE_TIMER)
{
WINPR_TIMER* timer;
-
timer = (WINPR_TIMER*) Object;
-
#ifdef HAVE_EVENTFD_H
+
if (timer->fd != -1)
{
int status;
UINT64 expirations;
-
status = waitOnFd(timer->fd, dwMilliseconds);
+
if (status < 0)
{
- fprintf(stderr, "WaitForSingleObject: timer select() failure [%d] %s\n", errno, strerror(errno));
+ WLog_ERR(TAG, "timer select() failure [%d] %s", errno, strerror(errno));
return WAIT_FAILED;
}
if (errno == ETIMEDOUT)
return WAIT_TIMEOUT;
- fprintf(stderr, "WaitForSingleObject: timer read() failure [%d] %s\n", errno, strerror(errno));
+ WLog_ERR(TAG, "timer read() failure [%d] %s", errno, strerror(errno));
}
else
{
- fprintf(stderr, "WaitForSingleObject: timer read() failure - incorrect number of bytes read");
+ WLog_ERR(TAG, "timer read() failure - incorrect number of bytes read");
}
return WAIT_FAILED;
}
else
{
- fprintf(stderr, "WaitForSingleObject: invalid timer file descriptor\n");
+ WLog_ERR(TAG, "invalid timer file descriptor");
return WAIT_FAILED;
}
#else
- fprintf(stderr, "WaitForSingleObject: file descriptors not supported\n");
+ WLog_ERR(TAG, "file descriptors not supported");
return WAIT_FAILED;
#endif
}
int fd;
int status;
WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object;
-
fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd;
if (fd == -1)
{
- fprintf(stderr, "WaitForSingleObject: invalid pipe file descriptor\n");
+ WLog_ERR(TAG, "invalid pipe file descriptor");
return WAIT_FAILED;
}
status = waitOnFd(fd, dwMilliseconds);
+
if (status < 0)
{
- fprintf(stderr, "WaitForSingleObject: named pipe select() failure [%d] %s\n", errno, strerror(errno));
+ WLog_ERR(TAG, "named pipe select() failure [%d] %s", errno, strerror(errno));
return WAIT_FAILED;
}
}
else
{
- fprintf(stderr, "WaitForSingleObject: unknown handle type %d\n", (int) Type);
+ WLog_ERR(TAG, "unknown handle type %d", (int) Type);
}
return WAIT_OBJECT_0;
DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable)
{
- fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__);
+ WLog_ERR(TAG, "Function not implemented.");
assert(0);
return WAIT_OBJECT_0;
}
ULONG Type;
PVOID Object;
#ifdef HAVE_POLL_H
- struct pollfd *pollfds;
+ struct pollfd* pollfds;
#else
int maxfd;
fd_set fds;
if (!nCount || (nCount > MAXIMUM_WAIT_OBJECTS))
{
- fprintf(stderr, "%s: invalid handles count(%d)\n", __FUNCTION__, nCount);
+ WLog_ERR(TAG, "invalid handles count(%d)", nCount);
return WAIT_FAILED;
}
maxfd = 0;
FD_ZERO(&fds);
ZeroMemory(&timeout, sizeof(timeout));
-
#endif
if (bWaitAll)
{
- fprintf(stderr, "%s: bWaitAll not yet implemented\n", __FUNCTION__);
+ WLog_ERR(TAG, "bWaitAll not yet implemented");
assert(0);
}
{
if (!winpr_Handle_GetInfo(lpHandles[index], &Type, &Object))
{
- fprintf(stderr, "%s: invalid handle\n", __FUNCTION__);
-
+ WLog_ERR(TAG, "invalid handle");
return WAIT_FAILED;
}
if (fd == -1)
{
- fprintf(stderr, "%s: invalid event file descriptor\n", __FUNCTION__);
+ WLog_ERR(TAG, "invalid event file descriptor");
return WAIT_FAILED;
}
}
#ifdef WINPR_PIPE_SEMAPHORE
fd = ((WINPR_SEMAPHORE*) Object)->pipe_fd[0];
#else
- fprintf(stderr, "%s: semaphore not supported\n", __FUNCTION__);
+ WLog_ERR(TAG, "semaphore not supported");
return WAIT_FAILED;
#endif
}
if (fd == -1)
{
- fprintf(stderr, "%s: invalid timer file descriptor\n", __FUNCTION__);
+ WLog_ERR(TAG, "invalid timer file descriptor");
return WAIT_FAILED;
}
}
if (fd == -1)
{
- fprintf(stderr, "%s: invalid timer file descriptor\n", __FUNCTION__);
+ WLog_ERR(TAG, "invalid timer file descriptor");
return WAIT_FAILED;
}
}
else
{
- fprintf(stderr, "%s: unknown handle type %d\n", __FUNCTION__, (int) Type);
+ WLog_ERR(TAG, "unknown handle type %d", (int) Type);
return WAIT_FAILED;
}
if (fd == -1)
{
- fprintf(stderr, "%s: invalid file descriptor\n", __FUNCTION__);
+ WLog_ERR(TAG, "invalid file descriptor");
return WAIT_FAILED;
}
if (fd > maxfd)
maxfd = fd;
+
#endif
}
#ifdef HAVE_POLL_H
+
do
{
status = poll(pollfds, nCount, dwMilliseconds);
}
while (status < 0 && errno == EINTR);
+
#else
+
if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
{
timeout.tv_sec = dwMilliseconds / 1000;
do
{
status = select(maxfd + 1, &fds, 0, 0,
- (dwMilliseconds == INFINITE) ? NULL : &timeout);
+ (dwMilliseconds == INFINITE) ? NULL : &timeout);
}
while (status < 0 && errno == EINTR);
+
#endif
if (status < 0)
{
- fprintf(stderr, "%s: select() failure [%d] %s\n", __FUNCTION__, errno, strerror(errno));
+ WLog_ERR(TAG, "select() failure [%d] %s", errno, strerror(errno));
return WAIT_FAILED;
}
}
#ifdef HAVE_POLL_H
+
if (pollfds[index].revents & POLLIN)
#else
if (FD_ISSET(fd, &fds))
if (Type == HANDLE_TYPE_SEMAPHORE)
{
int length;
-
length = read(fd, &length, 1);
if (length != 1)
{
- fprintf(stderr, "%s: semaphore read() failure [%d] %s\n", __FUNCTION__, errno, strerror(errno));
+ WLog_ERR(TAG, "semaphore read() failure [%d] %s", errno, strerror(errno));
return WAIT_FAILED;
}
}
{
int length;
UINT64 expirations;
-
length = read(fd, (void*) &expirations, sizeof(UINT64));
if (length != 8)
if (errno == ETIMEDOUT)
return WAIT_TIMEOUT;
- fprintf(stderr, "%s: timer read() failure [%d] %s\n", __FUNCTION__, errno, strerror(errno));
+ WLog_ERR(TAG, "timer read() failure [%d] %s", errno, strerror(errno));
}
else
{
- fprintf(stderr, "%s: timer read() failure - incorrect number of bytes read", __FUNCTION__);
+ WLog_ERR(TAG, "timer read() failure - incorrect number of bytes read");
}
return WAIT_FAILED;
}
}
- fprintf(stderr, "%s: failed (unknown error)\n", __FUNCTION__);
+ WLog_ERR(TAG, "failed (unknown error)");
return WAIT_FAILED;
}
DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds, BOOL bAlertable)
{
- fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__);
+ WLog_ERR(TAG, "[ERROR] %s: Function not implemented.");
assert(0);
return 0;
}
DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable)
{
- fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__);
+ WLog_ERR(TAG, "Function not implemented.");
assert(0);
return 0;
}
#include <sys/sysctl.h>
#endif
+#include "../log.h"
+#define TAG WINPR_TAG("sysinfo")
+
static DWORD GetProcessorArchitecture()
{
DWORD cpuArch = PROCESSOR_ARCHITECTURE_UNKNOWN;
-
#if defined(_M_AMD64)
cpuArch = PROCESSOR_ARCHITECTURE_AMD64;
#elif defined(_M_IX86)
#elif defined(_M_ALPHA)
cpuArch = PROCESSOR_ARCHITECTURE_ALPHA;
#endif
-
return cpuArch;
}
static DWORD GetNumberOfProcessors()
{
DWORD numCPUs = 1;
-
/* TODO: iOS */
-
#if defined(__linux__) || defined(__sun) || defined(_AIX)
numCPUs = (DWORD) sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(__MACOSX__) || \
{
int mib[4];
size_t length = sizeof(numCPUs);
-
mib[0] = CTL_HW;
- #if defined(__FreeBSD__)
- mib[1] = HW_NCPU;
- #else
- mib[1] = HW_AVAILCPU;
- #endif
-
+#if defined(__FreeBSD__)
+ mib[1] = HW_NCPU;
+#else
+ mib[1] = HW_AVAILCPU;
+#endif
sysctl(mib, 2, &numCPUs, &length, NULL, 0);
if (numCPUs < 1)
#elif defined(__sgi)
numCPUs = (DWORD) sysconf(_SC_NPROC_ONLN);
#endif
-
return numCPUs;
}
{
lpSystemInfo->wProcessorArchitecture = GetProcessorArchitecture();
lpSystemInfo->wReserved = 0;
-
lpSystemInfo->dwPageSize = 0;
lpSystemInfo->lpMinimumApplicationAddress = NULL;
lpSystemInfo->lpMaximumApplicationAddress = NULL;
lpSystemInfo->dwActiveProcessorMask = 0;
-
lpSystemInfo->dwNumberOfProcessors = GetNumberOfProcessors();
lpSystemInfo->dwProcessorType = 0;
-
lpSystemInfo->dwAllocationGranularity = 0;
-
lpSystemInfo->wProcessorLevel = 0;
lpSystemInfo->wProcessorRevision = 0;
}
char* dot;
int length;
char hostname[256];
-
gethostname(hostname, sizeof(hostname));
length = strlen(hostname);
-
dot = strchr(hostname, '.');
if (dot)
CopyMemory(lpBuffer, hostname, length);
lpBuffer[length] = '\0';
-
return TRUE;
}
case ComputerNamePhysicalDnsHostname:
case ComputerNamePhysicalDnsDomain:
case ComputerNamePhysicalDnsFullyQualified:
-
if (*lpnSize <= length)
{
*lpnSize = length + 1;
CopyMemory(lpBuffer, hostname, length);
lpBuffer[length] = '\0';
-
break;
default:
return FALSE;
- break;
}
return TRUE;
BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD nSize)
{
- fprintf(stderr, "GetComputerNameExW unimplemented\n");
+ WLog_ERR(TAG, "GetComputerNameExW unimplemented");
return 0;
}
BOOL GetVersionExA(LPOSVERSIONINFOA lpVersionInformation)
{
/* Windows 7 SP1 Version Info */
-
if ((lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOA)) ||
- (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA)))
+ (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA)))
{
lpVersionInformation->dwMajorVersion = 6;
lpVersionInformation->dwMinorVersion = 1;
if (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA))
{
LPOSVERSIONINFOEXA lpVersionInformationEx = (LPOSVERSIONINFOEXA) lpVersionInformation;
-
lpVersionInformationEx->wServicePackMajor = 1;
lpVersionInformationEx->wServicePackMinor = 0;
lpVersionInformationEx->wSuiteMask = 0;
BOOL GetVersionExW(LPOSVERSIONINFOW lpVersionInformation)
{
- fprintf(stderr, "GetVersionExW unimplemented\n");
+ WLog_ERR(TAG, "GetVersionExW unimplemented");
return 1;
}
time_t ct = 0;
struct tm* stm = NULL;
WORD wMilliseconds = 0;
-
ct = time(NULL);
- wMilliseconds = (WORD) (GetTickCount() % 1000);
-
+ wMilliseconds = (WORD)(GetTickCount() % 1000);
stm = gmtime(&ct);
-
ZeroMemory(lpSystemTime, sizeof(SYSTEMTIME));
if (stm)
{
- lpSystemTime->wYear = (WORD) (stm->tm_year + 1900);
- lpSystemTime->wMonth = (WORD) (stm->tm_mon + 1);
+ lpSystemTime->wYear = (WORD)(stm->tm_year + 1900);
+ lpSystemTime->wMonth = (WORD)(stm->tm_mon + 1);
lpSystemTime->wDayOfWeek = (WORD) stm->tm_wday;
lpSystemTime->wDay = (WORD) stm->tm_mday;
lpSystemTime->wHour = (WORD) stm->tm_hour;
time_t ct = 0;
struct tm* ltm = NULL;
WORD wMilliseconds = 0;
-
ct = time(NULL);
- wMilliseconds = (WORD) (GetTickCount() % 1000);
-
+ wMilliseconds = (WORD)(GetTickCount() % 1000);
ltm = localtime(&ct);
-
ZeroMemory(lpSystemTime, sizeof(SYSTEMTIME));
if (ltm)
{
- lpSystemTime->wYear = (WORD) (ltm->tm_year + 1900);
- lpSystemTime->wMonth = (WORD) (ltm->tm_mon + 1);
+ lpSystemTime->wYear = (WORD)(ltm->tm_year + 1900);
+ lpSystemTime->wMonth = (WORD)(ltm->tm_mon + 1);
lpSystemTime->wDayOfWeek = (WORD) ltm->tm_wday;
lpSystemTime->wDay = (WORD) ltm->tm_mday;
lpSystemTime->wHour = (WORD) ltm->tm_hour;
VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
{
ULARGE_INTEGER time64;
-
time64.u.HighPart = 0;
-
/* time represented in tenths of microseconds since midnight of January 1, 1601 */
-
time64.QuadPart = time(NULL) + 11644473600LL; /* Seconds since January 1, 1601 */
time64.QuadPart *= 10000000; /* Convert timestamp to tenths of a microsecond */
-
lpSystemTimeAsFileTime->dwLowDateTime = time64.LowPart;
lpSystemTimeAsFileTime->dwHighDateTime = time64.HighPart;
}
DWORD GetTickCount(void)
{
DWORD ticks = 0;
-
#ifdef __linux__
-
struct timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC_RAW, &ts))
ticks = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
#else
-
/**
* FIXME: this is relative to the Epoch time, and we
* need to return a value relative to the system uptime.
*/
-
struct timeval tv;
if (!gettimeofday(&tv, NULL))
ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
#endif
-
return ticks;
}
#endif // _WIN32
ULONGLONG GetTickCount64(void)
{
ULONGLONG ticks = 0;
-
#if defined(__linux__)
-
struct timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC_RAW, &ts))
ticks = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
#elif defined(_WIN32)
-
ticks = (ULONGLONG) GetTickCount();
-
#else
-
/**
* FIXME: this is relative to the Epoch time, and we
* need to return a value relative to the system uptime.
*/
-
struct timeval tv;
if (!gettimeofday(&tv, NULL))
ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
#endif
-
return ticks;
}
#if defined(__GNUC__) && defined(__AVX__)
#define xgetbv(_func_, _lo_, _hi_) \
- __asm__ __volatile__ ("xgetbv" : "=a" (_lo_), "=d" (_hi_) : "c" (_func_))
+ __asm__ __volatile__ ("xgetbv" : "=a" (_lo_), "=d" (_hi_) : "c" (_func_))
#endif
#define D_BIT_MMX (1<<23)
#define D_BIT_3DN (1<<30)
#define C_BIT_SSE3 (1<<0)
#define C_BIT_PCLMULQDQ (1<<1)
+#define C_BIT_LZCNT (1<<5)
#define C_BIT_3DNP (1<<8)
#define C_BIT_3DNP (1<<8)
#define C_BIT_SSSE3 (1<<9)
#define E_BITS_AVX (E_BIT_XMM|E_BIT_YMM)
static void cpuid(
- unsigned info,
- unsigned *eax,
- unsigned *ebx,
- unsigned *ecx,
- unsigned *edx)
+ unsigned info,
+ unsigned* eax,
+ unsigned* ebx,
+ unsigned* ecx,
+ unsigned* edx)
{
#ifdef __GNUC__
- *eax = *ebx = *ecx = *edx = 0;
-
- __asm volatile
- (
- /* The EBX (or RBX register on x86_64) is used for the PIC base address
- * and must not be corrupted by our inline assembly.
- */
+ *eax = *ebx = *ecx = *edx = 0;
+ __asm volatile
+ (
+ /* The EBX (or RBX register on x86_64) is used for the PIC base address
+ * and must not be corrupted by our inline assembly.
+ */
#ifdef _M_IX86
- "mov %%ebx, %%esi;"
- "cpuid;"
- "xchg %%ebx, %%esi;"
+ "mov %%ebx, %%esi;"
+ "cpuid;"
+ "xchg %%ebx, %%esi;"
#else
- "mov %%rbx, %%rsi;"
- "cpuid;"
- "xchg %%rbx, %%rsi;"
+ "mov %%rbx, %%rsi;"
+ "cpuid;"
+ "xchg %%rbx, %%rsi;"
#endif
- : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
- : "0" (info)
- );
-
+ : "=a"(*eax), "=S"(*ebx), "=c"(*ecx), "=d"(*edx)
+ : "0"(info)
+ );
#elif defined(_MSC_VER)
int a[4];
__cpuid(a, info);
// From linux kernel uapi/linux/auxvec.h
#define AT_HWCAP 16
-static unsigned GetARMCPUCaps(void){
+static unsigned GetARMCPUCaps(void)
+{
unsigned caps = 0;
-
- int fd = open ("/proc/self/auxv", O_RDONLY);
+ int fd = open("/proc/self/auxv", O_RDONLY);
if (fd == -1)
return 0;
unsigned a_val; /* Integer value */
} auxvec;
- while (1){
+ while (1)
+ {
int num;
- num = read(fd, (char *)&auxvec, sizeof(auxvec));
+ num = read(fd, (char*)&auxvec, sizeof(auxvec));
+
if (num < 1 || (auxvec.a_type == 0 && auxvec.a_val == 0))
- break;
- if (auxvec.a_type == AT_HWCAP)
+ break;
+
+ if (auxvec.a_type == AT_HWCAP)
{
- caps = auxvec.a_val;
+ caps = auxvec.a_val;
}
}
+
close(fd);
return caps;
}
case PF_ARM_NEON:
if (caps & HWCAP_NEON)
ret = TRUE;
+
break;
+
case PF_ARM_THUMB:
if (caps & HWCAP_THUMB)
ret = TRUE;
+
case PF_ARM_VFP_32_REGISTERS_AVAILABLE:
if (caps & HWCAP_VFPD32)
ret = TRUE;
+
case PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE:
if ((caps & HWCAP_IDIVA) || (caps & HWCAP_IDIVT))
ret = TRUE;
+
case PF_ARM_VFP3:
if (caps & HWCAP_VFPv3)
ret = TRUE;
+
break;
+
case PF_ARM_JAZELLE:
if (caps & HWCAP_JAVA)
ret = TRUE;
+
break;
+
case PF_ARM_DSP:
if (caps & HWCAP_EDSP)
ret = TRUE;
+
break;
+
case PF_ARM_MPU:
if (caps & HWCAP_EDSP)
ret = TRUE;
+
break;
+
case PF_ARM_THUMB2:
if ((caps & HWCAP_IDIVT) || (caps & HWCAP_VFPv4))
ret = TRUE;
+
break;
+
case PF_ARM_T2EE:
if (caps & HWCAP_THUMBEE)
ret = TRUE;
+
break;
+
case PF_ARM_INTEL_WMMX:
if (caps & HWCAP_IWMMXT)
ret = TRUE;
+
break;
+
default:
break;
}
+
#elif defined(__APPLE__) // __linux__
+
switch (ProcessorFeature)
{
case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
ret = TRUE;
break;
}
+
#endif // __linux__
#elif defined(_M_IX86_AMD64)
#ifdef __GNUC__
unsigned a, b, c, d;
-
cpuid(1, &a, &b, &c, &d);
switch (ProcessorFeature)
{
- case PF_MMX_INSTRUCTIONS_AVAILABLE:
+ case PF_MMX_INSTRUCTIONS_AVAILABLE:
if (d & D_BIT_MMX)
ret = TRUE;
+
break;
- case PF_XMMI_INSTRUCTIONS_AVAILABLE:
+
+ case PF_XMMI_INSTRUCTIONS_AVAILABLE:
if (d & D_BIT_SSE)
ret = TRUE;
+
break;
- case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
+
+ case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
if (d & D_BIT_SSE2)
ret = TRUE;
+
break;
+
case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
if (d & D_BIT_3DN)
ret = TRUE;
+
break;
- case PF_SSE3_INSTRUCTIONS_AVAILABLE:
+
+ case PF_SSE3_INSTRUCTIONS_AVAILABLE:
if (c & C_BIT_SSE3)
ret = TRUE;
+
break;
+
default:
break;
}
case PF_EX_ARM_VFP1:
if (caps & HWCAP_VFP)
ret = TRUE;
+
break;
+
case PF_EX_ARM_VFP3D16:
if (caps & HWCAP_VFPv3D16)
ret = TRUE;
+
break;
+
case PF_EX_ARM_VFP4:
if (caps & HWCAP_VFPv4)
ret = TRUE;
+
break;
+
case PF_EX_ARM_IDIVA:
if (caps & HWCAP_IDIVA)
ret = TRUE;
+
break;
+
case PF_EX_ARM_IDIVT:
if (caps & HWCAP_IDIVT)
ret = TRUE;
+
break;
}
+
#endif // __linux__
#elif defined(_M_IX86_AMD64)
unsigned a, b, c, d;
switch (ProcessorFeature)
{
+ case PF_EX_LZCNT:
+ if (c & C_BIT_LZCNT)
+ ret = TRUE;
+
+ break;
+
case PF_EX_3DNOW_PREFETCH:
if (c & C_BIT_3DNP)
ret = TRUE;
+
break;
+
case PF_EX_SSSE3:
if (c & C_BIT_SSSE3)
ret = TRUE;
+
break;
+
case PF_EX_SSE41:
if (c & C_BIT_SSE41)
ret = TRUE;
+
break;
+
case PF_EX_SSE42:
if (c & C_BIT_SSE42)
ret = TRUE;
+
break;
#if defined(__GNUC__) && defined(__AVX__)
+
case PF_EX_AVX:
case PF_EX_FMA:
case PF_EX_AVX_AES:
case PF_EX_AVX:
ret = TRUE;
break;
+
case PF_EX_FMA:
if (c & C_BIT_FMA)
ret = TRUE;
+
break;
+
case PF_EX_AVX_AES:
if (c & C_BIT_AES)
ret = TRUE;
+
break;
+
case PF_EX_AVX_PCLMULQDQ:
if (c & C_BIT_PCLMULQDQ)
ret = TRUE;
+
break;
}
}
- }
+ }
break;
#endif //__AVX__
+
default:
break;
}
+
#endif
return ret;
}
#include <unistd.h>
#endif
+#include "../log.h"
+#define TAG WINPR_TAG("thread")
+
/**
* CommandLineToArgvW function:
* http://msdn.microsoft.com/en-us/library/windows/desktop/bb776391/
pArgs = NULL;
numArgs = 0;
-
lpEscapedCmdLine = NULL;
cmdLineLength = strlen(lpCmdLine);
-
lpEscapedChars = (BOOL*) malloc((cmdLineLength + 1) * sizeof(BOOL));
ZeroMemory(lpEscapedChars, (cmdLineLength + 1) * sizeof(BOOL));
{
int i, n;
char* pLastEnd = NULL;
-
lpEscapedCmdLine = (char*) malloc((cmdLineLength + 1) * sizeof(char));
-
p = (char*) lpCmdLine;
pLastEnd = (char*) lpCmdLine;
pOutput = (char*) lpEscapedCmdLine;
CopyMemory(pOutput, p, length);
pOutput += length;
p += length;
-
break;
}
}
n = (pEnd - pBeg) - 1;
-
length = (pBeg - pLastEnd);
CopyMemory(pOutput, p, length);
pOutput += length;
*pOutput = '"';
pOutput++;
-
pLastEnd = p;
}
*pOutput = '\0';
pOutput++;
-
lpCmdLine = (LPCSTR) lpEscapedCmdLine;
cmdLineLength = strlen(lpCmdLine);
}
while (currentIndex < cmdLineLength - 1)
{
index = strcspn(p, " \t");
-
currentIndex += (index + 1);
p = (char*) &lpCmdLine[currentIndex];
-
maxNumArgs++;
}
maxBufferSize = (maxNumArgs * (sizeof(char*))) + (cmdLineLength + 1);
-
buffer = (char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, maxBufferSize);
if (!buffer)
pArgs = (LPSTR*) buffer;
pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))];
-
numArgs = 0;
currentIndex = 0;
p = (char*) lpCmdLine;
if (p[index] != '"')
{
/* no whitespace escaped with double quotes */
-
p = &p[index + 1];
pEnd = p - 1;
-
length = (pEnd - pBeg);
-
CopyMemory(pOutput, pBeg, length);
pOutput[length] = '\0';
pArgs[numArgs++] = pOutput;
if (p[index] != '"')
{
- printf("CommandLineToArgvA parsing error: uneven number of unescaped double quotes!\n");
+ WLog_ERR(TAG, "parsing error: uneven number of unescaped double quotes!");
}
if (p[index] == '\0')
free(lpEscapedChars);
*pNumArgs = numArgs;
-
return pArgs;
}
ini.c
sam.c
ntlm.c
+ image.c
print.c
stream.c
+ debug.c
cmdline.c
ssl.c)
+if (ANDROID)
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+endif()
+
winpr_module_add(${${MODULE_PREFIX}_SRCS}
${${MODULE_PREFIX}_COLLECTIONS_SRCS}
${${MODULE_PREFIX}_TRIO_SRCS}
* Gets or sets the number of elements that the ArrayList can contain.
*/
-int ArrayList_Capacity(wArrayList* arrayList)
+int ArrayList_Capacity(wArrayList *arrayList)
{
return arrayList->capacity;
}
* Gets the number of elements actually contained in the ArrayList.
*/
-int ArrayList_Count(wArrayList* arrayList)
+int ArrayList_Count(wArrayList *arrayList)
{
return arrayList->size;
}
* Gets a value indicating whether the ArrayList has a fixed size.
*/
-BOOL ArrayList_IsFixedSized(wArrayList* arrayList)
+BOOL ArrayList_IsFixedSized(wArrayList *arrayList)
{
return FALSE;
}
* Gets a value indicating whether the ArrayList is read-only.
*/
-BOOL ArrayList_IsReadOnly(wArrayList* arrayList)
+BOOL ArrayList_IsReadOnly(wArrayList *arrayList)
{
return FALSE;
}
* Gets a value indicating whether access to the ArrayList is synchronized (thread safe).
*/
-BOOL ArrayList_IsSynchronized(wArrayList* arrayList)
+BOOL ArrayList_IsSynchronized(wArrayList *arrayList)
{
return arrayList->synchronized;
}
* Lock access to the ArrayList
*/
-void ArrayList_Lock(wArrayList* arrayList)
+void ArrayList_Lock(wArrayList *arrayList)
{
EnterCriticalSection(&arrayList->lock);
}
* Unlock access to the ArrayList
*/
-void ArrayList_Unlock(wArrayList* arrayList)
+void ArrayList_Unlock(wArrayList *arrayList)
{
LeaveCriticalSection(&arrayList->lock);
}
* Gets the element at the specified index.
*/
-void* ArrayList_GetItem(wArrayList* arrayList, int index)
+void *ArrayList_GetItem(wArrayList *arrayList, int index)
{
- void* obj = NULL;
+ void *obj = NULL;
if ((index >= 0) && (index < arrayList->size))
{
* Sets the element at the specified index.
*/
-void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj)
+void ArrayList_SetItem(wArrayList *arrayList, int index, void *obj)
{
if ((index >= 0) && (index < arrayList->size))
{
* Shift a section of the list.
*/
-BOOL ArrayList_Shift(wArrayList* arrayList, int index, int count)
+BOOL ArrayList_Shift(wArrayList *arrayList, int index, int count)
{
if (count > 0)
{
{
void **newArray;
int newCapacity = arrayList->capacity * arrayList->growthFactor;
+ newArray = (void **)realloc(arrayList->array, sizeof(void *) * newCapacity);
- newArray = (void **)realloc(arrayList->array, sizeof(void*) * newCapacity);
if (!newArray)
return FALSE;
+
arrayList->array = newArray;
arrayList->capacity = newCapacity;
}
- MoveMemory(&arrayList->array[index + count], &arrayList->array[index], (arrayList->size - index) * sizeof(void*));
+ MoveMemory(&arrayList->array[index + count], &arrayList->array[index], (arrayList->size - index) * sizeof(void *));
arrayList->size += count;
}
else if (count < 0)
{
int chunk = arrayList->size - index + count;
+
if (chunk > 0)
- MoveMemory(&arrayList->array[index], &arrayList->array[index - count], chunk * sizeof(void*));
+ MoveMemory(&arrayList->array[index], &arrayList->array[index - count], chunk * sizeof(void *));
+
arrayList->size += count;
}
+
return TRUE;
}
* Removes all elements from the ArrayList.
*/
-void ArrayList_Clear(wArrayList* arrayList)
+void ArrayList_Clear(wArrayList *arrayList)
{
int index;
* Determines whether an element is in the ArrayList.
*/
-BOOL ArrayList_Contains(wArrayList* arrayList, void* obj)
+BOOL ArrayList_Contains(wArrayList *arrayList, void *obj)
{
+ DWORD index;
+ BOOL rc = FALSE;
+
if (arrayList->synchronized)
EnterCriticalSection(&arrayList->lock);
+ for (index = 0; index < arrayList->size; index++)
+ {
+ rc = arrayList->object.fnObjectEquals(arrayList->array[index], obj);
+
+ if (rc)
+ break;
+ }
+
if (arrayList->synchronized)
LeaveCriticalSection(&arrayList->lock);
- return FALSE;
+ return rc;
}
/**
* Adds an object to the end of the ArrayList.
*/
-int ArrayList_Add(wArrayList* arrayList, void* obj)
+int ArrayList_Add(wArrayList *arrayList, void *obj)
{
int index = -1;
{
void **newArray;
int newCapacity = arrayList->capacity * arrayList->growthFactor;
- newArray = (void **)realloc(arrayList->array, sizeof(void*) * newCapacity);
+ newArray = (void **)realloc(arrayList->array, sizeof(void *) * newCapacity);
+
if (!newArray)
goto out;
arrayList->array[arrayList->size++] = obj;
index = arrayList->size;
-
out:
+
if (arrayList->synchronized)
LeaveCriticalSection(&arrayList->lock);
* Inserts an element into the ArrayList at the specified index.
*/
-BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
+BOOL ArrayList_Insert(wArrayList *arrayList, int index, void *obj)
{
BOOL ret = TRUE;
+
if (arrayList->synchronized)
EnterCriticalSection(&arrayList->lock);
if (arrayList->synchronized)
LeaveCriticalSection(&arrayList->lock);
+
return ret;
}
* Removes the first occurrence of a specific object from the ArrayList.
*/
-BOOL ArrayList_Remove(wArrayList* arrayList, void* obj)
+BOOL ArrayList_Remove(wArrayList *arrayList, void *obj)
{
int index;
BOOL found = FALSE;
}
if (found)
- {
+ {
if (arrayList->object.fnObjectFree)
arrayList->object.fnObjectFree(arrayList->array[index]);
+
ret = ArrayList_Shift(arrayList, index, -1);
- }
+ }
if (arrayList->synchronized)
LeaveCriticalSection(&arrayList->lock);
+
return ret;
}
* Removes the element at the specified index of the ArrayList.
*/
-BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index)
+BOOL ArrayList_RemoveAt(wArrayList *arrayList, int index)
{
BOOL ret = TRUE;
{
if (arrayList->object.fnObjectFree)
arrayList->object.fnObjectFree(arrayList->array[index]);
+
ret = ArrayList_Shift(arrayList, index, -1);
}
if (arrayList->synchronized)
LeaveCriticalSection(&arrayList->lock);
+
return ret;
}
* in the ArrayList that contains the specified number of elements and ends at the specified index.
*/
-int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int count)
+int ArrayList_IndexOf(wArrayList *arrayList, void *obj, int startIndex, int count)
{
int index;
BOOL found = FALSE;
for (index = startIndex; index < startIndex + count; index++)
{
- if (arrayList->array[index] == obj)
+ if (arrayList->object.fnObjectEquals(arrayList->array[index], obj))
{
found = TRUE;
break;
* in the ArrayList that contains the specified number of elements and ends at the specified index.
*/
-int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int count)
+int ArrayList_LastIndexOf(wArrayList *arrayList, void *obj, int startIndex, int count)
{
int index;
BOOL found = FALSE;
for (index = startIndex + count - 1; index >= startIndex; index--)
{
- if (arrayList->array[index] == obj)
+ if (arrayList->object.fnObjectEquals(arrayList->array[index], obj))
{
found = TRUE;
break;
return index;
}
+static BOOL ArrayList_DefaultCompare(void *objA, void *objB)
+{
+ return objA == objB ? TRUE : FALSE;
+}
+
/**
* Construction, Destruction
*/
-wArrayList* ArrayList_New(BOOL synchronized)
+wArrayList *ArrayList_New(BOOL synchronized)
{
- wArrayList* arrayList = NULL;
-
+ wArrayList *arrayList = NULL;
arrayList = (wArrayList *)calloc(1, sizeof(wArrayList));
+
if (!arrayList)
return NULL;
arrayList->synchronized = synchronized;
arrayList->capacity = 32;
arrayList->growthFactor = 2;
-
+ arrayList->object.fnObjectEquals = ArrayList_DefaultCompare;
arrayList->array = (void **)malloc(arrayList->capacity * sizeof(void *));
+
if (!arrayList->array)
goto out_free;
InitializeCriticalSectionAndSpinCount(&arrayList->lock, 4000);
return arrayList;
-
out_free:
free(arrayList);
return NULL;
}
-void ArrayList_Free(wArrayList* arrayList)
+void ArrayList_Free(wArrayList *arrayList)
{
ArrayList_Clear(arrayList);
-
DeleteCriticalSection(&arrayList->lock);
free(arrayList->array);
free(arrayList);
#include "config.h"
#endif
+#include <winpr/print.h>
#include <winpr/bitstream.h>
+#include "../trio/trio.h"
const char* BYTE_BIT_STRINGS_LSB[256] =
{
"00111111", "10111111", "01111111", "11111111"
};
-void BitDump(const BYTE* buffer, UINT32 length, UINT32 flags)
+void BitDump(const char* tag, int level, const BYTE* buffer, UINT32 length, UINT32 flags)
{
DWORD i;
int nbits;
const char* str;
const char** strs;
-
+ char pbuffer[64 * 8 + 1];
+ size_t pos = 0, len = sizeof(pbuffer);
strs = (flags & BITDUMP_MSB_FIRST) ? BYTE_BIT_STRINGS_MSB : BYTE_BIT_STRINGS_LSB;
for (i = 0; i < length; i += 8)
{
str = strs[buffer[i / 8]];
-
nbits = (length - i) > 8 ? 8 : (length - i);
+ pos += trio_snprintf(&pbuffer[pos], length - pos, "%.*s ", nbits, str);
if ((i % 64) == 0)
- printf("\n");
-
- printf("%.*s ", nbits, str);
+ {
+ pos = 0;
+ WLog_LVL(tag, level, "%s", pbuffer);
+ }
}
- printf("\n");
+ if (i)
+ WLog_LVL(tag, level, "%s ", pbuffer);
}
UINT32 ReverseBits32(UINT32 bits, UINT32 nbits)
while (nbits > 0);
rbits >>= 1;
-
return rbits;
}
void BitStream_Prefetch(wBitStream* bs)
{
(bs->prefetch) = 0;
+
if ((bs->pointer - bs->buffer) < (bs->capacity + 4))
(bs->prefetch) |= (*(bs->pointer + 4) << 24);
+
if ((bs->pointer - bs->buffer) < (bs->capacity + 5))
(bs->prefetch) |= (*(bs->pointer + 5) << 16);
+
if ((bs->pointer - bs->buffer) < (bs->capacity + 6))
(bs->prefetch) |= (*(bs->pointer + 6) << 8);
+
if ((bs->pointer - bs->buffer) < (bs->capacity + 7))
(bs->prefetch) |= (*(bs->pointer + 7) << 0);
}
if ((bs->pointer - bs->buffer) < (bs->capacity + 0))
(bs->accumulator) |= (*(bs->pointer + 0) << 24);
+
if ((bs->pointer - bs->buffer) < (bs->capacity + 1))
(bs->accumulator) |= (*(bs->pointer + 1) << 16);
+
if ((bs->pointer - bs->buffer) < (bs->capacity + 2))
(bs->accumulator) |= (*(bs->pointer + 2) << 8);
+
if ((bs->pointer - bs->buffer) < (bs->capacity + 3))
(bs->accumulator) |= (*(bs->pointer + 3) << 0);
{
if ((bs->pointer - bs->buffer) < (bs->capacity + 0))
*(bs->pointer + 0) = (bs->accumulator >> 24);
+
if ((bs->pointer - bs->buffer) < (bs->capacity + 1))
*(bs->pointer + 1) = (bs->accumulator >> 16);
+
if ((bs->pointer - bs->buffer) < (bs->capacity + 2))
*(bs->pointer + 2) = (bs->accumulator >> 8);
+
if ((bs->pointer - bs->buffer) < (bs->capacity + 3))
*(bs->pointer + 3) = (bs->accumulator >> 0);
}
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->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;
#endif
-void BitStream_Attach(wBitStream* bs, BYTE* buffer, UINT32 capacity)
+void BitStream_Attach(wBitStream* bs, const BYTE* buffer, UINT32 capacity)
{
bs->position = 0;
bs->buffer = buffer;
bs->offset = 0;
bs->accumulator = 0;
- bs->pointer = bs->buffer;
+ bs->pointer = (BYTE*) bs->buffer;
bs->capacity = capacity;
bs->length = bs->capacity * 8;
}
wBitStream* BitStream_New()
{
wBitStream* bs = NULL;
-
bs = (wBitStream*) calloc(1, sizeof(wBitStream));
if (bs)
{
-
}
return bs;
* Methods
*/
-BOOL BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count)
+static BOOL BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count)
{
if (count > 0)
{
return TRUE;
}
-BOOL BufferPool_ShiftUsed(wBufferPool* pool, int index, int count)
+static BOOL BufferPool_ShiftUsed(wBufferPool* pool, int index, int count)
{
if (count > 0)
{
* Adds a new node containing the specified value at the start of the LinkedList.
*/
-void LinkedList_AddFirst(wLinkedList* list, void* value)
+BOOL LinkedList_AddFirst(wLinkedList* list, void* value)
{
wLinkedListNode* node;
node = (wLinkedListNode*) malloc(sizeof(wLinkedListNode));
+ if (!node)
+ return FALSE;
node->prev = node->next = NULL;
node->value = value;
}
list->count++;
+ return TRUE;
}
/**
* Adds a new node containing the specified value at the end of the LinkedList.
*/
-void LinkedList_AddLast(wLinkedList* list, void* value)
+BOOL LinkedList_AddLast(wLinkedList* list, void* value)
{
wLinkedListNode* node;
node = (wLinkedListNode*) malloc(sizeof(wLinkedListNode));
+ if (!node)
+ return FALSE;
node->prev = node->next = NULL;
node->value = value;
}
list->count++;
+ return TRUE;
}
/**
* Removes the first occurrence of the specified value from the LinkedList.
*/
-void LinkedList_Remove(wLinkedList* list, void* value)
+BOOL LinkedList_Remove(wLinkedList* list, void* value)
{
wLinkedListNode* node;
free(node);
list->count--;
-
- break;
+ return TRUE;
}
node = node->next;
}
+ return FALSE;
}
/**
--- /dev/null
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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.
+ */
+
+/* A stack unwinder. */
+
+#ifndef _CORKSCREW_BACKTRACE_H
+#define _CORKSCREW_BACKTRACE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <corkscrew/ptrace.h>
+#include <corkscrew/map_info.h>
+#include <corkscrew/symbol_table.h>
+
+ /*
+ * Describes a single frame of a backtrace.
+ */
+ typedef struct
+ {
+ uintptr_t absolute_pc; /* absolute PC offset */
+ uintptr_t stack_top; /* top of stack for this frame */
+ size_t stack_size; /* size of this stack frame */
+ } backtrace_frame_t;
+
+ /*
+ * Describes the symbols associated with a backtrace frame.
+ */
+ typedef struct
+ {
+ uintptr_t relative_pc; /* relative frame PC offset from the start of the library,
+ or the absolute PC if the library is unknown */
+ uintptr_t relative_symbol_addr; /* relative offset of the symbol from the start of the
+ library or 0 if the library is unknown */
+ char *map_name; /* executable or library name, or NULL if unknown */
+ char *symbol_name; /* symbol name, or NULL if unknown */
+ char *demangled_name; /* demangled symbol name, or NULL if unknown */
+ } backtrace_symbol_t;
+
+ /*
+ * Unwinds the call stack for the current thread of execution.
+ * Populates the backtrace array with the program counters from the call stack.
+ * Returns the number of frames collected, or -1 if an error occurred.
+ */
+ ssize_t unwind_backtrace(backtrace_frame_t *backtrace, size_t ignore_depth, size_t max_depth);
+
+ /*
+ * Unwinds the call stack for a thread within this process.
+ * Populates the backtrace array with the program counters from the call stack.
+ * Returns the number of frames collected, or -1 if an error occurred.
+ *
+ * The task is briefly suspended while the backtrace is being collected.
+ */
+ ssize_t unwind_backtrace_thread(pid_t tid, backtrace_frame_t *backtrace,
+ size_t ignore_depth, size_t max_depth);
+
+ /*
+ * Unwinds the call stack of a task within a remote process using ptrace().
+ * Populates the backtrace array with the program counters from the call stack.
+ * Returns the number of frames collected, or -1 if an error occurred.
+ */
+ ssize_t unwind_backtrace_ptrace(pid_t tid, const ptrace_context_t *context,
+ backtrace_frame_t *backtrace, size_t ignore_depth, size_t max_depth);
+
+ /*
+ * Gets the symbols for each frame of a backtrace.
+ * The symbols array must be big enough to hold one symbol record per frame.
+ * The symbols must later be freed using free_backtrace_symbols.
+ */
+ void get_backtrace_symbols(const backtrace_frame_t *backtrace, size_t frames,
+ backtrace_symbol_t *backtrace_symbols);
+
+ /*
+ * Gets the symbols for each frame of a backtrace from a remote process.
+ * The symbols array must be big enough to hold one symbol record per frame.
+ * The symbols must later be freed using free_backtrace_symbols.
+ */
+ void get_backtrace_symbols_ptrace(const ptrace_context_t *context,
+ const backtrace_frame_t *backtrace, size_t frames,
+ backtrace_symbol_t *backtrace_symbols);
+
+ /*
+ * Frees the storage associated with backtrace symbols.
+ */
+ void free_backtrace_symbols(backtrace_symbol_t *backtrace_symbols, size_t frames);
+
+ enum
+ {
+ // A hint for how big to make the line buffer for format_backtrace_line
+ MAX_BACKTRACE_LINE_LENGTH = 800,
+ };
+
+ /**
+ * Formats a line from a backtrace as a zero-terminated string into the specified buffer.
+ */
+ void format_backtrace_line(unsigned frameNumber, const backtrace_frame_t *frame,
+ const backtrace_symbol_t *symbol, char *buffer, size_t bufferSize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CORKSCREW_BACKTRACE_H
--- /dev/null
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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.
+ */
+
+/* C++ symbol name demangling. */
+
+#ifndef _CORKSCREW_DEMANGLE_H
+#define _CORKSCREW_DEMANGLE_H
+
+#include <sys/types.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Demangles a C++ symbol name.
+ * If name is NULL or if the name cannot be demangled, returns NULL.
+ * Otherwise, returns a newly allocated string that contains the demangled name.
+ *
+ * The caller must free the returned string using free().
+ */
+char* demangle_symbol_name(const char* name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CORKSCREW_DEMANGLE_H
--- /dev/null
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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.
+ */
+
+/* Process memory map. */
+
+#ifndef _CORKSCREW_MAP_INFO_H
+#define _CORKSCREW_MAP_INFO_H
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct map_info {
+ struct map_info* next;
+ uintptr_t start;
+ uintptr_t end;
+ bool is_readable;
+ bool is_writable;
+ bool is_executable;
+ void* data; // arbitrary data associated with the map by the user, initially NULL
+ char name[];
+} map_info_t;
+
+/* Loads memory map from /proc/<tid>/maps. */
+map_info_t* load_map_info_list(pid_t tid);
+
+/* Frees memory map. */
+void free_map_info_list(map_info_t* milist);
+
+/* Finds the memory map that contains the specified address. */
+const map_info_t* find_map_info(const map_info_t* milist, uintptr_t addr);
+
+/* Returns true if the addr is in a readable map. */
+bool is_readable_map(const map_info_t* milist, uintptr_t addr);
+/* Returns true if the addr is in a writable map. */
+bool is_writable_map(const map_info_t* milist, uintptr_t addr);
+/* Returns true if the addr is in an executable map. */
+bool is_executable_map(const map_info_t* milist, uintptr_t addr);
+
+/* Acquires a reference to the memory map for this process.
+ * The result is cached and refreshed automatically.
+ * Make sure to release the map info when done. */
+map_info_t* acquire_my_map_info_list();
+
+/* Releases a reference to the map info for this process that was
+ * previous acquired using acquire_my_map_info_list(). */
+void release_my_map_info_list(map_info_t* milist);
+
+/* Flushes the cached memory map so the next call to
+ * acquire_my_map_info_list() gets fresh data. */
+void flush_my_map_info_list();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CORKSCREW_MAP_INFO_H
--- /dev/null
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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.
+ */
+
+/* Useful ptrace() utility functions. */
+
+#ifndef _CORKSCREW_PTRACE_H
+#define _CORKSCREW_PTRACE_H
+
+#include <corkscrew/map_info.h>
+#include <corkscrew/symbol_table.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Stores information about a process that is used for several different
+ * ptrace() based operations. */
+typedef struct {
+ map_info_t* map_info_list;
+} ptrace_context_t;
+
+/* Describes how to access memory from a process. */
+typedef struct {
+ pid_t tid;
+ const map_info_t* map_info_list;
+} memory_t;
+
+#if __i386__
+/* ptrace() register context. */
+typedef struct pt_regs_x86 {
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t esi;
+ uint32_t edi;
+ uint32_t ebp;
+ uint32_t eax;
+ uint32_t xds;
+ uint32_t xes;
+ uint32_t xfs;
+ uint32_t xgs;
+ uint32_t orig_eax;
+ uint32_t eip;
+ uint32_t xcs;
+ uint32_t eflags;
+ uint32_t esp;
+ uint32_t xss;
+} pt_regs_x86_t;
+#endif
+
+#if __mips__
+/* ptrace() GET_REGS context. */
+typedef struct pt_regs_mips {
+ uint64_t regs[32];
+ uint64_t lo;
+ uint64_t hi;
+ uint64_t cp0_epc;
+ uint64_t cp0_badvaddr;
+ uint64_t cp0_status;
+ uint64_t cp0_cause;
+} pt_regs_mips_t;
+#endif
+
+/*
+ * Initializes a memory structure for accessing memory from this process.
+ */
+void init_memory(memory_t* memory, const map_info_t* map_info_list);
+
+/*
+ * Initializes a memory structure for accessing memory from another process
+ * using ptrace().
+ */
+void init_memory_ptrace(memory_t* memory, pid_t tid);
+
+/*
+ * Reads a word of memory safely.
+ * If the memory is local, ensures that the address is readable before dereferencing it.
+ * Returns false and a value of 0xffffffff if the word could not be read.
+ */
+bool try_get_word(const memory_t* memory, uintptr_t ptr, uint32_t* out_value);
+
+/*
+ * Reads a word of memory safely using ptrace().
+ * Returns false and a value of 0xffffffff if the word could not be read.
+ */
+bool try_get_word_ptrace(pid_t tid, uintptr_t ptr, uint32_t* out_value);
+
+/*
+ * Loads information needed for examining a remote process using ptrace().
+ * The caller must already have successfully attached to the process
+ * using ptrace().
+ *
+ * The context can be used for any threads belonging to that process
+ * assuming ptrace() is attached to them before performing the actual
+ * unwinding. The context can continue to be used to decode backtraces
+ * even after ptrace() has been detached from the process.
+ */
+ptrace_context_t* load_ptrace_context(pid_t pid);
+
+/*
+ * Frees a ptrace context.
+ */
+void free_ptrace_context(ptrace_context_t* context);
+
+/*
+ * Finds a symbol using ptrace.
+ * Returns the containing map and information about the symbol, or
+ * NULL if one or the other is not available.
+ */
+void find_symbol_ptrace(const ptrace_context_t* context,
+ uintptr_t addr, const map_info_t** out_map_info, const symbol_t** out_symbol);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CORKSCREW_PTRACE_H
--- /dev/null
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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 _CORKSCREW_SYMBOL_TABLE_H
+#define _CORKSCREW_SYMBOL_TABLE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ uintptr_t start;
+ uintptr_t end;
+ char* name;
+} symbol_t;
+
+typedef struct {
+ symbol_t* symbols;
+ size_t num_symbols;
+} symbol_table_t;
+
+/*
+ * Loads a symbol table from a given file.
+ * Returns NULL on error.
+ */
+symbol_table_t* load_symbol_table(const char* filename);
+
+/*
+ * Frees a symbol table.
+ */
+void free_symbol_table(symbol_table_t* table);
+
+/*
+ * Finds a symbol associated with an address in the symbol table.
+ * Returns NULL if not found.
+ */
+const symbol_t* find_symbol(const symbol_table_t* table, uintptr_t addr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CORKSCREW_SYMBOL_TABLE_H
--- /dev/null
+/**
+ * WinPR: Windows Portable Runtime
+ * Debugging Utils
+ *
+ * Copyright 2014 Armin Novak <armin.novak@thincast.com>
+ * Copyright 2014 Thincast Technologies GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+
+#if defined(HAVE_EXECINFO_H)
+#include <execinfo.h>
+#endif
+
+#if defined(ANDROID)
+#include <corkscrew/backtrace.h>
+#endif
+
+#include <winpr/crt.h>
+#include <winpr/wlog.h>
+#include <winpr/debug.h>
+
+#define TAG "com.winpr.utils.debug"
+#define LOGT(...) do { WLog_Print(WLog_Get(TAG), WLOG_TRACE, __VA_ARGS__); } while(0)
+#define LOGD(...) do { WLog_Print(WLog_Get(TAG), WLOG_DEBUG, __VA_ARGS__); } while(0)
+#define LOGI(...) do { WLog_Print(WLog_Get(TAG), WLOG_INFO, __VA_ARGS__); } while(0)
+#define LOGW(...) do { WLog_Print(WLog_Get(TAG), WLOG_WARN, __VA_ARGS__); } while(0)
+#define LOGE(...) do { WLog_Print(WLog_Get(TAG), WLOG_ERROR, __VA_ARGS__); } while(0)
+#define LOGF(...) do { WLog_Print(WLog_Get(TAG), WLOG_FATAL, __VA_ARGS__); } while(0)
+
+static const char *support_msg = "Invalid stacktrace buffer! check if platform is supported!";
+
+#if defined(HAVE_EXECINFO_H)
+typedef struct
+{
+ void **buffer;
+ size_t max;
+ size_t used;
+} t_execinfo;
+#endif
+
+#if defined(ANDROID)
+#include <pthread.h>
+#include <dlfcn.h>
+#include <unistd.h>
+
+typedef struct
+{
+ backtrace_frame_t *buffer;
+ size_t max;
+ size_t used;
+} t_corkscrew_data;
+
+typedef struct
+{
+ void *hdl;
+ ssize_t (*unwind_backtrace)(backtrace_frame_t *backtrace, size_t ignore_depth, size_t max_depth);
+ ssize_t (*unwind_backtrace_thread)(pid_t tid, backtrace_frame_t *backtrace,
+ size_t ignore_depth, size_t max_depth);
+ ssize_t (*unwind_backtrace_ptrace)(pid_t tid, const ptrace_context_t *context,
+ backtrace_frame_t *backtrace, size_t ignore_depth, size_t max_depth);
+ void (*get_backtrace_symbols)(const backtrace_frame_t *backtrace, size_t frames,
+ backtrace_symbol_t *backtrace_symbols);
+ void (*get_backtrace_symbols_ptrace)(const ptrace_context_t *context,
+ const backtrace_frame_t *backtrace, size_t frames,
+ backtrace_symbol_t *backtrace_symbols);
+ void (*free_backtrace_symbols)(backtrace_symbol_t *backtrace_symbols, size_t frames);
+ void (*format_backtrace_line)(unsigned frameNumber, const backtrace_frame_t *frame,
+ const backtrace_symbol_t *symbol, char *buffer, size_t bufferSize);
+} t_corkscrew;
+
+static pthread_once_t initialized = PTHREAD_ONCE_INIT;
+static t_corkscrew *fkt = NULL;
+
+void load_library(void)
+{
+ static t_corkscrew lib;
+ {
+ lib.hdl = dlopen("libcorkscrew.so", RTLD_LAZY);
+
+ if (!lib.hdl)
+ {
+ LOGF("dlopen error %s", dlerror());
+ goto fail;
+ }
+
+ lib.unwind_backtrace = dlsym(lib.hdl, "unwind_backtrace");
+
+ if (!lib.unwind_backtrace)
+ {
+ LOGF("dlsym error %s", dlerror());
+ goto fail;
+ }
+
+ lib.unwind_backtrace_thread = dlsym(lib.hdl, "unwind_backtrace_thread");
+
+ if (!lib.unwind_backtrace_thread)
+ {
+ LOGF("dlsym error %s", dlerror());
+ goto fail;
+ }
+
+ lib.unwind_backtrace_ptrace = dlsym(lib.hdl, "unwind_backtrace_ptrace");
+
+ if (!lib.unwind_backtrace_ptrace)
+ {
+ LOGF("dlsym error %s", dlerror());
+ goto fail;
+ }
+
+ lib.get_backtrace_symbols = dlsym(lib.hdl, "get_backtrace_symbols");
+
+ if (!lib.get_backtrace_symbols)
+ {
+ LOGF("dlsym error %s", dlerror());
+ goto fail;
+ }
+
+ lib.get_backtrace_symbols_ptrace = dlsym(lib.hdl, "get_backtrace_symbols_ptrace");
+
+ if (!lib.get_backtrace_symbols_ptrace)
+ {
+ LOGF("dlsym error %s", dlerror());
+ goto fail;
+ }
+
+ lib.free_backtrace_symbols = dlsym(lib.hdl, "free_backtrace_symbols");
+
+ if (!lib.free_backtrace_symbols)
+ {
+ LOGF("dlsym error %s", dlerror());
+ goto fail;
+ }
+
+ lib.format_backtrace_line = dlsym(lib.hdl, "format_backtrace_line");
+
+ if (!lib.format_backtrace_line)
+ {
+ LOGF("dlsym error %s", dlerror());
+ goto fail;
+ }
+
+ fkt = &lib;
+ return;
+ }
+fail:
+ {
+ if (lib.hdl)
+ dlclose(lib.hdl);
+
+ fkt = NULL;
+ }
+}
+#endif
+
+void winpr_backtrace_free(void *buffer)
+{
+ if (!buffer)
+ {
+ LOGF(support_msg);
+ return;
+ }
+
+#if defined(HAVE_EXECINFO_H)
+ t_execinfo *data = (t_execinfo *)buffer;
+
+ if (data->buffer)
+ free(data->buffer);
+
+ free(data);
+#elif defined(ANDROID)
+ t_corkscrew_data *data = (t_corkscrew_data *)buffer;
+
+ if (data->buffer)
+ free(data->buffer);
+
+ free(data);
+#else
+ LOGF(support_msg);
+#endif
+}
+
+void *winpr_backtrace(DWORD size)
+{
+#if defined(HAVE_EXECINFO_H)
+ t_execinfo *data = calloc(1, sizeof(t_execinfo));
+
+ if (!data)
+ return NULL;
+
+ data->buffer = calloc(size, sizeof(void *));
+
+ if (!data->buffer)
+ return NULL;
+
+ data->max = size;
+ data->used = backtrace(data->buffer, size);
+ return data;
+#elif defined(ANDROID)
+ t_corkscrew_data *data = calloc(1, sizeof(t_corkscrew_data));
+
+ if (!data)
+ return NULL;
+
+ data->buffer = calloc(size, sizeof(backtrace_frame_t));
+
+ if (!data->buffer)
+ {
+ free(data);
+ return NULL;
+ }
+
+ pthread_once(&initialized, load_library);
+ data->max = size;
+ data->used = fkt->unwind_backtrace(data->buffer, 0, size);
+ return data;
+#else
+ LOGF(support_msg);
+ return NULL;
+#endif
+}
+
+char **winpr_backtrace_symbols(void *buffer, size_t *used)
+{
+ if (used)
+ *used = 0;
+
+ if (!buffer)
+ {
+ LOGF(support_msg);
+ return NULL;
+ }
+
+#if defined(HAVE_EXECINFO_H)
+ t_execinfo *data = (t_execinfo *)buffer;
+ assert(data);
+
+ if (used)
+ *used = data->used;
+
+ return backtrace_symbols(data->buffer, data->used);
+#elif defined(ANDROID)
+ t_corkscrew_data *data = (t_corkscrew_data *)buffer;
+ assert(data);
+ pthread_once(&initialized, load_library);
+
+ if (!fkt)
+ {
+ LOGF(support_msg);
+ return NULL;
+ }
+ else
+ {
+ size_t line_len = (data->max > 1024) ? data->max : 1024;
+ size_t i;
+ char *lines = calloc(data->used + 1, sizeof(char *) * line_len);
+ char **vlines = (char **)lines;
+ backtrace_symbol_t *symbols = calloc(data->used, sizeof(backtrace_symbol_t));;
+
+ if (!lines || !symbols)
+ {
+ if (lines)
+ free(lines);
+
+ if (symbols)
+ free(symbols);
+
+ return NULL;
+ }
+
+ /* To allow a char** malloced array to be returned, allocate n+1 lines
+ * and fill in the first lines[i] char with the address of lines[(i+1) * 1024] */
+ for (i=0; i<data->used; i++)
+ vlines[i] = &lines[(i + 1) * line_len];
+
+ fkt->get_backtrace_symbols(data->buffer, data->used, symbols);
+
+ for (i=0; i<data->used; i++)
+ fkt->format_backtrace_line(i, &data->buffer[i], &symbols[i], vlines[i], line_len);
+
+ fkt->free_backtrace_symbols(symbols, data->used);
+
+ if (used)
+ *used = data->used;
+
+ return (char **)lines;
+ }
+
+#else
+ LOGF(support_msg);
+ return NULL;
+#endif
+}
+
+void winpr_backtrace_symbols_fd(void *buffer, int fd)
+{
+ if (!buffer)
+ {
+ LOGF(support_msg);
+ return;
+ }
+
+#if defined(HAVE_EXECINFO_H)
+ t_execinfo *data = (t_execinfo *)buffer;
+ assert(data);
+ backtrace_symbols_fd(data->buffer, data->used, fd);
+#elif defined(ANDROID)
+ size_t used;
+ t_corkscrew_data *data = (t_corkscrew_data *)buffer;
+ assert(data);
+ char **lines = winpr_backtrace_symbols(buffer, &used);
+
+ if (lines)
+ {
+ DWORD i;
+
+ for (i=0; i<used; i++)
+ write(fd, lines[i], strlen(lines[i]));
+ }
+
+#else
+ LOGF(support_msg);
+#endif
+}
--- /dev/null
+/**
+ * WinPR: Windows Portable Runtime
+ * Image Utils
+ *
+ * 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 <winpr/crt.h>
+
+#include <winpr/image.h>
+
+#include "../log.h"
+#define TAG WINPR_TAG("utils.image")
+
+/**
+ * Refer to "Compressed Image File Formats: JPEG, PNG, GIF, XBM, BMP" book
+ */
+
+#if defined(__APPLE__)
+#pragma pack(1)
+#else
+#pragma pack(push, 1)
+#endif
+
+struct _WINPR_BITMAP_FILE_HEADER
+{
+ BYTE bfType[2];
+ UINT32 bfSize;
+ UINT16 bfReserved1;
+ UINT16 bfReserved2;
+ UINT32 bfOffBits;
+};
+typedef struct _WINPR_BITMAP_FILE_HEADER WINPR_BITMAP_FILE_HEADER;
+
+struct _WINPR_BITMAP_INFO_HEADER
+{
+ UINT32 biSize;
+ INT32 biWidth;
+ INT32 biHeight;
+ UINT16 biPlanes;
+ UINT16 biBitCount;
+ UINT32 biCompression;
+ UINT32 biSizeImage;
+ INT32 biXPelsPerMeter;
+ INT32 biYPelsPerMeter;
+ UINT32 biClrUsed;
+ UINT32 biClrImportant;
+};
+typedef struct _WINPR_BITMAP_INFO_HEADER WINPR_BITMAP_INFO_HEADER;
+
+struct _WINPR_BITMAP_CORE_HEADER
+{
+ UINT32 bcSize;
+ UINT16 bcWidth;
+ UINT16 bcHeight;
+ UINT16 bcPlanes;
+ UINT16 bcBitCount;
+};
+typedef struct _WINPR_BITMAP_CORE_HEADER WINPR_BITMAP_CORE_HEADER;
+
+#if defined(__APPLE__)
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+
+int winpr_bitmap_write(const char* filename, BYTE* data, int width, int height, int bpp)
+{
+ FILE* fp;
+ WINPR_BITMAP_FILE_HEADER bf;
+ WINPR_BITMAP_INFO_HEADER bi;
+
+ fp = fopen(filename, "w+b");
+
+ if (!fp)
+ {
+ WLog_ERR(TAG, "failed to open file %s", filename);
+ return -1;
+ }
+
+ bf.bfType[0] = 'B';
+ bf.bfType[1] = 'M';
+ bf.bfReserved1 = 0;
+ bf.bfReserved2 = 0;
+ bf.bfOffBits = sizeof(WINPR_BITMAP_FILE_HEADER) + sizeof(WINPR_BITMAP_INFO_HEADER);
+ bi.biSizeImage = width * height * (bpp / 8);
+ bf.bfSize = bf.bfOffBits + bi.biSizeImage;
+
+ bi.biWidth = width;
+ bi.biHeight = -1 * height;
+ bi.biPlanes = 1;
+ bi.biBitCount = bpp;
+ bi.biCompression = 0;
+ bi.biXPelsPerMeter = width;
+ bi.biYPelsPerMeter = height;
+ bi.biClrUsed = 0;
+ bi.biClrImportant = 0;
+ bi.biSize = sizeof(WINPR_BITMAP_INFO_HEADER);
+
+ fwrite((void*) &bf, sizeof(WINPR_BITMAP_FILE_HEADER), 1, fp);
+ fwrite((void*) &bi, sizeof(WINPR_BITMAP_INFO_HEADER), 1, fp);
+ fwrite((void*) data, bi.biSizeImage, 1, fp);
+
+ fclose(fp);
+
+ return 1;
+}
+
+int winpr_image_write(wImage* image, const char* filename)
+{
+ return winpr_bitmap_write(filename, image->data, image->width, image->height, image->bitsPerPixel);
+}
+
+int winpr_image_read(wImage* image, const char* filename)
+{
+ FILE* fp;
+ int index;
+ BOOL vFlip;
+ BYTE* pDstData;
+ WINPR_BITMAP_FILE_HEADER bf;
+ WINPR_BITMAP_INFO_HEADER bi;
+
+ fp = fopen(filename, "r+b");
+
+ if (!fp)
+ {
+ WLog_ERR(TAG, "failed to open file %s", filename);
+ return -1;
+ }
+
+ fread((void*) &bf, sizeof(WINPR_BITMAP_FILE_HEADER), 1, fp);
+
+ if ((bf.bfType[0] != 'B') || (bf.bfType[1] != 'M'))
+ return -1;
+
+ fread((void*) &bi, sizeof(WINPR_BITMAP_INFO_HEADER), 1, fp);
+
+ if (ftell(fp) != bf.bfOffBits)
+ {
+ fseek(fp, bf.bfOffBits, SEEK_SET);
+ }
+
+ image->width = bi.biWidth;
+
+ if (bi.biHeight < 0)
+ {
+ vFlip = FALSE;
+ image->height = -1 * bi.biHeight;
+ }
+ else
+ {
+ vFlip = TRUE;
+ image->height = bi.biHeight;
+ }
+
+ image->bitsPerPixel = bi.biBitCount;
+ image->bytesPerPixel = (image->bitsPerPixel / 8);
+ image->scanline = (bi.biSizeImage / bi.biHeight);
+
+ image->data = (BYTE*) malloc(bi.biSizeImage);
+
+ if (!image->data)
+ return -1;
+
+ if (!vFlip)
+ {
+ fread((void*) image->data, bi.biSizeImage, 1, fp);
+ }
+ else
+ {
+ pDstData = &(image->data[(image->height - 1) * image->scanline]);
+
+ for (index = 0; index < image->height; index++)
+ {
+ fread((void*) pDstData, image->scanline, 1, fp);
+ pDstData -= image->scanline;
+ }
+ }
+
+ fclose(fp);
+
+ return 1;
+}
+
+wImage* winpr_image_new()
+{
+ wImage* image;
+
+ image = (wImage*) calloc(1, sizeof(wImage));
+
+ if (!image)
+ return NULL;
+
+ return image;
+}
+
+void winpr_image_free(wImage* image, BOOL bFreeBuffer)
+{
+ if (!image)
+ return;
+
+ if (bFreeBuffer)
+ free(image->data);
+
+ free(image);
+}
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
+#include <errno.h>
#include <winpr/crt.h>
#include <winpr/print.h>
#include "trio.h"
-void winpr_HexDump(const BYTE* data, int length)
+#include "../log.h"
+
+void winpr_HexDump(const char* tag, int level, const BYTE* data, int length)
{
const BYTE* p = data;
int i, line, offset = 0;
+ const size_t llen = (length > WINPR_HEXDUMP_LINE_LENGTH) ? WINPR_HEXDUMP_LINE_LENGTH : length;
+ size_t blen = 7 + WINPR_HEXDUMP_LINE_LENGTH * 5;
+ size_t pos = 0;
+ char* buffer = malloc(blen);
- while (offset < length)
+ if (!buffer)
{
- fprintf(stderr, "%04x ", offset);
+ WLog_ERR(tag, "malloc(%zd) failed with [%d] %s", blen, errno, strerror(errno));
+ return;
+ }
+ while (offset < length)
+ {
+ pos += trio_snprintf(&buffer[pos], blen - pos, "%04x ", offset);
line = length - offset;
if (line > WINPR_HEXDUMP_LINE_LENGTH)
line = WINPR_HEXDUMP_LINE_LENGTH;
for (i = 0; i < line; i++)
- fprintf(stderr, "%02x ", p[i]);
+ pos += trio_snprintf(&buffer[pos], blen - pos, "%02x ", p[i]);
for (; i < WINPR_HEXDUMP_LINE_LENGTH; i++)
- fprintf(stderr, " ");
+ pos += trio_snprintf(&buffer[pos], blen - pos, " ");
for (i = 0; i < line; i++)
- fprintf(stderr, "%c", (p[i] >= 0x20 && p[i] < 0x7F) ? p[i] : '.');
-
- fprintf(stderr, "\n");
+ pos += trio_snprintf(&buffer[pos], blen - pos, "%c",
+ (p[i] >= 0x20 && p[i] < 0x7F) ? p[i] : '.');
+ pos += trio_snprintf(&buffer[pos], blen - pos, "\n");
+ WLog_LVL(tag, level, "%s", buffer);
offset += line;
p += line;
+ pos = 0;
}
+
+ free(buffer);
}
-void winpr_CArrayDump(const BYTE* data, int length, int width)
+void winpr_CArrayDump(const char* tag, int level, const BYTE* data, int length, int width)
{
const BYTE* p = data;
int i, line, offset = 0;
+ const size_t llen = ((length > width) ? width : length) * 4 + 1;
+ size_t pos;
+ char* buffer = malloc(llen);
+
+ if (!buffer)
+ {
+ WLog_ERR(tag, "malloc(%zd) failed with [%d] %s", llen, errno, strerror(errno));
+ return;
+ }
while (offset < length)
{
if (line > width)
line = width;
- printf("\t\"");
+ pos = 0;
for (i = 0; i < line; i++)
- printf("\\x%02X", p[i]);
-
- printf("\"\n");
+ pos += trio_snprintf(&buffer[pos], llen - pos, "\\x%02X", p[i]);
+ WLog_LVL(tag, level, "%s", buffer);
offset += line;
p += line;
}
- printf("\n");
+ free(buffer);
}
char* winpr_BinToHexString(const BYTE* data, int length, BOOL space)
char* p;
int ln, hn;
char bin2hex[] = "0123456789ABCDEF";
-
n = space ? 3 : 2;
-
p = (char*) malloc((length + 1) * n);
for (i = 0; i < length; i++)
{
ln = data[i] & 0xF;
hn = (data[i] >> 4) & 0xF;
-
p[i * n] = bin2hex[hn];
p[(i * n) + 1] = bin2hex[ln];
}
p[length * n] = '\0';
-
return p;
}
-int wvprintfx(const char *fmt, va_list args)
+int wvprintfx(const char* fmt, va_list args)
{
return trio_vprintf(fmt, args);
}
-int wprintfx(const char *fmt, ...)
+int wprintfx(const char* fmt, ...)
{
va_list args;
int status;
-
va_start(args, fmt);
status = trio_vprintf(fmt, args);
va_end(args);
-
return status;
}
-int wvsnprintfx(char *buffer, size_t bufferSize, const char* fmt, va_list args)
+int wvsnprintfx(char* buffer, size_t bufferSize, const char* fmt, va_list args)
{
return trio_vsnprintf(buffer, bufferSize, fmt, args);
}
#include <winpr/sam.h>
#include <winpr/print.h>
+#include "../log.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#else
#define WINPR_SAM_FILE "/etc/winpr/SAM"
#endif
+#define TAG WINPR_TAG("utils")
WINPR_SAM* SamOpen(BOOL read_only)
{
sam->fp = fp;
}
else
- printf("Could not open SAM file!\n");
+ WLog_ERR(TAG, "Could not open SAM file!");
return sam;
}
-BOOL SamLookupStart(WINPR_SAM* sam)
+static BOOL SamLookupStart(WINPR_SAM* sam)
{
size_t read_size;
long int file_size;
-
fseek(sam->fp, 0, SEEK_END);
file_size = ftell(sam->fp);
fseek(sam->fp, 0, SEEK_SET);
return FALSE;
sam->buffer = (char*) malloc(file_size + 2);
-
read_size = fread(sam->buffer, file_size, 1, sam->fp);
if (!read_size)
sam->buffer[file_size] = '\n';
sam->buffer[file_size + 1] = '\0';
-
sam->line = strtok(sam->buffer, "\n");
-
return TRUE;
}
-void SamLookupFinish(WINPR_SAM* sam)
+static void SamLookupFinish(WINPR_SAM* sam)
{
free(sam->buffer);
-
sam->buffer = NULL;
sam->line = NULL;
}
-void HexStrToBin(char* str, BYTE* bin, int length)
+static void HexStrToBin(char* str, BYTE* bin, int length)
{
int i;
-
CharUpperBuffA(str, length * 2);
for (i = 0; i < length; i++)
char* p[7];
int LmHashLength;
int NtHashLength;
-
p[0] = sam->line;
p[1] = strchr(p[0], ':') + 1;
p[2] = strchr(p[1], ':') + 1;
p[4] = strchr(p[3], ':') + 1;
p[5] = strchr(p[4], ':') + 1;
p[6] = p[0] + strlen(p[0]);
-
- entry->UserLength = (UINT32) (p[1] - p[0] - 1);
- entry->DomainLength = (UINT32) (p[2] - p[1] - 1);
-
- LmHashLength = (int) (p[3] - p[2] - 1);
- NtHashLength = (int) (p[4] - p[3] - 1);
-
+ entry->UserLength = (UINT32)(p[1] - p[0] - 1);
+ entry->DomainLength = (UINT32)(p[2] - p[1] - 1);
+ LmHashLength = (int)(p[3] - p[2] - 1);
+ NtHashLength = (int)(p[4] - p[3] - 1);
entry->User = (LPSTR) malloc(entry->UserLength + 1);
memcpy(entry->User, p[0], entry->UserLength);
entry->User[entry->UserLength] = '\0';
int length;
BOOL found = 0;
WINPR_SAM_ENTRY* entry;
-
entry = (WINPR_SAM_ENTRY*) malloc(sizeof(WINPR_SAM_ENTRY));
-
SamLookupStart(sam);
while (sam->line != NULL)
LPWSTR EntryDomain;
UINT32 EntryDomainLength;
WINPR_SAM_ENTRY* entry;
-
entry = (WINPR_SAM_ENTRY*) malloc(sizeof(WINPR_SAM_ENTRY));
-
SamLookupStart(sam);
while (sam->line != NULL)
{
DomainMatch = 0;
UserMatch = 0;
-
entry = SamReadEntry(sam, entry);
if (DomainLength > 0)
EntryDomainLength = (UINT32) strlen(entry->Domain) * 2;
EntryDomain = (LPWSTR) malloc(EntryDomainLength + 2);
MultiByteToWideChar(CP_ACP, 0, entry->Domain, EntryDomainLength / 2,
- (LPWSTR) EntryDomain, EntryDomainLength / 2);
+ (LPWSTR) EntryDomain, EntryDomainLength / 2);
if (DomainLength == EntryDomainLength)
{
DomainMatch = 1;
}
}
+
free(EntryDomain);
}
else
EntryUserLength = (UINT32) strlen(entry->User) * 2;
EntryUser = (LPWSTR) malloc(EntryUserLength + 2);
MultiByteToWideChar(CP_ACP, 0, entry->User, EntryUserLength / 2,
- (LPWSTR) EntryUser, EntryUserLength / 2);
+ (LPWSTR) EntryUser, EntryUserLength / 2);
if (UserLength == EntryUserLength)
{
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/ssl.h>
+#include <winpr/thread.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
+#include "../log.h"
+#define TAG WINPR_TAG("utils.ssl")
+
static int g_winpr_openssl_num_locks = 0;
static HANDLE* g_winpr_openssl_locks = NULL;
static BOOL g_winpr_openssl_initialized_by_winpr = FALSE;
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
-static unsigned long _winpr_openssl_id()
+static unsigned long _winpr_openssl_id(void)
{
return (unsigned long)GetCurrentThreadId();
}
#endif
-static void _winpr_openssl_locking(int mode, int type, const char *file, int line)
+static void _winpr_openssl_locking(int mode, int type, const char* file, int line)
{
if (mode & CRYPTO_LOCK)
{
}
}
-static struct CRYPTO_dynlock_value *_winpr_openssl_dynlock_create(const char *file, int line)
+static struct CRYPTO_dynlock_value* _winpr_openssl_dynlock_create(const char* file, int line)
{
- struct CRYPTO_dynlock_value *dynlock = (struct CRYPTO_dynlock_value *)
- malloc(sizeof(struct CRYPTO_dynlock_value));
+ struct CRYPTO_dynlock_value* dynlock = (struct CRYPTO_dynlock_value*)
+ malloc(sizeof(struct CRYPTO_dynlock_value));
- if (dynlock) {
+ if (dynlock)
+ {
dynlock->mutex = CreateMutex(NULL, FALSE, NULL);
}
return dynlock;
}
-static void _winpr_openssl_dynlock_lock(int mode, struct CRYPTO_dynlock_value *dynlock, const char *file, int line)
+static void _winpr_openssl_dynlock_lock(int mode, struct CRYPTO_dynlock_value* dynlock, const char* file, int line)
{
if (mode & CRYPTO_LOCK)
{
}
}
-static void _winpr_openssl_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock, const char *file, int line)
+static void _winpr_openssl_dynlock_destroy(struct CRYPTO_dynlock_value* dynlock, const char* file, int line)
{
CloseHandle(dynlock->mutex);
free(dynlock);
}
-static BOOL _winpr_openssl_initialize_locking()
+static BOOL _winpr_openssl_initialize_locking(void)
{
int i, count;
if (CRYPTO_get_locking_callback())
{
- fprintf(stderr, "%s: warning: OpenSSL static locking callback is already set\n", __FUNCTION__);
+ WLog_WARN(TAG, "OpenSSL static locking callback is already set");
}
else
{
if ((count = CRYPTO_num_locks()) > 0)
{
- HANDLE *locks;
+ HANDLE* locks;
+
if (!(locks = calloc(count, sizeof(HANDLE))))
{
- fprintf(stderr, "%s: error allocating lock table\n", __FUNCTION__);
+ WLog_ERR(TAG, "error allocating lock table");
return FALSE;
}
{
if (!(locks[i] = CreateMutex(NULL, FALSE, NULL)))
{
- fprintf(stderr, "%s: error creating lock #%d\n", __FUNCTION__, i);
+ WLog_ERR(TAG, "error creating lock #%d", i);
+
while (i--)
{
CloseHandle(g_winpr_openssl_locks[i]);
}
+
free(locks);
return FALSE;
}
g_winpr_openssl_locks = locks;
g_winpr_openssl_num_locks = count;
-
CRYPTO_set_locking_callback(_winpr_openssl_locking);
}
}
-
/* OpenSSL dynamic locking */
if (CRYPTO_get_dynlock_create_callback() ||
- CRYPTO_get_dynlock_lock_callback() ||
- CRYPTO_get_dynlock_destroy_callback())
+ CRYPTO_get_dynlock_lock_callback() ||
+ CRYPTO_get_dynlock_destroy_callback())
{
- fprintf(stderr, "%s: warning: dynamic locking callbacks are already set\n", __FUNCTION__);
+ WLog_WARN(TAG, "dynamic locking callbacks are already set");
}
else
{
CRYPTO_set_dynlock_destroy_callback(_winpr_openssl_dynlock_destroy);
}
-
/* Use the deprecated CRYPTO_get_id_callback() if building against OpenSSL < 1.0.0 */
-
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
+
if (CRYPTO_get_id_callback())
{
- fprintf(stderr, "%s: warning OpenSSL id_callback is already set\n", __FUNCTION__);
+ WLog_WARN(TAG, "OpenSSL id_callback is already set");
}
else
{
CRYPTO_set_id_callback(_winpr_openssl_id);
}
-#endif
+#endif
return TRUE;
}
-static BOOL _winpr_openssl_cleanup_locking()
+static BOOL _winpr_openssl_cleanup_locking(void)
{
/* undo our static locking modifications */
-
if (CRYPTO_get_locking_callback() == _winpr_openssl_locking)
{
int i;
-
CRYPTO_set_locking_callback(NULL);
for (i = 0; i < g_winpr_openssl_num_locks; i++)
g_winpr_openssl_locks = NULL;
}
-
/* unset our dynamic locking callbacks */
if (CRYPTO_get_dynlock_create_callback() == _winpr_openssl_dynlock_create)
CRYPTO_set_dynlock_destroy_callback(NULL);
}
-
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
+
if (CRYPTO_get_id_callback() == _winpr_openssl_id)
{
CRYPTO_set_id_callback(NULL);
}
-#endif
+#endif
return TRUE;
}
-static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVOID *context)
+static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVOID* context)
{
DWORD flags = param ? *(PDWORD)param : WINPR_SSL_INIT_DEFAULT;
if (flags & WINPR_SSL_INIT_ENABLE_LOCKING)
{
- if (!_winpr_openssl_initialize_locking(FALSE))
+ if (!_winpr_openssl_initialize_locking())
{
return FALSE;
}
/* SSL_load_error_strings() is void */
SSL_load_error_strings();
-
/* SSL_library_init() always returns "1" */
SSL_library_init();
-
g_winpr_openssl_initialized_by_winpr = TRUE;
-
return TRUE;
}
{
if (!g_winpr_openssl_initialized_by_winpr)
{
- fprintf(stderr, "%s: warning: ssl was not initialized by winpr\n", __FUNCTION__);
+ WLog_WARN(TAG, "ssl was not initialized by winpr");
return FALSE;
}
+
g_winpr_openssl_initialized_by_winpr = FALSE;
_winpr_openssl_cleanup_locking();
CRYPTO_cleanup_all_ex_data();
DWORD i, j;
char str[64];
- for (i = 0; i < 256; )
+ for (i = 0; i < 256;)
{
printf("\t");
if (0)
{
/* Least Significant Bit First */
-
str[0] = (i & (1 << 7)) ? '1' : '0';
str[1] = (i & (1 << 6)) ? '1' : '0';
str[2] = (i & (1 << 5)) ? '1' : '0';
else
{
/* Most Significant Bit First */
-
str[7] = (i & (1 << 7)) ? '1' : '0';
str[6] = (i & (1 << 6)) ? '1' : '0';
str[5] = (i & (1 << 5)) ? '1' : '0';
}
printf("\"%s\",%s", str, j == 3 ? "" : " ");
-
i++;
}
{
wBitStream* bs;
BYTE buffer[1024];
-
ZeroMemory(buffer, sizeof(buffer));
-
bs = BitStream_New();
-
BitStream_Attach(bs, buffer, sizeof(buffer));
-
BitStream_Write_Bits(bs, 0xAF, 8); /* 11110101 */
BitStream_Write_Bits(bs, 0xF, 4); /* 1111 */
BitStream_Write_Bits(bs, 0xA, 4); /* 0101 */
-
BitStream_Flush(bs);
- BitDump(buffer, bs->position, BITDUMP_MSB_FIRST);
-
+ BitDump(__FUNCTION__, WLOG_INFO, buffer, bs->position, BITDUMP_MSB_FIRST);
BitStream_Write_Bits(bs, 3, 2); /* 11 */
BitStream_Write_Bits(bs, 0, 3); /* 000 */
BitStream_Write_Bits(bs, 0x2D, 6); /* 101101 */
BitStream_Write_Bits(bs, 0x19, 5); /* 11001 */
-
//BitStream_Flush(bs); /* flush should be done automatically here (32 bits written) */
- BitDump(buffer, bs->position, BITDUMP_MSB_FIRST);
-
+ BitDump(__FUNCTION__, WLOG_INFO, buffer, bs->position, BITDUMP_MSB_FIRST);
BitStream_Write_Bits(bs, 3, 2); /* 11 */
-
BitStream_Flush(bs);
- BitDump(buffer, bs->position, BITDUMP_MSB_FIRST);
-
+ BitDump(__FUNCTION__, WLOG_INFO, buffer, bs->position, BITDUMP_MSB_FIRST);
BitStream_Write_Bits(bs, 00, 2); /* 00 */
BitStream_Write_Bits(bs, 0xF, 4); /* 1111 */
-
BitStream_Write_Bits(bs, 0, 20);
BitStream_Write_Bits(bs, 0xAFF, 12); /* 111111110101 */
-
BitStream_Flush(bs);
- BitDump(buffer, bs->position, BITDUMP_MSB_FIRST);
-
+ BitDump(__FUNCTION__, WLOG_INFO, buffer, bs->position, BITDUMP_MSB_FIRST);
BitStream_Free(bs);
-
return 0;
}
* Internal Variables
*
*************************************************************************/
-
-static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.131 2010/09/12 11:08:08 breese Exp $";
+/* Unused but kept for reference */
+/* static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.131 2010/09/12 11:08:08 breese Exp $"; */
#if TRIO_FEATURE_FLOAT
/*
#if defined(__cplusplus)
# define PREDEF_STANDARD_CXX
-#endif
-#if __cplusplus - 0 >= 199711L
-# define PREDEF_STANDARD_CXX89
+# if __cplusplus - 0 >= 199711L
+# define PREDEF_STANDARD_CXX89
+# endif
#endif
#if defined(TRIO_PLATFORM_UNIX)
*/
#if !defined(TRIO_EMBED_NAN)
-static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $";
+/* Unused but kept for reference */
+/* static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $"; */
#endif
#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE) \
*/
#if !defined(TRIO_EMBED_STRING)
-static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $";
+/* Unused but kept for reference */
+/* static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; */
#endif
/*************************************************************************
#include "config.h"
#endif
+#include <assert.h>
+
#include <winpr/crt.h>
#include <winpr/file.h>
#include <winpr/path.h>
ProcessId = GetCurrentProcessId();
+ if (!log || !appender)
+ return -1;
+
if (!appender->FilePath)
{
appender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog");
int FunctionNameLength;
int TextStringLength;
+ if (!log || !appender || !message)
+ return -1;
+
fp = appender->FileDescriptor;
if (!fp)
#include "wlog/ConsoleAppender.h"
+#ifdef ANDROID
+#include <android/log.h>
+#endif
+
/**
* Console Appender
*/
return 1;
}
#endif
+#ifdef ANDROID
+ (void)fp;
+ android_LogPriority level;
+ switch(message->Level)
+ {
+ case WLOG_TRACE:
+ level = ANDROID_LOG_VERBOSE;
+ break;
+ case WLOG_DEBUG:
+ level = ANDROID_LOG_DEBUG;
+ break;
+ case WLOG_INFO:
+ level = ANDROID_LOG_INFO;
+ break;
+ case WLOG_WARN:
+ level = ANDROID_LOG_WARN;
+ break;
+ case WLOG_ERROR:
+ level = ANDROID_LOG_ERROR;
+ break;
+ case WLOG_FATAL:
+ level = ANDROID_LOG_FATAL;
+ break;
+ case WLOG_OFF:
+ level = ANDROID_LOG_SILENT;
+ break;
+ default:
+ level = ANDROID_LOG_FATAL;
+ break;
+ }
+ if (level != ANDROID_LOG_SILENT)
+ __android_log_print(level, log->Name, "%s%s", message->PrefixString, message->TextString);
+
+#else
fp = (appender->outputStream == WLOG_CONSOLE_STDERR) ? stderr : stdout;
fprintf(fp, "%s%s\n", message->PrefixString, message->TextString);
-
+#endif
return 1;
}
free(FullFileName);
}
- WLog_PacketMessage_Write((wPcap*) appender->PacketMessageContext,
- message->PacketData, message->PacketLength, message->PacketFlags);
+ if (appender->PacketMessageContext)
+ WLog_PacketMessage_Write((wPcap*) appender->PacketMessageContext,
+ message->PacketData, message->PacketLength, message->PacketFlags);
return PacketId;
}
#include "wlog/DataMessage.h"
+#include "../../log.h"
+#define TAG WINPR_TAG("utils.wlog")
+
int WLog_DataMessage_Write(char* filename, void* data, int length)
{
FILE* fp;
-
fp = fopen(filename, "w+b");
if (!fp)
{
- fprintf(stderr, "failed to open file %s\n", filename);
+ WLog_ERR(TAG, "failed to open file %s", filename);
return -1;
}
fwrite(data, length, 1, fp);
-
fclose(fp);
-
return 0;
}
ProcessId = GetCurrentProcessId();
+ if (!log || !appender)
+ return -1;
+
if (!appender->FilePath)
{
appender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog");
int WLog_FileAppender_Close(wLog* log, wLogFileAppender* appender)
{
+ if (!log || !appender)
+ return -1;
+
if (!appender->FileDescriptor)
return 0;
FILE* fp;
char prefix[WLOG_MAX_PREFIX_SIZE];
+ if (!log || !appender || !message)
+ return -1;
+
fp = appender->FileDescriptor;
if (!fp)
int DataId;
char* FullFileName;
+ if (!log || !appender || !message)
+ return -1;
+
DataId = g_DataId++;
FullFileName = WLog_Message_GetOutputFileName(DataId, "dat");
int ImageId;
char* FullFileName;
+ if (!log || !appender || !message)
+ return -1;
+
ImageId = g_ImageId++;
FullFileName = WLog_Message_GetOutputFileName(ImageId, "bmp");
#include "wlog/ImageMessage.h"
-#include <stdio.h>
-#include <string.h>
-
-typedef struct
-{
- BYTE magic[2];
-} BITMAP_MAGIC;
-
-typedef struct
-{
- UINT32 filesz;
- UINT16 creator1;
- UINT16 creator2;
- UINT32 bmp_offset;
-} BITMAP_CORE_HEADER;
-
-typedef struct
-{
- UINT32 header_sz;
- INT32 width;
- INT32 height;
- UINT16 nplanes;
- UINT16 bitspp;
- UINT32 compress_type;
- UINT32 bmp_bytesz;
- INT32 hres;
- INT32 vres;
- UINT32 ncolors;
- UINT32 nimpcolors;
-} BITMAP_INFO_HEADER;
-
int WLog_ImageMessage_Write(char* filename, void* data, int width, int height, int bpp)
{
- FILE* fp;
- BITMAP_MAGIC magic;
- BITMAP_CORE_HEADER header;
- BITMAP_INFO_HEADER info_header;
+ int status;
- fp = fopen(filename, "w+b");
+ status = winpr_bitmap_write(filename, data, width, height, bpp);
- if (!fp)
- {
- fprintf(stderr, "failed to open file %s\n", filename);
+ if (status < 0)
return -1;
- }
-
- magic.magic[0] = 'B';
- magic.magic[1] = 'M';
-
- header.creator1 = 0;
- header.creator2 = 0;
-
- header.bmp_offset =
- sizeof(BITMAP_MAGIC) +
- sizeof(BITMAP_CORE_HEADER) +
- sizeof(BITMAP_INFO_HEADER);
-
- info_header.bmp_bytesz = width * height * (bpp / 8);
-
- header.filesz =
- header.bmp_offset +
- info_header.bmp_bytesz;
-
- info_header.width = width;
- info_header.height = (-1) * height;
- info_header.nplanes = 1;
- info_header.bitspp = bpp;
- info_header.compress_type = 0;
- info_header.hres = width;
- info_header.vres = height;
- info_header.ncolors = 0;
- info_header.nimpcolors = 0;
- info_header.header_sz = sizeof(BITMAP_INFO_HEADER);
-
- fwrite((void*) &magic, sizeof(BITMAP_MAGIC), 1, fp);
- fwrite((void*) &header, sizeof(BITMAP_CORE_HEADER), 1, fp);
- fwrite((void*) &info_header, sizeof(BITMAP_INFO_HEADER), 1, fp);
- fwrite((void*) data, info_header.bmp_bytesz, 1, fp);
-
- fclose(fp);
- return 0;
+ return 1;
}
if (env)
layout->FormatString = env;
else
+ {
+#ifdef ANDROID
+ layout->FormatString = _strdup("[pid=%pid:tid=%tid] - ");
+#else
layout->FormatString = _strdup("[%hr:%mi:%se:%ml] [%pid:%tid] [%lv][%mn] - ");
+#endif
+ }
}
return layout;
#include <winpr/crt.h>
#include <winpr/stream.h>
+#include "../../log.h"
+#define TAG WINPR_TAG("utils.wlog")
+
#ifndef _WIN32
#include <sys/time.h>
#else
void Pcap_Read_Header(wPcap* pcap, wPcapHeader* header)
{
- fread((void*) header, sizeof(wPcapHeader), 1, pcap->fp);
+ if (pcap && pcap->fp)
+ fread((void*) header, sizeof(wPcapHeader), 1, pcap->fp);
}
void Pcap_Write_Header(wPcap* pcap, wPcapHeader* header)
{
- fwrite((void*) header, sizeof(wPcapHeader), 1, pcap->fp);
+ if (pcap && pcap->fp)
+ fwrite((void*) header, sizeof(wPcapHeader), 1, pcap->fp);
}
void Pcap_Read_RecordHeader(wPcap* pcap, wPcapRecordHeader* record)
{
- fread((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp);
+ if (pcap && pcap->fp)
+ fread((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp);
}
void Pcap_Write_RecordHeader(wPcap* pcap, wPcapRecordHeader* record)
{
- fwrite((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp);
+ if (pcap && pcap->fp)
+ fwrite((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp);
}
void Pcap_Write_RecordContent(wPcap* pcap, wPcapRecord* record)
{
- fwrite(record->data, record->length, 1, pcap->fp);
+ if (pcap && pcap->fp)
+ fwrite(record->data, record->length, 1, pcap->fp);
}
void Pcap_Read_Record(wPcap* pcap, wPcapRecord* record)
{
- Pcap_Read_RecordHeader(pcap, &record->header);
- record->length = record->header.incl_len;
- record->data = malloc(record->length);
- fread(record->data, record->length, 1, pcap->fp);
+ if (pcap && pcap->fp)
+ {
+ Pcap_Read_RecordHeader(pcap, &record->header);
+ record->length = record->header.incl_len;
+ record->data = malloc(record->length);
+ fread(record->data, record->length, 1, pcap->fp);
+ }
}
void Pcap_Write_Record(wPcap* pcap, wPcapRecord* record)
{
pcap->tail = (wPcapRecord*) malloc(sizeof(wPcapRecord));
ZeroMemory(pcap->tail, sizeof(wPcapRecord));
-
pcap->head = pcap->tail;
pcap->record = pcap->head;
record = pcap->tail;
{
record = (wPcapRecord*) malloc(sizeof(wPcapRecord));
ZeroMemory(record, sizeof(wPcapRecord));
-
pcap->tail->next = record;
pcap->tail = record;
}
record->length = length;
record->header.incl_len = length;
record->header.orig_len = length;
-
gettimeofday(&tp, 0);
record->header.ts_sec = tp.tv_sec;
record->header.ts_usec = tp.tv_usec;
Pcap_Read_RecordHeader(pcap, &record->header);
record->length = record->header.incl_len;
-
return TRUE;
}
BOOL Pcap_GetNext_RecordContent(wPcap* pcap, wPcapRecord* record)
{
- fread(record->data, record->length, 1, pcap->fp);
- return TRUE;
+ if (pcap && pcap->fp)
+ {
+ fread(record->data, record->length, 1, pcap->fp);
+ return TRUE;
+ }
+
+ return FALSE;
}
BOOL Pcap_GetNext_Record(wPcap* pcap, wPcapRecord* record)
return FALSE;
Pcap_Read_Record(pcap, record);
-
return TRUE;
}
wPcap* Pcap_Open(char* name, BOOL write)
{
wPcap* pcap;
-
FILE* pcap_fp = fopen(name, write ? "w+b" : "rb");
if (!pcap_fp)
{
- perror("opening pcap file");
+ WLog_ERR(TAG,"opening pcap file");
return NULL;
}
if (pcap)
{
ZeroMemory(pcap, sizeof(wPcap));
-
pcap->name = name;
pcap->write = write;
pcap->record_count = 0;
pcap->header.network = 1; /* ethernet */
Pcap_Write_Header(pcap, &pcap->header);
}
- else
+ else if (pcap->fp)
{
fseek(pcap->fp, 0, SEEK_END);
pcap->file_size = (int) ftell(pcap->fp);
void Pcap_Flush(wPcap* pcap)
{
+ if (!pcap || !pcap->fp)
+ return;
+
while (pcap->record)
{
Pcap_Write_Record(pcap, pcap->record);
pcap->record = pcap->record->next;
}
- if (pcap->fp)
- fflush(pcap->fp);
+ fflush(pcap->fp);
}
void Pcap_Close(wPcap* pcap)
{
- Pcap_Flush(pcap);
-
- if (pcap->fp)
- fclose(pcap->fp);
+ if (!pcap || !pcap->fp)
+ return;
+ Pcap_Flush(pcap);
+ fclose(pcap->fp);
free(pcap);
}
wStream* s;
BYTE buffer[14];
- s = Stream_New(buffer, 14);
+ if (!pcap || !pcap->fp || !ethernet)
+ return -1;
+ s = Stream_New(buffer, 14);
Stream_Write(s, ethernet->Destination, 6);
Stream_Write(s, ethernet->Source, 6);
Stream_Write_UINT16_BE(s, ethernet->Type);
-
fwrite(buffer, 14, 1, pcap->fp);
-
Stream_Free(s, FALSE);
-
return 0;
}
while (checksum >> 16)
checksum = (checksum & 0xFFFF) + (checksum >> 16);
- return (UINT16) (~checksum);
+ return (UINT16)(~checksum);
}
int WLog_PacketMessage_Write_IPv4Header(wPcap* pcap, wIPv4Header* ipv4)
wStream* s;
BYTE buffer[20];
- s = Stream_New(buffer, 20);
+ if (!pcap || !pcap->fp || !ipv4)
+ return -1;
+ s = Stream_New(buffer, 20);
Stream_Write_UINT8(s, (ipv4->Version << 4) | ipv4->InternetHeaderLength);
Stream_Write_UINT8(s, ipv4->TypeOfService);
Stream_Write_UINT16_BE(s, ipv4->TotalLength);
Stream_Write_UINT16(s, ipv4->HeaderChecksum);
Stream_Write_UINT32_BE(s, ipv4->SourceAddress);
Stream_Write_UINT32_BE(s, ipv4->DestinationAddress);
-
ipv4->HeaderChecksum = IPv4Checksum((BYTE*) buffer, 20);
Stream_Rewind(s, 10);
Stream_Write_UINT16(s, ipv4->HeaderChecksum);
Stream_Seek(s, 8);
-
fwrite(buffer, 20, 1, pcap->fp);
-
Stream_Free(s, FALSE);
-
return 0;
}
wStream* s;
BYTE buffer[20];
- s = Stream_New(buffer, 20);
+ if (!pcap || !pcap->fp || !tcp)
+ return -1;
+ s = Stream_New(buffer, 20);
Stream_Write_UINT16_BE(s, tcp->SourcePort);
Stream_Write_UINT16_BE(s, tcp->DestinationPort);
Stream_Write_UINT32_BE(s, tcp->SequenceNumber);
Stream_Write_UINT16_BE(s, tcp->Checksum);
Stream_Write_UINT16_BE(s, tcp->UrgentPointer);
- fwrite(buffer, 20, 1, pcap->fp);
+ if (pcap->fp)
+ fwrite(buffer, 20, 1, pcap->fp);
Stream_Free(s, FALSE);
-
return 0;
}
struct timeval tp;
wPcapRecord record;
wEthernetHeader ethernet;
-
ethernet.Type = 0x0800;
+ if (!pcap || !pcap->fp)
+ return -1;
+
if (flags & WLOG_PACKET_OUTBOUND)
{
/* 00:15:5D:01:64:04 */
ethernet.Source[3] = 0x01;
ethernet.Source[4] = 0x64;
ethernet.Source[5] = 0x04;
-
/* 00:15:5D:01:64:01 */
ethernet.Destination[0] = 0x00;
ethernet.Destination[1] = 0x15;
ethernet.Source[3] = 0x01;
ethernet.Source[4] = 0x64;
ethernet.Source[5] = 0x01;
-
/* 00:15:5D:01:64:04 */
ethernet.Destination[0] = 0x00;
ethernet.Destination[1] = 0x15;
ipv4.Version = 4;
ipv4.InternetHeaderLength = 5;
ipv4.TypeOfService = 0;
- ipv4.TotalLength = (UINT16) (length + 20 + 20);
+ ipv4.TotalLength = (UINT16)(length + 20 + 20);
ipv4.Identification = 0;
ipv4.InternetProtocolFlags = 0x02;
ipv4.FragmentOffset = 0;
tcp.Window = 0x7FFF;
tcp.Checksum = 0;
tcp.UrgentPointer = 0;
-
record.data = data;
record.length = length;
record.header.incl_len = record.length + 14 + 20 + 20;
record.header.orig_len = record.length + 14 + 20 + 20;
record.next = NULL;
-
gettimeofday(&tp, 0);
record.header.ts_sec = tp.tv_sec;
record.header.ts_usec = tp.tv_usec;
-
Pcap_Write_RecordHeader(pcap, &record.header);
WLog_PacketMessage_Write_EthernetHeader(pcap, ðernet);
WLog_PacketMessage_Write_IPv4Header(pcap, &ipv4);
WLog_PacketMessage_Write_TcpHeader(pcap, &tcp);
Pcap_Write_RecordContent(pcap, &record);
fflush(pcap->fp);
-
return 0;
}
#include <winpr/crt.h>
#include <winpr/print.h>
+#include <winpr/debug.h>
#include <winpr/environment.h>
+#if defined(ANDROID)
+#include <android/log.h>
+#endif
+
#include <winpr/wlog.h>
#include "wlog/wlog.h"
+#include "../../log.h"
+
/**
* References for general logging concepts:
*
static DWORD g_FilterCount = 0;
static wLogFilter* g_Filters = NULL;
+static void log_recursion(const char* file, const char* fkt, int line)
+{
+ size_t used, i;
+ void* bt = winpr_backtrace(20);
+ char** msg = winpr_backtrace_symbols(bt, &used);
+#if defined(ANDROID)
+ const char* tag = WINPR_TAG("utils.wlog");
+ __android_log_print(ANDROID_LOG_FATAL, tag, "Recursion detected!!!");
+ __android_log_print(ANDROID_LOG_FATAL, tag, "Check %s [%s:%d]", fkt, file, line);
+
+ for (i=0; i<used; i++)
+ __android_log_print(ANDROID_LOG_FATAL, tag, "%d: %s", msg[i]);
+
+#else
+ fprintf(stderr, "[%s]: Recursion detected!\n", fkt);
+ fprintf(stderr, "[%s]: Check %s:%d\n", fkt, file, line);
+
+ for (i=0; i<used; i++)
+ fprintf(stderr, "%s: %zd: %s\n", fkt, i, msg[i]);
+
+#endif
+
+ if (msg)
+ free(msg);
+
+ winpr_backtrace_free(bt);
+}
+
int WLog_Write(wLog* log, wLogMessage* message)
{
- int status;
+ int status = -1;
wLogAppender* appender;
-
appender = WLog_GetLogAppender(log);
if (!appender)
EnterCriticalSection(&appender->lock);
- status = appender->WriteMessage(log, appender, message);
+ if (appender->recursive)
+ log_recursion(message->FileName, message->FunctionName, message->LineNumber);
+ else
+ {
+ appender->recursive = TRUE;
+ status = appender->WriteMessage(log, appender, message);
+ appender->recursive = FALSE;
+ }
LeaveCriticalSection(&appender->lock);
-
return status;
}
int WLog_WriteData(wLog* log, wLogMessage* message)
{
- int status;
+ int status = -1;
wLogAppender* appender;
-
appender = WLog_GetLogAppender(log);
if (!appender)
EnterCriticalSection(&appender->lock);
- status = appender->WriteDataMessage(log, appender, message);
+ if (appender->recursive)
+ log_recursion(message->FileName, message->FunctionName, message->LineNumber);
+ else
+ {
+ appender->recursive = TRUE;
+ status = appender->WriteDataMessage(log, appender, message);
+ appender->recursive = FALSE;
+ }
LeaveCriticalSection(&appender->lock);
-
return status;
}
int WLog_WriteImage(wLog* log, wLogMessage* message)
{
- int status;
+ int status = -1;
wLogAppender* appender;
-
appender = WLog_GetLogAppender(log);
if (!appender)
EnterCriticalSection(&appender->lock);
- status = appender->WriteImageMessage(log, appender, message);
+ if (appender->recursive)
+ log_recursion(message->FileName, message->FunctionName, message->LineNumber);
+ else
+ {
+ appender->recursive = TRUE;
+ status = appender->WriteImageMessage(log, appender, message);
+ appender->recursive = FALSE;
+ }
LeaveCriticalSection(&appender->lock);
-
return status;
}
int WLog_WritePacket(wLog* log, wLogMessage* message)
{
- int status;
+ int status = -1;
wLogAppender* appender;
-
appender = WLog_GetLogAppender(log);
if (!appender)
EnterCriticalSection(&appender->lock);
- status = appender->WritePacketMessage(log, appender, message);
+ if (appender->recursive)
+ log_recursion(message->FileName, message->FunctionName, message->LineNumber);
+ else
+ {
+ appender->recursive = TRUE;
+ status = appender->WritePacketMessage(log, appender, message);
+ appender->recursive = FALSE;
+ }
LeaveCriticalSection(&appender->lock);
-
return status;
}
{
char formattedLogMessage[WLOG_MAX_STRING_SIZE];
wvsnprintfx(formattedLogMessage, WLOG_MAX_STRING_SIZE - 1, message->FormatString, args);
-
message->TextString = formattedLogMessage;
status = WLog_Write(log, message);
}
{
message->Data = va_arg(args, void*);
message->Length = va_arg(args, int);
-
status = WLog_WriteData(log, message);
}
else if (message->Type == WLOG_MESSAGE_IMAGE)
message->ImageWidth = va_arg(args, int);
message->ImageHeight = va_arg(args, int);
message->ImageBpp = va_arg(args, int);
-
status = WLog_WriteImage(log, message);
}
else if (message->Type == WLOG_MESSAGE_PACKET)
message->PacketData = va_arg(args, void*);
message->PacketLength = va_arg(args, int);
message->PacketFlags = va_arg(args, int);
-
status = WLog_WritePacket(log, message);
}
{
int status;
va_list args;
-
va_start(args, message);
-
status = WLog_PrintMessageVA(log, message, args);
-
va_end(args);
}
int count;
LPSTR names;
int iLevel;
-
count = 1;
p = (char*) name;
filter->NameCount = count;
filter->Names = (LPSTR*) malloc(sizeof(LPSTR) * (count + 1));
filter->Names[count] = NULL;
-
count = 0;
p = (char*) names;
filter->Names[count++] = p;
-
q = strrchr(p, ':');
if (!q)
*q = '\0';
q++;
-
iLevel = WLog_ParseLogLevel(q);
if (iLevel < 0)
DWORD nSize;
int status;
char** strs;
-
nSize = GetEnvironmentVariableA("WLOG_FILTER", NULL, 0);
if (nSize < 1)
return -1;
nSize = GetEnvironmentVariableA("WLOG_FILTER", env, nSize);
-
count = 1;
p = env;
}
g_FilterCount = count;
-
p = env;
count = 0;
strs = (char**) calloc(g_FilterCount, sizeof(char*));
-
strs[count++] = p;
while ((p = strchr(p, ',')) != NULL)
}
free(strs);
-
return 0;
}
char* p;
int count;
LPSTR names;
-
count = 1;
p = (char*) name;
log->NameCount = count;
log->Names = (LPSTR*) malloc(sizeof(LPSTR) * (count + 1));
log->Names[count] = NULL;
-
count = 0;
p = (char*) names;
log->Names[count++] = p;
char* env;
DWORD nSize;
int iLevel;
-
log = (wLog*) calloc(1, sizeof(wLog));
if (log)
return NULL;
WLog_ParseName(log, name);
-
log->Parent = rootLogger;
log->ChildrenCount = 0;
-
log->ChildrenSize = 16;
log->Children = (wLog**) calloc(log->ChildrenSize, sizeof(wLog*));
else
{
log->Level = WLOG_WARN;
-
nSize = GetEnvironmentVariableA("WLOG_LEVEL", NULL, 0);
if (nSize)
{
env = (LPSTR) malloc(nSize);
nSize = GetEnvironmentVariableA("WLOG_LEVEL", env, nSize);
-
iLevel = WLog_ParseLogLevel(env);
if (iLevel >= 0)
free(log->Names[0]);
free(log->Names);
free(log->Children);
-
free(log);
}
}
{
g_RootLog = WLog_New("", NULL);
g_RootLog->IsRoot = TRUE;
-
WLog_ParseFilters();
-
logAppenderType = WLOG_APPENDER_CONSOLE;
-
nSize = GetEnvironmentVariableA("WLOG_APPENDER", NULL, 0);
if (nSize)
parent->Children[parent->ChildrenCount++] = child;
child->Parent = parent;
-
return 0;
}
wLog* root;
wLog* child = NULL;
BOOL found = FALSE;
-
root = WLog_GetRoot();
for (index = 0; index < root->ChildrenCount; index++)
{
wLog* log;
wLog* root;
-
root = WLog_GetRoot();
-
log = WLog_FindChild(name);
if (!log)
void WLog_Uninit()
{
wLog* root = WLog_GetRoot();
-
DWORD index;
wLog* child = NULL;
#include "wtsapi.h"
+#include "../log.h"
+#define TAG WINPR_TAG("wtsapi")
+
/**
* Remote Desktop Services API Functions:
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa383464/
static PWtsApiFunctionTable g_WtsApi = NULL;
+static HMODULE g_WtsApi32Module = NULL;
+
+static WtsApiFunctionTable WtsApi32_WtsApiFunctionTable =
+{
+ 0, /* dwVersion */
+ 0, /* dwFlags */
+
+ NULL, /* StopRemoteControlSession */
+ NULL, /* StartRemoteControlSessionW */
+ NULL, /* StartRemoteControlSessionA */
+ NULL, /* ConnectSessionW */
+ NULL, /* ConnectSessionA */
+ NULL, /* EnumerateServersW */
+ NULL, /* EnumerateServersA */
+ NULL, /* OpenServerW */
+ NULL, /* OpenServerA */
+ NULL, /* OpenServerExW */
+ NULL, /* OpenServerExA */
+ NULL, /* CloseServer */
+ NULL, /* EnumerateSessionsW */
+ NULL, /* EnumerateSessionsA */
+ NULL, /* EnumerateSessionsExW */
+ NULL, /* EnumerateSessionsExA */
+ NULL, /* EnumerateProcessesW */
+ NULL, /* EnumerateProcessesA */
+ NULL, /* TerminateProcess */
+ NULL, /* QuerySessionInformationW */
+ NULL, /* QuerySessionInformationA */
+ NULL, /* QueryUserConfigW */
+ NULL, /* QueryUserConfigA */
+ NULL, /* SetUserConfigW */
+ NULL, /* SetUserConfigA */
+ NULL, /* SendMessageW */
+ NULL, /* SendMessageA */
+ NULL, /* DisconnectSession */
+ NULL, /* LogoffSession */
+ NULL, /* ShutdownSystem */
+ NULL, /* WaitSystemEvent */
+ NULL, /* VirtualChannelOpen */
+ NULL, /* VirtualChannelOpenEx */
+ NULL, /* VirtualChannelClose */
+ NULL, /* VirtualChannelRead */
+ NULL, /* VirtualChannelWrite */
+ NULL, /* VirtualChannelPurgeInput */
+ NULL, /* VirtualChannelPurgeOutput */
+ NULL, /* VirtualChannelQuery */
+ NULL, /* FreeMemory */
+ NULL, /* RegisterSessionNotification */
+ NULL, /* UnRegisterSessionNotification */
+ NULL, /* RegisterSessionNotificationEx */
+ NULL, /* UnRegisterSessionNotificationEx */
+ NULL, /* QueryUserToken */
+ NULL, /* FreeMemoryExW */
+ NULL, /* FreeMemoryExA */
+ NULL, /* EnumerateProcessesExW */
+ NULL, /* EnumerateProcessesExA */
+ NULL, /* EnumerateListenersW */
+ NULL, /* EnumerateListenersA */
+ NULL, /* QueryListenerConfigW */
+ NULL, /* QueryListenerConfigA */
+ NULL, /* CreateListenerW */
+ NULL, /* CreateListenerA */
+ NULL, /* SetListenerSecurityW */
+ NULL, /* SetListenerSecurityA */
+ NULL, /* GetListenerSecurityW */
+ NULL, /* GetListenerSecurityA */
+ NULL, /* EnableChildSessions */
+ NULL, /* IsChildSessionsEnabled */
+ NULL, /* GetChildSessionId */
+ NULL /* GetActiveConsoleSessionId */
+};
+
+#define WTSAPI32_LOAD_PROC(_name, _type) \
+ WtsApi32_WtsApiFunctionTable.p ## _name = (## _type) GetProcAddress(g_WtsApi32Module, "WTS" #_name);
+
+int WtsApi32_InitializeWtsApi(void)
+{
+ g_WtsApi32Module = LoadLibraryA("wtsapi32.dll");
+
+ if (!g_WtsApi32Module)
+ return -1;
+
+#ifdef _WIN32
+ WTSAPI32_LOAD_PROC(StopRemoteControlSession, WTS_STOP_REMOTE_CONTROL_SESSION_FN);
+ WTSAPI32_LOAD_PROC(StartRemoteControlSessionW, WTS_START_REMOTE_CONTROL_SESSION_FN_W);
+ WTSAPI32_LOAD_PROC(StartRemoteControlSessionA, WTS_START_REMOTE_CONTROL_SESSION_FN_A);
+ WTSAPI32_LOAD_PROC(ConnectSessionW, WTS_CONNECT_SESSION_FN_W);
+ WTSAPI32_LOAD_PROC(ConnectSessionA, WTS_CONNECT_SESSION_FN_A);
+ WTSAPI32_LOAD_PROC(EnumerateServersW, WTS_ENUMERATE_SERVERS_FN_W);
+ WTSAPI32_LOAD_PROC(EnumerateServersA, WTS_ENUMERATE_SERVERS_FN_A);
+ WTSAPI32_LOAD_PROC(OpenServerW, WTS_OPEN_SERVER_FN_W);
+ WTSAPI32_LOAD_PROC(OpenServerA, WTS_OPEN_SERVER_FN_A);
+ WTSAPI32_LOAD_PROC(OpenServerExW, WTS_OPEN_SERVER_EX_FN_W);
+ WTSAPI32_LOAD_PROC(OpenServerExA, WTS_OPEN_SERVER_EX_FN_A);
+ WTSAPI32_LOAD_PROC(CloseServer, WTS_CLOSE_SERVER_FN);
+ WTSAPI32_LOAD_PROC(EnumerateSessionsW, WTS_ENUMERATE_SESSIONS_FN_W);
+ WTSAPI32_LOAD_PROC(EnumerateSessionsA, WTS_ENUMERATE_SESSIONS_FN_A);
+ WTSAPI32_LOAD_PROC(EnumerateSessionsExW, WTS_ENUMERATE_SESSIONS_EX_FN_W);
+ WTSAPI32_LOAD_PROC(EnumerateSessionsExA, WTS_ENUMERATE_SESSIONS_EX_FN_A);
+ WTSAPI32_LOAD_PROC(EnumerateProcessesW, WTS_ENUMERATE_PROCESSES_FN_W);
+ WTSAPI32_LOAD_PROC(EnumerateProcessesA, WTS_ENUMERATE_PROCESSES_FN_A);
+ WTSAPI32_LOAD_PROC(TerminateProcess, WTS_TERMINATE_PROCESS_FN);
+ WTSAPI32_LOAD_PROC(QuerySessionInformationW, WTS_QUERY_SESSION_INFORMATION_FN_W);
+ WTSAPI32_LOAD_PROC(QuerySessionInformationA, WTS_QUERY_SESSION_INFORMATION_FN_A);
+ WTSAPI32_LOAD_PROC(QueryUserConfigW, WTS_QUERY_USER_CONFIG_FN_W);
+ WTSAPI32_LOAD_PROC(QueryUserConfigA, WTS_QUERY_USER_CONFIG_FN_A);
+ WTSAPI32_LOAD_PROC(SetUserConfigW, WTS_SET_USER_CONFIG_FN_W);
+ WTSAPI32_LOAD_PROC(SetUserConfigA, WTS_SET_USER_CONFIG_FN_A);
+ WTSAPI32_LOAD_PROC(SendMessageW, WTS_SEND_MESSAGE_FN_W);
+ WTSAPI32_LOAD_PROC(SendMessageA, WTS_SEND_MESSAGE_FN_A);
+ WTSAPI32_LOAD_PROC(DisconnectSession, WTS_DISCONNECT_SESSION_FN);
+ WTSAPI32_LOAD_PROC(LogoffSession, WTS_LOGOFF_SESSION_FN);
+ WTSAPI32_LOAD_PROC(ShutdownSystem, WTS_SHUTDOWN_SYSTEM_FN);
+ WTSAPI32_LOAD_PROC(WaitSystemEvent, WTS_WAIT_SYSTEM_EVENT_FN);
+ WTSAPI32_LOAD_PROC(VirtualChannelOpen, WTS_VIRTUAL_CHANNEL_OPEN_FN);
+ WTSAPI32_LOAD_PROC(VirtualChannelOpenEx, WTS_VIRTUAL_CHANNEL_OPEN_EX_FN);
+ WTSAPI32_LOAD_PROC(VirtualChannelClose, WTS_VIRTUAL_CHANNEL_CLOSE_FN);
+ WTSAPI32_LOAD_PROC(VirtualChannelRead, WTS_VIRTUAL_CHANNEL_READ_FN);
+ WTSAPI32_LOAD_PROC(VirtualChannelWrite, WTS_VIRTUAL_CHANNEL_WRITE_FN);
+ WTSAPI32_LOAD_PROC(VirtualChannelPurgeInput, WTS_VIRTUAL_CHANNEL_PURGE_INPUT_FN);
+ WTSAPI32_LOAD_PROC(VirtualChannelPurgeOutput, WTS_VIRTUAL_CHANNEL_PURGE_OUTPUT_FN);
+ WTSAPI32_LOAD_PROC(VirtualChannelQuery, WTS_VIRTUAL_CHANNEL_QUERY_FN);
+ WTSAPI32_LOAD_PROC(FreeMemory, WTS_FREE_MEMORY_FN);
+ WTSAPI32_LOAD_PROC(RegisterSessionNotification, WTS_REGISTER_SESSION_NOTIFICATION_FN);
+ WTSAPI32_LOAD_PROC(UnRegisterSessionNotification, WTS_UNREGISTER_SESSION_NOTIFICATION_FN);
+ WTSAPI32_LOAD_PROC(RegisterSessionNotificationEx, WTS_REGISTER_SESSION_NOTIFICATION_EX_FN);
+ WTSAPI32_LOAD_PROC(UnRegisterSessionNotificationEx, WTS_UNREGISTER_SESSION_NOTIFICATION_EX_FN);
+ WTSAPI32_LOAD_PROC(QueryUserToken, WTS_QUERY_USER_TOKEN_FN);
+ WTSAPI32_LOAD_PROC(FreeMemoryExW, WTS_FREE_MEMORY_EX_FN_W);
+ WTSAPI32_LOAD_PROC(FreeMemoryExA, WTS_FREE_MEMORY_EX_FN_A);
+ WTSAPI32_LOAD_PROC(EnumerateProcessesExW, WTS_ENUMERATE_PROCESSES_EX_FN_W);
+ WTSAPI32_LOAD_PROC(EnumerateProcessesExA, WTS_ENUMERATE_PROCESSES_EX_FN_A);
+ WTSAPI32_LOAD_PROC(EnumerateListenersW, WTS_ENUMERATE_LISTENERS_FN_W);
+ WTSAPI32_LOAD_PROC(EnumerateListenersA, WTS_ENUMERATE_LISTENERS_FN_A);
+ WTSAPI32_LOAD_PROC(QueryListenerConfigW, WTS_QUERY_LISTENER_CONFIG_FN_W);
+ WTSAPI32_LOAD_PROC(QueryListenerConfigA, WTS_QUERY_LISTENER_CONFIG_FN_A);
+ WTSAPI32_LOAD_PROC(CreateListenerW, WTS_CREATE_LISTENER_FN_W);
+ WTSAPI32_LOAD_PROC(CreateListenerA, WTS_CREATE_LISTENER_FN_A);
+ WTSAPI32_LOAD_PROC(SetListenerSecurityW, WTS_SET_LISTENER_SECURITY_FN_W);
+ WTSAPI32_LOAD_PROC(SetListenerSecurityA, WTS_SET_LISTENER_SECURITY_FN_A);
+ WTSAPI32_LOAD_PROC(GetListenerSecurityW, WTS_GET_LISTENER_SECURITY_FN_W);
+ WTSAPI32_LOAD_PROC(GetListenerSecurityA, WTS_GET_LISTENER_SECURITY_FN_A);
+ WTSAPI32_LOAD_PROC(EnableChildSessions, WTS_ENABLE_CHILD_SESSIONS_FN);
+ WTSAPI32_LOAD_PROC(IsChildSessionsEnabled, WTS_IS_CHILD_SESSIONS_ENABLED_FN);
+ WTSAPI32_LOAD_PROC(GetChildSessionId, WTS_GET_CHILD_SESSION_ID_FN);
+ WTSAPI32_LOAD_PROC(GetActiveConsoleSessionId, WTS_GET_ACTIVE_CONSOLE_SESSION_ID_FN);
+#endif
+ g_WtsApi = &WtsApi32_WtsApiFunctionTable;
+ return 1;
+}
+
+/* WtsApi Functions */
+
BOOL WINAPI WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers)
{
WTSAPI_STUB_CALL_BOOL(StartRemoteControlSessionW, pTargetServerName, TargetLogonId, HotkeyVk, HotkeyModifiers);
}
BOOL WINAPI WTSSendMessageW(HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength,
- LPWSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait)
+ LPWSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait)
{
WTSAPI_STUB_CALL_BOOL(SendMessageW, hServer, SessionId, pTitle, TitleLength,
- pMessage, MessageLength, Style, Timeout, pResponse, bWait);
+ pMessage, MessageLength, Style, Timeout, pResponse, bWait);
}
BOOL WINAPI WTSSendMessageA(HANDLE hServer, DWORD SessionId, LPSTR pTitle, DWORD TitleLength,
- LPSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait)
+ LPSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait)
{
WTSAPI_STUB_CALL_BOOL(SendMessageA, hServer, SessionId, pTitle, TitleLength,
- pMessage, MessageLength, Style, Timeout, pResponse, bWait);
+ pMessage, MessageLength, Style, Timeout, pResponse, bWait);
}
BOOL WINAPI WTSDisconnectSession(HANDLE hServer, DWORD SessionId, BOOL bWait)
}
BOOL WINAPI WTSCreateListenerW(HANDLE hServer, PVOID pReserved, DWORD Reserved,
- LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer, DWORD flag)
+ LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer, DWORD flag)
{
WTSAPI_STUB_CALL_BOOL(CreateListenerW, hServer, pReserved, Reserved, pListenerName, pBuffer, flag);
}
BOOL WINAPI WTSCreateListenerA(HANDLE hServer, PVOID pReserved, DWORD Reserved,
- LPSTR pListenerName, PWTSLISTENERCONFIGA pBuffer, DWORD flag)
+ LPSTR pListenerName, PWTSLISTENERCONFIGA pBuffer, DWORD flag)
{
WTSAPI_STUB_CALL_BOOL(CreateListenerA, hServer, pReserved, Reserved, pListenerName, pBuffer, flag);
}
BOOL WINAPI WTSSetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved,
- LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
- PSECURITY_DESCRIPTOR pSecurityDescriptor)
+ LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
WTSAPI_STUB_CALL_BOOL(SetListenerSecurityW, hServer, pReserved, Reserved,
- pListenerName, SecurityInformation, pSecurityDescriptor);
+ pListenerName, SecurityInformation, pSecurityDescriptor);
}
BOOL WINAPI WTSSetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved,
- LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
- PSECURITY_DESCRIPTOR pSecurityDescriptor)
+ LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
WTSAPI_STUB_CALL_BOOL(SetListenerSecurityA, hServer, pReserved, Reserved,
- pListenerName, SecurityInformation, pSecurityDescriptor);
+ pListenerName, SecurityInformation, pSecurityDescriptor);
}
BOOL WINAPI WTSGetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved,
- LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
- PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded)
+ LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded)
{
WTSAPI_STUB_CALL_BOOL(GetListenerSecurityW, hServer, pReserved, Reserved, pListenerName,
- SecurityInformation, pSecurityDescriptor, nLength, lpnLengthNeeded);
+ SecurityInformation, pSecurityDescriptor, nLength, lpnLengthNeeded);
}
BOOL WINAPI WTSGetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved,
- LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
- PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded)
+ LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded)
{
WTSAPI_STUB_CALL_BOOL(GetListenerSecurityA, hServer, pReserved, Reserved, pListenerName,
- SecurityInformation, pSecurityDescriptor, nLength, lpnLengthNeeded);
+ SecurityInformation, pSecurityDescriptor, nLength, lpnLengthNeeded);
}
BOOL CDECL WTSEnableChildSessions(BOOL bEnable)
BOOL WTSRegisterWtsApiFunctionTable(PWtsApiFunctionTable table)
{
g_WtsApi = table;
+ g_Initialized = TRUE;
return TRUE;
}
-static BOOL LoadAndInitialize(char *library)
+static BOOL LoadAndInitialize(char* library)
{
INIT_WTSAPI_FN pInitWtsApi;
g_WtsApiModule = LoadLibraryA(library);
{
return FALSE;
}
+
g_WtsApi = pInitWtsApi();
return TRUE;
}
env = (LPSTR) malloc(nSize);
nSize = GetEnvironmentVariableA("WTSAPI_LIBRARY", env, nSize);
+
if (env)
LoadAndInitialize(env);
}
#define FREERDS_LIBRARY_NAME "libfreerds-fdsapi.so"
+
void InitializeWtsApiStubs_FreeRDS()
{
char* prefix;
char* libdir;
wIniFile* ini;
-
+
if (g_WtsApi)
return;
-
+
ini = IniFile_New();
if (IniFile_Parse(ini, "/var/run/freerds.instance") < 0)
{
IniFile_Free(ini);
- fprintf(stderr, "failed to parse freerds.instance\n");
+ WLog_ERR(TAG, "failed to parse freerds.instance");
LoadAndInitialize(FREERDS_LIBRARY_NAME);
return;
}
-
+
prefix = IniFile_GetKeyValueString(ini, "FreeRDS", "prefix");
libdir = IniFile_GetKeyValueString(ini, "FreeRDS", "libdir");
-
- fprintf(stderr, "FreeRDS (prefix / libdir): %s / %s\n", prefix, libdir);
-
+ WLog_INFO(TAG, "FreeRDS (prefix / libdir): %s / %s", prefix, libdir);
+
if (prefix && libdir)
{
char* prefix_libdir;
char* wtsapi_library;
-
prefix_libdir = GetCombinedPath(prefix, libdir);
wtsapi_library = GetCombinedPath(prefix_libdir, FREERDS_LIBRARY_NAME);
-
+
if (wtsapi_library)
{
LoadAndInitialize(wtsapi_library);
}
-
+
free(prefix_libdir);
free(wtsapi_library);
}
-
+
IniFile_Free(ini);
}
return;
g_Initialized = TRUE;
-
InitializeWtsApiStubs_Env();
-
+#ifdef _WIN32
+ WtsApi32_InitializeWtsApi();
+#endif
+
if (!g_WtsApi)
InitializeWtsApiStubs_FreeRDS();