mirror of https://github.com/FreeRDP/FreeRDP
Scanbuild warning, argument checks and leak fixes.
* Added Stream_GetRemainingCapacity to check remaining stream size before writes. * Fixed shadow server memory leak. * Fixed lots of scanbuild warnings * Added missing argument checks in many functions * Added missing static function declarations
This commit is contained in:
parent
5bb7a05026
commit
b2c29158be
|
@ -138,7 +138,6 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src,
|
|||
frames = alsa->dsp_context->resampled_frames;
|
||||
DEBUG_DVC("resampled %d frames at %"PRIu32" to %d frames at %"PRIu32"",
|
||||
size / rbytes_per_frame, alsa->actual_rate, frames, alsa->target_rate);
|
||||
size = frames * tbytes_per_frame;
|
||||
src = alsa->dsp_context->resampled_buffer;
|
||||
}
|
||||
|
||||
|
@ -225,14 +224,11 @@ static void* audin_alsa_thread_func(void* arg)
|
|||
long error;
|
||||
BYTE* buffer;
|
||||
int rbytes_per_frame;
|
||||
int tbytes_per_frame;
|
||||
snd_pcm_t* capture_handle = NULL;
|
||||
AudinALSADevice* alsa = (AudinALSADevice*) arg;
|
||||
DWORD status;
|
||||
DEBUG_DVC("in");
|
||||
|
||||
rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel;
|
||||
tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel;
|
||||
buffer = (BYTE*) calloc(1, rbytes_per_frame * alsa->frames_per_packet);
|
||||
|
||||
if (!buffer)
|
||||
|
@ -502,6 +498,10 @@ static UINT audin_alsa_parse_addin_args(AudinALSADevice* device,
|
|||
COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
|
||||
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
|
||||
audin_alsa_args, flags, alsa, NULL, NULL);
|
||||
|
||||
if (status < 0)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
arg = audin_alsa_args;
|
||||
|
||||
do
|
||||
|
|
|
@ -68,19 +68,19 @@ static void audin_pulse_context_state_callback(pa_context* context, void* userda
|
|||
{
|
||||
pa_context_state_t state;
|
||||
AudinPulseDevice* pulse = (AudinPulseDevice*) userdata;
|
||||
|
||||
state = pa_context_get_state(context);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case PA_CONTEXT_READY:
|
||||
DEBUG_DVC("PA_CONTEXT_READY");
|
||||
pa_threaded_mainloop_signal (pulse->mainloop, 0);
|
||||
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
||||
break;
|
||||
|
||||
case PA_CONTEXT_FAILED:
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
DEBUG_DVC("state %d", state);
|
||||
pa_threaded_mainloop_signal (pulse->mainloop, 0);
|
||||
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -105,31 +105,38 @@ static UINT audin_pulse_connect(IAudinDevice* device)
|
|||
if (pa_context_connect(pulse->context, NULL, 0, NULL))
|
||||
{
|
||||
WLog_ERR(TAG, "pa_context_connect failed (%d)",
|
||||
pa_context_errno(pulse->context));
|
||||
pa_context_errno(pulse->context));
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||
|
||||
if (pa_threaded_mainloop_start(pulse->mainloop) < 0)
|
||||
{
|
||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||
WLog_ERR(TAG, "pa_threaded_mainloop_start failed (%d)",
|
||||
pa_context_errno(pulse->context));
|
||||
pa_context_errno(pulse->context));
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
state = pa_context_get_state(pulse->context);
|
||||
|
||||
if (state == PA_CONTEXT_READY)
|
||||
break;
|
||||
|
||||
if (!PA_CONTEXT_IS_GOOD(state))
|
||||
{
|
||||
WLog_ERR(TAG, "bad context state (%d)",
|
||||
pa_context_errno(pulse->context));
|
||||
pa_context_errno(pulse->context));
|
||||
pa_context_disconnect(pulse->context);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
pa_threaded_mainloop_wait(pulse->mainloop);
|
||||
}
|
||||
|
||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||
DEBUG_DVC("connected");
|
||||
return CHANNEL_RC_OK;
|
||||
|
@ -146,24 +153,27 @@ static UINT audin_pulse_free(IAudinDevice* device)
|
|||
|
||||
if (!pulse)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (pulse->mainloop)
|
||||
{
|
||||
pa_threaded_mainloop_stop(pulse->mainloop);
|
||||
}
|
||||
|
||||
if (pulse->context)
|
||||
{
|
||||
pa_context_disconnect(pulse->context);
|
||||
pa_context_unref(pulse->context);
|
||||
pulse->context = NULL;
|
||||
}
|
||||
|
||||
if (pulse->mainloop)
|
||||
{
|
||||
pa_threaded_mainloop_free(pulse->mainloop);
|
||||
pulse->mainloop = NULL;
|
||||
}
|
||||
|
||||
freerdp_dsp_context_free(pulse->dsp_context);
|
||||
free(pulse);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
|
@ -178,34 +188,38 @@ static BOOL audin_pulse_format_supported(IAudinDevice* device, audinFormat* form
|
|||
{
|
||||
case 1: /* PCM */
|
||||
if (format->cbSize == 0 &&
|
||||
(format->nSamplesPerSec <= PA_RATE_MAX) &&
|
||||
(format->wBitsPerSample == 8 || format->wBitsPerSample == 16) &&
|
||||
(format->nChannels >= 1 && format->nChannels <= PA_CHANNELS_MAX))
|
||||
(format->nSamplesPerSec <= PA_RATE_MAX) &&
|
||||
(format->wBitsPerSample == 8 || format->wBitsPerSample == 16) &&
|
||||
(format->nChannels >= 1 && format->nChannels <= PA_CHANNELS_MAX))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 6: /* A-LAW */
|
||||
case 7: /* U-LAW */
|
||||
if (format->cbSize == 0 &&
|
||||
(format->nSamplesPerSec <= PA_RATE_MAX) &&
|
||||
(format->wBitsPerSample == 8) &&
|
||||
(format->nChannels >= 1 && format->nChannels <= PA_CHANNELS_MAX))
|
||||
(format->nSamplesPerSec <= PA_RATE_MAX) &&
|
||||
(format->wBitsPerSample == 8) &&
|
||||
(format->nChannels >= 1 && format->nChannels <= PA_CHANNELS_MAX))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x11: /* IMA ADPCM */
|
||||
if ((format->nSamplesPerSec <= PA_RATE_MAX) &&
|
||||
(format->wBitsPerSample == 4) &&
|
||||
(format->nChannels == 1 || format->nChannels == 2))
|
||||
(format->wBitsPerSample == 4) &&
|
||||
(format->nChannels == 1 || format->nChannels == 2))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -214,7 +228,8 @@ static BOOL audin_pulse_format_supported(IAudinDevice* device, audinFormat* form
|
|||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT audin_pulse_set_format(IAudinDevice* device, audinFormat* format, UINT32 FramesPerPacket)
|
||||
static UINT audin_pulse_set_format(IAudinDevice* device, audinFormat* format,
|
||||
UINT32 FramesPerPacket)
|
||||
{
|
||||
int bs;
|
||||
pa_sample_spec sample_spec = { 0 };
|
||||
|
@ -230,6 +245,7 @@ static UINT audin_pulse_set_format(IAudinDevice* device, audinFormat* format, UI
|
|||
|
||||
sample_spec.rate = format->nSamplesPerSec;
|
||||
sample_spec.channels = format->nChannels;
|
||||
|
||||
switch (format->wFormatTag)
|
||||
{
|
||||
case 1: /* PCM */
|
||||
|
@ -238,10 +254,12 @@ static UINT audin_pulse_set_format(IAudinDevice* device, audinFormat* format, UI
|
|||
case 8:
|
||||
sample_spec.format = PA_SAMPLE_U8;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
sample_spec.format = PA_SAMPLE_S16LE;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 6: /* A-LAW */
|
||||
|
@ -256,9 +274,9 @@ static UINT audin_pulse_set_format(IAudinDevice* device, audinFormat* format, UI
|
|||
sample_spec.format = PA_SAMPLE_S16LE;
|
||||
bs = (format->nBlockAlign - 4 * format->nChannels) * 4;
|
||||
pulse->frames_per_packet = (pulse->frames_per_packet * format->nChannels * 2 /
|
||||
bs + 1) * bs / (format->nChannels * 2);
|
||||
bs + 1) * bs / (format->nChannels * 2);
|
||||
DEBUG_DVC("aligned FramesPerPacket=%"PRIu32"",
|
||||
pulse->frames_per_packet);
|
||||
pulse->frames_per_packet);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -272,8 +290,8 @@ static void audin_pulse_stream_state_callback(pa_stream* stream, void* userdata)
|
|||
{
|
||||
pa_stream_state_t state;
|
||||
AudinPulseDevice* pulse = (AudinPulseDevice*) userdata;
|
||||
|
||||
state = pa_stream_get_state(stream);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case PA_STREAM_READY:
|
||||
|
@ -317,29 +335,32 @@ static void audin_pulse_stream_request_callback(pa_stream* stream, size_t length
|
|||
|
||||
pa_stream_peek(stream, &data, &length);
|
||||
frames = length / pulse->bytes_per_frame;
|
||||
|
||||
DEBUG_DVC("length %"PRIdz" frames %d", length, frames);
|
||||
|
||||
src = (const BYTE*) data;
|
||||
|
||||
while (frames > 0)
|
||||
{
|
||||
cframes = pulse->frames_per_packet - pulse->buffer_frames;
|
||||
|
||||
if (cframes > frames)
|
||||
cframes = frames;
|
||||
|
||||
memcpy(pulse->buffer + pulse->buffer_frames * pulse->bytes_per_frame,
|
||||
src, cframes * pulse->bytes_per_frame);
|
||||
src, cframes * pulse->bytes_per_frame);
|
||||
pulse->buffer_frames += cframes;
|
||||
|
||||
if (pulse->buffer_frames >= pulse->frames_per_packet)
|
||||
{
|
||||
if (pulse->format == 0x11)
|
||||
{
|
||||
if (!pulse->dsp_context->encode_ima_adpcm(pulse->dsp_context,
|
||||
pulse->buffer, pulse->buffer_frames * pulse->bytes_per_frame,
|
||||
pulse->sample_spec.channels, pulse->block_size))
|
||||
pulse->buffer, pulse->buffer_frames * pulse->bytes_per_frame,
|
||||
pulse->sample_spec.channels, pulse->block_size))
|
||||
{
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
encoded_data = pulse->dsp_context->adpcm_buffer;
|
||||
encoded_size = pulse->dsp_context->adpcm_size;
|
||||
}
|
||||
|
@ -350,13 +371,15 @@ static void audin_pulse_stream_request_callback(pa_stream* stream, size_t length
|
|||
}
|
||||
|
||||
DEBUG_DVC("encoded %d [%d] to %d [%X]",
|
||||
pulse->buffer_frames, pulse->bytes_per_frame, encoded_size,
|
||||
pulse->format);
|
||||
pulse->buffer_frames, pulse->bytes_per_frame, encoded_size,
|
||||
pulse->format);
|
||||
error = pulse->receive(encoded_data, encoded_size, pulse->user_data);
|
||||
pulse->buffer_frames = 0;
|
||||
|
||||
if (!error)
|
||||
break;
|
||||
}
|
||||
|
||||
src += cframes * pulse->bytes_per_frame;
|
||||
frames -= cframes;
|
||||
}
|
||||
|
@ -385,15 +408,16 @@ static UINT audin_pulse_close(IAudinDevice* device)
|
|||
pa_stream_unref(pulse->stream);
|
||||
pulse->stream = NULL;
|
||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||
|
||||
pulse->receive = NULL;
|
||||
pulse->user_data = NULL;
|
||||
|
||||
if (pulse->buffer)
|
||||
{
|
||||
free(pulse->buffer);
|
||||
pulse->buffer = NULL;
|
||||
pulse->buffer_frames = 0;
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
|
@ -410,66 +434,76 @@ static UINT audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u
|
|||
|
||||
if (!pulse->context)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (!pulse->sample_spec.rate || pulse->stream)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
pulse->buffer = NULL;
|
||||
pulse->receive = receive;
|
||||
pulse->user_data = user_data;
|
||||
|
||||
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||
pulse->stream = pa_stream_new(pulse->context, "freerdp_audin",
|
||||
&pulse->sample_spec, NULL);
|
||||
&pulse->sample_spec, NULL);
|
||||
|
||||
if (!pulse->stream)
|
||||
{
|
||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||
DEBUG_DVC("pa_stream_new failed (%d)",
|
||||
pa_context_errno(pulse->context));
|
||||
pa_context_errno(pulse->context));
|
||||
return pa_context_errno(pulse->context);
|
||||
}
|
||||
|
||||
pulse->bytes_per_frame = pa_frame_size(&pulse->sample_spec);
|
||||
pa_stream_set_state_callback(pulse->stream,
|
||||
audin_pulse_stream_state_callback, pulse);
|
||||
audin_pulse_stream_state_callback, pulse);
|
||||
pa_stream_set_read_callback(pulse->stream,
|
||||
audin_pulse_stream_request_callback, pulse);
|
||||
buffer_attr.maxlength = (UINT32) -1;
|
||||
buffer_attr.tlength = (UINT32) -1;
|
||||
buffer_attr.prebuf = (UINT32) -1;
|
||||
buffer_attr.minreq = (UINT32) -1;
|
||||
audin_pulse_stream_request_callback, pulse);
|
||||
buffer_attr.maxlength = (UINT32) - 1;
|
||||
buffer_attr.tlength = (UINT32) - 1;
|
||||
buffer_attr.prebuf = (UINT32) - 1;
|
||||
buffer_attr.minreq = (UINT32) - 1;
|
||||
/* 500ms latency */
|
||||
buffer_attr.fragsize = pa_usec_to_bytes(500000, &pulse->sample_spec);
|
||||
|
||||
if (pa_stream_connect_record(pulse->stream,
|
||||
pulse->device_name,
|
||||
&buffer_attr, PA_STREAM_ADJUST_LATENCY) < 0)
|
||||
pulse->device_name,
|
||||
&buffer_attr, PA_STREAM_ADJUST_LATENCY) < 0)
|
||||
{
|
||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||
WLog_ERR(TAG, "pa_stream_connect_playback failed (%d)",
|
||||
pa_context_errno(pulse->context));
|
||||
pa_context_errno(pulse->context));
|
||||
return pa_context_errno(pulse->context);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
state = pa_stream_get_state(pulse->stream);
|
||||
|
||||
if (state == PA_STREAM_READY)
|
||||
break;
|
||||
|
||||
if (!PA_STREAM_IS_GOOD(state))
|
||||
{
|
||||
audin_pulse_close(device);
|
||||
WLog_ERR(TAG, "bad stream state (%d)",
|
||||
pa_context_errno(pulse->context));
|
||||
pa_context_errno(pulse->context));
|
||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||
return pa_context_errno(pulse->context);
|
||||
}
|
||||
|
||||
pa_threaded_mainloop_wait(pulse->mainloop);
|
||||
}
|
||||
|
||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||
freerdp_dsp_context_reset_adpcm(pulse->dsp_context);
|
||||
pulse->buffer = calloc(1, pulse->bytes_per_frame * pulse->frames_per_packet);
|
||||
if (!pulse->buffer) {
|
||||
|
||||
if (!pulse->buffer)
|
||||
{
|
||||
WLog_ERR(TAG, "calloc failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
pulse->buffer_frames = 0;
|
||||
DEBUG_DVC("connected");
|
||||
return CHANNEL_RC_OK;
|
||||
|
@ -492,10 +526,12 @@ static UINT audin_pulse_parse_addin_args(AudinPulseDevice* device, ADDIN_ARGV* a
|
|||
DWORD flags;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
AudinPulseDevice* pulse = (AudinPulseDevice*) device;
|
||||
|
||||
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
|
||||
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_pulse_args, flags,
|
||||
pulse, NULL, NULL);
|
||||
|
||||
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_pulse_args, flags, pulse, NULL, NULL);
|
||||
if (status < 0)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
arg = audin_pulse_args;
|
||||
|
||||
|
@ -505,17 +541,16 @@ static UINT audin_pulse_parse_addin_args(AudinPulseDevice* device, ADDIN_ARGV* a
|
|||
continue;
|
||||
|
||||
CommandLineSwitchStart(arg)
|
||||
|
||||
CommandLineSwitchCase(arg, "dev")
|
||||
{
|
||||
pulse->device_name = _strdup(arg->Value);
|
||||
|
||||
if (!pulse->device_name)
|
||||
{
|
||||
WLog_ERR(TAG, "_strdup failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
CommandLineSwitchEnd(arg)
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
@ -539,8 +574,8 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
|
|||
ADDIN_ARGV* args;
|
||||
AudinPulseDevice* pulse;
|
||||
UINT error;
|
||||
|
||||
pulse = (AudinPulseDevice*) calloc(1, sizeof(AudinPulseDevice));
|
||||
|
||||
if (!pulse)
|
||||
{
|
||||
WLog_ERR(TAG, "calloc failed!");
|
||||
|
@ -553,7 +588,6 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
|
|||
pulse->iface.Close = audin_pulse_close;
|
||||
pulse->iface.Free = audin_pulse_free;
|
||||
pulse->rdpcontext = pEntryPoints->rdpcontext;
|
||||
|
||||
args = pEntryPoints->args;
|
||||
|
||||
if ((error = audin_pulse_parse_addin_args(pulse, args)))
|
||||
|
@ -563,6 +597,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
|
|||
}
|
||||
|
||||
pulse->dsp_context = freerdp_dsp_context_new();
|
||||
|
||||
if (!pulse->dsp_context)
|
||||
{
|
||||
WLog_ERR(TAG, "freerdp_dsp_context_new failed!");
|
||||
|
|
|
@ -43,11 +43,11 @@
|
|||
|
||||
extern const STATIC_ENTRY_TABLE CLIENT_STATIC_ENTRY_TABLES[];
|
||||
|
||||
void* freerdp_channels_find_static_entry_in_table(const STATIC_ENTRY_TABLE* table, const char* identifier)
|
||||
void* freerdp_channels_find_static_entry_in_table(const STATIC_ENTRY_TABLE* table,
|
||||
const char* identifier)
|
||||
{
|
||||
int index = 0;
|
||||
STATIC_ENTRY* pEntry;
|
||||
|
||||
pEntry = (STATIC_ENTRY*) &table->table[index++];
|
||||
|
||||
while (pEntry->entry != NULL)
|
||||
|
@ -67,7 +67,6 @@ void* freerdp_channels_client_find_static_entry(const char* name, const char* id
|
|||
{
|
||||
int index = 0;
|
||||
STATIC_ENTRY_TABLE* pEntry;
|
||||
|
||||
pEntry = (STATIC_ENTRY_TABLE*) &CLIENT_STATIC_ENTRY_TABLES[index++];
|
||||
|
||||
while (pEntry->table != NULL)
|
||||
|
@ -85,16 +84,17 @@ void* freerdp_channels_client_find_static_entry(const char* name, const char* id
|
|||
|
||||
extern const STATIC_ADDIN_TABLE CLIENT_STATIC_ADDIN_TABLE[];
|
||||
|
||||
FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
|
||||
FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR pszName, LPSTR pszSubsystem,
|
||||
LPSTR pszType, DWORD dwFlags)
|
||||
{
|
||||
int i, j;
|
||||
DWORD nAddins;
|
||||
FREERDP_ADDIN* pAddin = NULL;
|
||||
FREERDP_ADDIN** ppAddins = NULL;
|
||||
STATIC_SUBSYSTEM_ENTRY* subsystems;
|
||||
|
||||
nAddins = 0;
|
||||
ppAddins = (FREERDP_ADDIN**) calloc(1, sizeof(FREERDP_ADDIN*) * 128);
|
||||
|
||||
if (!ppAddins)
|
||||
{
|
||||
WLog_ERR(TAG, "calloc failed!");
|
||||
|
@ -106,6 +106,7 @@ FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR pszName, LPSTR
|
|||
for (i = 0; CLIENT_STATIC_ADDIN_TABLE[i].name != NULL; i++)
|
||||
{
|
||||
pAddin = (FREERDP_ADDIN*) calloc(1, sizeof(FREERDP_ADDIN));
|
||||
|
||||
if (!pAddin)
|
||||
{
|
||||
WLog_ERR(TAG, "calloc failed!");
|
||||
|
@ -113,18 +114,16 @@ FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR pszName, LPSTR
|
|||
}
|
||||
|
||||
strcpy(pAddin->cName, CLIENT_STATIC_ADDIN_TABLE[i].name);
|
||||
|
||||
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_STATIC;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
|
||||
|
||||
ppAddins[nAddins++] = pAddin;
|
||||
|
||||
subsystems = (STATIC_SUBSYSTEM_ENTRY*) CLIENT_STATIC_ADDIN_TABLE[i].table;
|
||||
|
||||
for (j = 0; subsystems[j].name != NULL; j++)
|
||||
{
|
||||
pAddin = (FREERDP_ADDIN*) calloc(1, sizeof(FREERDP_ADDIN));
|
||||
|
||||
if (!pAddin)
|
||||
{
|
||||
WLog_ERR(TAG, "calloc failed!");
|
||||
|
@ -133,12 +132,10 @@ FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR pszName, LPSTR
|
|||
|
||||
strcpy(pAddin->cName, CLIENT_STATIC_ADDIN_TABLE[i].name);
|
||||
strcpy(pAddin->cSubsystem, subsystems[j].name);
|
||||
|
||||
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_STATIC;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM;
|
||||
|
||||
ppAddins[nAddins++] = pAddin;
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +146,8 @@ error_out:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
|
||||
FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSubsystem,
|
||||
LPSTR pszType, DWORD dwFlags)
|
||||
{
|
||||
int index;
|
||||
int nDashes;
|
||||
|
@ -166,14 +164,12 @@ FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSub
|
|||
size_t cchInstallPrefix;
|
||||
FREERDP_ADDIN** ppAddins;
|
||||
WIN32_FIND_DATAA FindData;
|
||||
|
||||
cchAddinPath = strlen(pszAddinPath);
|
||||
cchInstallPrefix = strlen(pszInstallPrefix);
|
||||
|
||||
pszExtension = PathGetSharedLibraryExtensionA(0);
|
||||
|
||||
cchPattern = 128 + strlen(pszExtension) + 2;
|
||||
pszPattern = (LPSTR) malloc(cchPattern + 1);
|
||||
|
||||
if (!pszPattern)
|
||||
{
|
||||
WLog_ERR(TAG, "malloc failed!");
|
||||
|
@ -183,28 +179,28 @@ FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSub
|
|||
if (pszName && pszSubsystem && pszType)
|
||||
{
|
||||
sprintf_s(pszPattern, cchPattern, FREERDP_SHARED_LIBRARY_PREFIX"%s-client-%s-%s.%s",
|
||||
pszName, pszSubsystem, pszType, pszExtension);
|
||||
pszName, pszSubsystem, pszType, pszExtension);
|
||||
}
|
||||
else if (pszName && pszType)
|
||||
{
|
||||
sprintf_s(pszPattern, cchPattern, FREERDP_SHARED_LIBRARY_PREFIX"%s-client-?-%s.%s",
|
||||
pszName, pszType, pszExtension);
|
||||
pszName, pszType, pszExtension);
|
||||
}
|
||||
else if (pszName)
|
||||
{
|
||||
sprintf_s(pszPattern, cchPattern, FREERDP_SHARED_LIBRARY_PREFIX"%s-client*.%s",
|
||||
pszName, pszExtension);
|
||||
pszName, pszExtension);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(pszPattern, cchPattern, FREERDP_SHARED_LIBRARY_PREFIX"?-client*.%s",
|
||||
pszExtension);
|
||||
pszExtension);
|
||||
}
|
||||
|
||||
cchPattern = strlen(pszPattern);
|
||||
|
||||
cchSearchPath = cchInstallPrefix + cchAddinPath + cchPattern + 3;
|
||||
pszSearchPath = (LPSTR) malloc(cchSearchPath + 1);
|
||||
|
||||
if (!pszSearchPath)
|
||||
{
|
||||
WLog_ERR(TAG, "malloc failed!");
|
||||
|
@ -214,20 +210,14 @@ FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSub
|
|||
|
||||
CopyMemory(pszSearchPath, pszInstallPrefix, cchInstallPrefix);
|
||||
pszSearchPath[cchInstallPrefix] = '\0';
|
||||
|
||||
NativePathCchAppendA(pszSearchPath, cchSearchPath + 1, pszAddinPath);
|
||||
NativePathCchAppendA(pszSearchPath, cchSearchPath + 1, pszPattern);
|
||||
|
||||
free(pszPattern);
|
||||
|
||||
cchSearchPath = strlen(pszSearchPath);
|
||||
|
||||
hFind = FindFirstFileA(pszSearchPath, &FindData);
|
||||
|
||||
free(pszSearchPath);
|
||||
|
||||
nAddins = 0;
|
||||
ppAddins = (FREERDP_ADDIN**) calloc(1, sizeof(FREERDP_ADDIN*) * 128);
|
||||
|
||||
if (!ppAddins)
|
||||
{
|
||||
WLog_ERR(TAG, "calloc failed!");
|
||||
|
@ -241,9 +231,9 @@ FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSub
|
|||
{
|
||||
char* p[5];
|
||||
FREERDP_ADDIN* pAddin;
|
||||
|
||||
nDashes = 0;
|
||||
pAddin = (FREERDP_ADDIN*) calloc(1, sizeof(FREERDP_ADDIN));
|
||||
|
||||
if (!pAddin)
|
||||
{
|
||||
WLog_ERR(TAG, "calloc failed!");
|
||||
|
@ -256,57 +246,45 @@ FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSub
|
|||
if (nDashes == 1)
|
||||
{
|
||||
/* <name>-client.<extension> */
|
||||
|
||||
p[0] = FindData.cFileName;
|
||||
p[1] = strchr(p[0], '-') + 1;
|
||||
|
||||
strncpy(pAddin->cName, p[0], (p[1] - p[0]) - 1);
|
||||
|
||||
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
|
||||
|
||||
ppAddins[nAddins++] = pAddin;
|
||||
}
|
||||
else if (nDashes == 2)
|
||||
{
|
||||
/* <name>-client-<subsystem>.<extension> */
|
||||
|
||||
p[0] = FindData.cFileName;
|
||||
p[1] = strchr(p[0], '-') + 1;
|
||||
p[2] = strchr(p[1], '-') + 1;
|
||||
p[3] = strchr(p[2], '.') + 1;
|
||||
|
||||
strncpy(pAddin->cName, p[0], (p[1] - p[0]) - 1);
|
||||
strncpy(pAddin->cSubsystem, p[2], (p[3] - p[2]) - 1);
|
||||
|
||||
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM;
|
||||
|
||||
ppAddins[nAddins++] = pAddin;
|
||||
}
|
||||
else if (nDashes == 3)
|
||||
{
|
||||
/* <name>-client-<subsystem>-<type>.<extension> */
|
||||
|
||||
p[0] = FindData.cFileName;
|
||||
p[1] = strchr(p[0], '-') + 1;
|
||||
p[2] = strchr(p[1], '-') + 1;
|
||||
p[3] = strchr(p[2], '-') + 1;
|
||||
p[4] = strchr(p[3], '.') + 1;
|
||||
|
||||
strncpy(pAddin->cName, p[0], (p[1] - p[0]) - 1);
|
||||
strncpy(pAddin->cSubsystem, p[2], (p[3] - p[2]) - 1);
|
||||
strncpy(pAddin->cType, p[3], (p[4] - p[3]) - 1);
|
||||
|
||||
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM;
|
||||
pAddin->dwFlags |= FREERDP_ADDIN_TYPE;
|
||||
|
||||
ppAddins[nAddins++] = pAddin;
|
||||
}
|
||||
else
|
||||
|
@ -317,16 +295,15 @@ FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSub
|
|||
while (FindNextFileA(hFind, &FindData));
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
ppAddins[nAddins] = NULL;
|
||||
|
||||
return ppAddins;
|
||||
error_out:
|
||||
freerdp_channels_addin_list_free(ppAddins);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FREERDP_ADDIN** freerdp_channels_list_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
|
||||
FREERDP_ADDIN** freerdp_channels_list_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
if (dwFlags & FREERDP_ADDIN_STATIC)
|
||||
return freerdp_channels_list_client_static_addins(pszName, pszSubsystem, pszType, dwFlags);
|
||||
|
@ -367,7 +344,8 @@ BOOL freerdp_channels_is_virtual_channel_entry_ex(LPCSTR pszName)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
PVIRTUALCHANNELENTRY freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
|
||||
PVIRTUALCHANNELENTRY freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsystem,
|
||||
LPSTR pszType, DWORD dwFlags)
|
||||
{
|
||||
int i, j;
|
||||
STATIC_SUBSYSTEM_ENTRY* subsystems;
|
||||
|
@ -403,7 +381,7 @@ PVIRTUALCHANNELENTRY freerdp_channels_load_static_addin_entry(LPCSTR pszName, LP
|
|||
if (!freerdp_channels_is_virtual_channel_entry_ex(pszName))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return CLIENT_STATIC_ADDIN_TABLE[i].entry;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -798,7 +798,7 @@ static UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context,
|
|||
WLog_Print(cliprdr->log, WLOG_DEBUG,
|
||||
"ClientLockClipboardData: clipDataId: 0x%08"PRIX32"",
|
||||
lockClipboardData->clipDataId);
|
||||
return cliprdr_packet_send(cliprdr, s);;
|
||||
return cliprdr_packet_send(cliprdr, s);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Inuvika Inc.
|
||||
* Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -75,10 +77,8 @@
|
|||
|
||||
static void drive_file_fix_path(char* path)
|
||||
{
|
||||
int i;
|
||||
int length;
|
||||
|
||||
length = (int) strlen(path);
|
||||
size_t i;
|
||||
size_t length = strlen(path);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
|
@ -87,11 +87,15 @@ static void drive_file_fix_path(char* path)
|
|||
}
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
if ((length == 3) && (path[1] == ':') && (path[2] == '/'))
|
||||
return;
|
||||
|
||||
#else
|
||||
|
||||
if ((length == 1) && (path[0] == '/'))
|
||||
return;
|
||||
|
||||
#endif
|
||||
|
||||
if ((length > 0) && (path[length - 1] == '/'))
|
||||
|
@ -102,16 +106,20 @@ static char* drive_file_combine_fullpath(const char* base_path, const char* path
|
|||
{
|
||||
char* fullpath;
|
||||
|
||||
if (!base_path || !path)
|
||||
return NULL;
|
||||
|
||||
fullpath = (char*) malloc(strlen(base_path) + strlen(path) + 1);
|
||||
|
||||
if (!fullpath)
|
||||
{
|
||||
WLog_ERR(TAG, "malloc failed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy(fullpath, base_path);
|
||||
strcat(fullpath, path);
|
||||
drive_file_fix_path(fullpath);
|
||||
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
|
@ -123,6 +131,9 @@ static BOOL drive_file_remove_dir(const char* path)
|
|||
struct dirent* pdirent;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
dir = opendir(path);
|
||||
|
||||
if (dir == NULL)
|
||||
|
@ -139,11 +150,13 @@ static BOOL drive_file_remove_dir(const char* path)
|
|||
}
|
||||
|
||||
p = (char*) malloc(strlen(path) + strlen(pdirent->d_name) + 2);
|
||||
|
||||
if (!p)
|
||||
{
|
||||
WLog_ERR(TAG, "malloc failed!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sprintf(p, "%s/%s", path, pdirent->d_name);
|
||||
|
||||
if (STAT(p, &st) != 0)
|
||||
|
@ -162,7 +175,7 @@ static BOOL drive_file_remove_dir(const char* path)
|
|||
{
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
|
||||
free(p);
|
||||
|
||||
if (!ret)
|
||||
|
@ -196,7 +209,8 @@ static void drive_file_set_fullpath(DRIVE_FILE* file, char* fullpath)
|
|||
file->filename += 1;
|
||||
}
|
||||
|
||||
static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions)
|
||||
static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 CreateDisposition,
|
||||
UINT32 CreateOptions)
|
||||
{
|
||||
struct STAT st;
|
||||
BOOL exists;
|
||||
|
@ -211,20 +225,25 @@ static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 Creat
|
|||
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;
|
||||
|
||||
#endif
|
||||
exists = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
file->is_dir = ((CreateOptions & FILE_DIRECTORY_FILE) ? TRUE : FALSE);
|
||||
|
||||
if (file->is_dir)
|
||||
{
|
||||
/* Should only create the directory if the disposition allows for it */
|
||||
|
@ -237,6 +256,7 @@ static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 Creat
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
exists = FALSE;
|
||||
}
|
||||
|
||||
|
@ -257,20 +277,26 @@ static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 Creat
|
|||
case FILE_SUPERSEDE:
|
||||
oflag = O_TRUNC | O_CREAT;
|
||||
break;
|
||||
|
||||
case FILE_OPEN:
|
||||
break;
|
||||
|
||||
case FILE_CREATE:
|
||||
oflag = O_CREAT | O_EXCL;
|
||||
break;
|
||||
|
||||
case FILE_OPEN_IF:
|
||||
oflag = O_CREAT;
|
||||
break;
|
||||
|
||||
case FILE_OVERWRITE:
|
||||
oflag = O_TRUNC;
|
||||
break;
|
||||
|
||||
case FILE_OVERWRITE_IF:
|
||||
oflag = O_TRUNC | O_CREAT;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -281,9 +307,9 @@ static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 Creat
|
|||
}
|
||||
|
||||
if ((DesiredAccess & GENERIC_ALL)
|
||||
|| (DesiredAccess & GENERIC_WRITE)
|
||||
|| (DesiredAccess & FILE_WRITE_DATA)
|
||||
|| (DesiredAccess & FILE_APPEND_DATA))
|
||||
|| (DesiredAccess & GENERIC_WRITE)
|
||||
|| (DesiredAccess & FILE_WRITE_DATA)
|
||||
|| (DesiredAccess & FILE_APPEND_DATA))
|
||||
{
|
||||
oflag |= O_RDWR;
|
||||
}
|
||||
|
@ -291,11 +317,14 @@ static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 Creat
|
|||
{
|
||||
oflag |= O_RDONLY;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
if (largeFile)
|
||||
{
|
||||
oflag |= O_LARGEFILE;
|
||||
}
|
||||
|
||||
#else
|
||||
oflag |= O_BINARY;
|
||||
#endif
|
||||
|
@ -312,11 +341,11 @@ static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 Creat
|
|||
}
|
||||
|
||||
DRIVE_FILE* drive_file_new(const char* base_path, const char* path, UINT32 id,
|
||||
UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions)
|
||||
UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions)
|
||||
{
|
||||
DRIVE_FILE* file;
|
||||
|
||||
file = (DRIVE_FILE*) calloc(1, sizeof(DRIVE_FILE));
|
||||
|
||||
if (!file)
|
||||
{
|
||||
WLog_ERR(TAG, "calloc failed!");
|
||||
|
@ -335,6 +364,7 @@ DRIVE_FILE* drive_file_new(const char* base_path, const char* path, UINT32 id,
|
|||
}
|
||||
|
||||
#if defined(__linux__) && defined(O_PATH)
|
||||
|
||||
if (file->fd < 0 && file->err == EACCES)
|
||||
{
|
||||
/**
|
||||
|
@ -344,20 +374,23 @@ DRIVE_FILE* drive_file_new(const char* base_path, const char* path, UINT32 id,
|
|||
* 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
|
||||
|
||||
#endif
|
||||
return file;
|
||||
}
|
||||
|
||||
void drive_file_free(DRIVE_FILE* file)
|
||||
{
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
if (file->fd != -1)
|
||||
close(file->fd);
|
||||
|
||||
|
@ -379,10 +412,13 @@ void drive_file_free(DRIVE_FILE* file)
|
|||
|
||||
BOOL drive_file_seek(DRIVE_FILE* file, UINT64 Offset)
|
||||
{
|
||||
if (!file)
|
||||
return FALSE;
|
||||
|
||||
if (file->is_dir || file->fd == -1)
|
||||
return FALSE;
|
||||
|
||||
if (LSEEK(file->fd, Offset, SEEK_SET) == (off_t)-1)
|
||||
if (LSEEK(file->fd, Offset, SEEK_SET) == (off_t) - 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -392,6 +428,9 @@ BOOL drive_file_read(DRIVE_FILE* file, BYTE* buffer, UINT32* Length)
|
|||
{
|
||||
ssize_t r;
|
||||
|
||||
if (!file || !buffer || !Length)
|
||||
return FALSE;
|
||||
|
||||
if (file->is_dir || file->fd == -1)
|
||||
return FALSE;
|
||||
|
||||
|
@ -401,7 +440,6 @@ BOOL drive_file_read(DRIVE_FILE* file, BYTE* buffer, UINT32* Length)
|
|||
return FALSE;
|
||||
|
||||
*Length = (UINT32) r;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -409,6 +447,9 @@ BOOL drive_file_write(DRIVE_FILE* file, BYTE* buffer, UINT32 Length)
|
|||
{
|
||||
ssize_t r;
|
||||
|
||||
if (!file || !buffer)
|
||||
return FALSE;
|
||||
|
||||
if (file->is_dir || file->fd == -1)
|
||||
return FALSE;
|
||||
|
||||
|
@ -430,6 +471,9 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
|||
{
|
||||
struct STAT st;
|
||||
|
||||
if (!file || !output)
|
||||
return FALSE;
|
||||
|
||||
if (STAT(file->fullpath, &st) != 0)
|
||||
{
|
||||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
|
@ -439,9 +483,11 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
|||
switch (FsInformationClass)
|
||||
{
|
||||
case FileBasicInformation:
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
|
||||
if (!Stream_EnsureRemainingCapacity(output, 4 + 36))
|
||||
goto out_fail;
|
||||
|
||||
Stream_Write_UINT32(output, 36); /* Length */
|
||||
Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */
|
||||
Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */
|
||||
|
@ -452,9 +498,11 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
|||
break;
|
||||
|
||||
case FileStandardInformation:
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232088.aspx */
|
||||
if (!Stream_EnsureRemainingCapacity(output, 4 + 22))
|
||||
goto out_fail;
|
||||
|
||||
Stream_Write_UINT32(output, 22); /* Length */
|
||||
Stream_Write_UINT64(output, st.st_size); /* AllocationSize */
|
||||
Stream_Write_UINT64(output, st.st_size); /* EndOfFile */
|
||||
|
@ -465,9 +513,11 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
|||
break;
|
||||
|
||||
case FileAttributeTagInformation:
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232093.aspx */
|
||||
if (!Stream_EnsureRemainingCapacity(output, 4 + 8))
|
||||
goto out_fail;
|
||||
|
||||
Stream_Write_UINT32(output, 8); /* Length */
|
||||
Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */
|
||||
Stream_Write_UINT32(output, 0); /* ReparseTag */
|
||||
|
@ -478,40 +528,42 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
|||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
return TRUE;
|
||||
out_fail:
|
||||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int dir_empty(const char *path)
|
||||
int dir_empty(const char* path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return PathIsDirectoryEmptyA(path);
|
||||
#else
|
||||
struct dirent *dp;
|
||||
struct dirent* dp;
|
||||
int empty = 1;
|
||||
DIR* dir = opendir(path);
|
||||
|
||||
DIR *dir = opendir(path);
|
||||
if (dir == NULL) //Not a directory or doesn't exist
|
||||
return 1;
|
||||
|
||||
while ((dp = readdir(dir)) != NULL) {
|
||||
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)
|
||||
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length,
|
||||
wStream* input)
|
||||
{
|
||||
char* s = NULL;
|
||||
mode_t m;
|
||||
INT64 size;
|
||||
int status;
|
||||
char* fullpath;
|
||||
|
@ -530,7 +582,8 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
|||
HANDLE hFd;
|
||||
LARGE_INTEGER liSize;
|
||||
|
||||
m = 0;
|
||||
if (!file || !input)
|
||||
return FALSE;
|
||||
|
||||
switch (FsInformationClass)
|
||||
{
|
||||
|
@ -544,68 +597,83 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
|||
|
||||
if (!PathFileExistsA(file->fullpath))
|
||||
return FALSE;
|
||||
hFd = CreateFileA(file->fullpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
hFd = CreateFileA(file->fullpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hFd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
WLog_ERR(TAG, "Unable to create file %s", file->fullpath);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (liCreationTime.QuadPart != 0)
|
||||
{
|
||||
ftCreationTime.dwHighDateTime = liCreationTime.HighPart;
|
||||
ftCreationTime.dwLowDateTime = liCreationTime.LowPart;
|
||||
pftCreationTime = &ftCreationTime;
|
||||
}
|
||||
|
||||
if (liLastAccessTime.QuadPart != 0)
|
||||
{
|
||||
ftLastAccessTime.dwHighDateTime = liLastAccessTime.HighPart;
|
||||
ftLastAccessTime.dwLowDateTime = liLastAccessTime.LowPart;
|
||||
pftLastAccessTime = &ftLastAccessTime;
|
||||
}
|
||||
|
||||
if (liLastWriteTime.QuadPart != 0)
|
||||
{
|
||||
ftLastWriteTime.dwHighDateTime = liLastWriteTime.HighPart;
|
||||
ftLastWriteTime.dwLowDateTime = liLastWriteTime.LowPart;
|
||||
pftLastWriteTime = &ftLastWriteTime;
|
||||
}
|
||||
|
||||
if (liChangeTime.QuadPart != 0 && liChangeTime.QuadPart > liLastWriteTime.QuadPart)
|
||||
{
|
||||
ftLastWriteTime.dwHighDateTime = liChangeTime.HighPart;
|
||||
ftLastWriteTime.dwLowDateTime = liChangeTime.LowPart;
|
||||
pftLastWriteTime = &ftLastWriteTime;
|
||||
}
|
||||
|
||||
if (!SetFileTime(hFd, pftCreationTime, pftLastAccessTime, pftLastWriteTime))
|
||||
{
|
||||
WLog_ERR(TAG, "Unable to set file time on %s", file->fullpath);
|
||||
CloseHandle(hFd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CloseHandle(hFd);
|
||||
break;
|
||||
|
||||
case FileEndOfFileInformation:
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
|
||||
case FileAllocationInformation:
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
|
||||
Stream_Read_INT64(input, size);
|
||||
hFd = CreateFileA(file->fullpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
hFd = CreateFileA(file->fullpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
WLog_ERR(TAG, "Unable to truncate %s to %"PRId64"", file->fullpath, size);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
liSize.QuadPart = size;
|
||||
|
||||
if (SetFilePointer(hFd, liSize.LowPart, &liSize.HighPart, FILE_BEGIN) == 0)
|
||||
{
|
||||
WLog_ERR(TAG, "Unable to truncate %s to %"PRId64"", file->fullpath, size);
|
||||
CloseHandle(hFd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CloseHandle(hFd);
|
||||
break;
|
||||
|
||||
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))
|
||||
|
@ -615,6 +683,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
|||
Stream_Read_UINT8(input, file->delete_pending);
|
||||
else
|
||||
file->delete_pending = 1;
|
||||
|
||||
break;
|
||||
|
||||
case FileRenameInformation:
|
||||
|
@ -622,9 +691,8 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
|||
Stream_Seek_UINT8(input); /* ReplaceIfExists */
|
||||
Stream_Seek_UINT8(input); /* RootDirectory */
|
||||
Stream_Read_UINT32(input, FileNameLength);
|
||||
|
||||
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(input),
|
||||
FileNameLength / 2, &s, 0, NULL, NULL);
|
||||
FileNameLength / 2, &s, 0, NULL, NULL);
|
||||
|
||||
if (status < 1)
|
||||
if (!(s = (char*) calloc(1, 1)))
|
||||
|
@ -634,18 +702,22 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
|||
}
|
||||
|
||||
fullpath = drive_file_combine_fullpath(file->basepath, s);
|
||||
|
||||
if (!fullpath)
|
||||
{
|
||||
WLog_ERR(TAG, "drive_file_combine_fullpath failed!");
|
||||
free (s);
|
||||
free(s);
|
||||
return FALSE;
|
||||
}
|
||||
free(s);
|
||||
|
||||
free(s);
|
||||
#ifdef _WIN32
|
||||
|
||||
if (file->fd)
|
||||
close(file->fd);
|
||||
|
||||
#endif
|
||||
|
||||
if (rename(file->fullpath, fullpath) == 0)
|
||||
{
|
||||
drive_file_set_fullpath(file, fullpath);
|
||||
|
@ -669,7 +741,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
|||
}
|
||||
|
||||
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
||||
const char* path, wStream* output)
|
||||
const char* path, wStream* output)
|
||||
{
|
||||
int length;
|
||||
BOOL ret;
|
||||
|
@ -677,6 +749,9 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
|||
struct STAT st;
|
||||
struct dirent* ent;
|
||||
|
||||
if (!file || !path || !output)
|
||||
return FALSE;
|
||||
|
||||
if (!file->dir)
|
||||
{
|
||||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
|
@ -712,7 +787,6 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
|||
|
||||
if (FilePatternMatchA(ent->d_name, file->pattern))
|
||||
break;
|
||||
|
||||
}
|
||||
while (ent);
|
||||
}
|
||||
|
@ -730,31 +804,32 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
|||
|
||||
memset(&st, 0, sizeof(struct STAT));
|
||||
ent_path = (WCHAR*) malloc(strlen(file->fullpath) + strlen(ent->d_name) + 2);
|
||||
|
||||
if (!ent_path)
|
||||
{
|
||||
WLog_ERR(TAG, "malloc failed!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sprintf((char*) ent_path, "%s/%s", file->fullpath, ent->d_name);
|
||||
|
||||
if (STAT((char*) ent_path, &st) != 0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
free(ent_path);
|
||||
ent_path = NULL;
|
||||
|
||||
length = ConvertToUnicode(sys_code_page, 0, ent->d_name, -1, &ent_path, 0) * 2;
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
switch (FsInformationClass)
|
||||
{
|
||||
case FileDirectoryInformation:
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232097.aspx */
|
||||
if (!Stream_EnsureRemainingCapacity(output, 4 + 64 + length))
|
||||
goto out_fail;
|
||||
|
||||
Stream_Write_UINT32(output, 64 + length); /* Length */
|
||||
Stream_Write_UINT32(output, 0); /* NextEntryOffset */
|
||||
Stream_Write_UINT32(output, 0); /* FileIndex */
|
||||
|
@ -770,9 +845,11 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
|||
break;
|
||||
|
||||
case FileFullDirectoryInformation:
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232068.aspx */
|
||||
if (!Stream_EnsureRemainingCapacity(output, 4 + 68 + length))
|
||||
goto out_fail;
|
||||
|
||||
Stream_Write_UINT32(output, 68 + length); /* Length */
|
||||
Stream_Write_UINT32(output, 0); /* NextEntryOffset */
|
||||
Stream_Write_UINT32(output, 0); /* FileIndex */
|
||||
|
@ -789,9 +866,11 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
|||
break;
|
||||
|
||||
case FileBothDirectoryInformation:
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232095.aspx */
|
||||
if (!Stream_EnsureRemainingCapacity(output, 4 + 93 + length))
|
||||
goto out_fail;
|
||||
|
||||
Stream_Write_UINT32(output, 93 + length); /* Length */
|
||||
Stream_Write_UINT32(output, 0); /* NextEntryOffset */
|
||||
Stream_Write_UINT32(output, 0); /* FileIndex */
|
||||
|
@ -811,9 +890,11 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
|||
break;
|
||||
|
||||
case FileNamesInformation:
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232077.aspx */
|
||||
if (!Stream_EnsureRemainingCapacity(output, 4 + 12 + length))
|
||||
goto out_fail;
|
||||
|
||||
Stream_Write_UINT32(output, 12 + length); /* Length */
|
||||
Stream_Write_UINT32(output, 0); /* NextEntryOffset */
|
||||
Stream_Write_UINT32(output, 0); /* FileIndex */
|
||||
|
@ -831,7 +912,6 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
|||
|
||||
free(ent_path);
|
||||
return ret;
|
||||
|
||||
out_fail:
|
||||
free(ent_path);
|
||||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
* Copyright 2011 Vic Lee
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -167,9 +169,13 @@ static UINT rail_send_client_sysparam(RailClientContext* context,
|
|||
case SPI_SET_HIGH_CONTRAST:
|
||||
length += sysparam->highContrast.colorSchemeLength + 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
length += 8;
|
||||
break;
|
||||
}
|
||||
|
||||
s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8);
|
||||
s = rail_pdu_init(length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* Copyright 2011 Roman Barabanov <romanbarabanov@gmail.com>
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -66,6 +68,7 @@ static UINT rail_write_unicode_string_value(wStream* s, RAIL_UNICODE_STRING* uni
|
|||
|
||||
Stream_Write(s, unicode_string->string, unicode_string->length); /* string */
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
|
@ -77,16 +80,12 @@ static UINT rail_write_unicode_string_value(wStream* s, RAIL_UNICODE_STRING* uni
|
|||
UINT rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType)
|
||||
{
|
||||
UINT16 orderLength;
|
||||
|
||||
orderLength = (UINT16) Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
|
||||
rail_write_pdu_header(s, orderType, orderLength);
|
||||
Stream_SetPosition(s, orderLength);
|
||||
|
||||
WLog_Print(rail->log, WLOG_DEBUG, "Sending %s PDU, length: %"PRIu16"",
|
||||
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength);
|
||||
|
||||
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength);
|
||||
return rail_send_channel_data(rail, Stream_Buffer(s), orderLength);
|
||||
}
|
||||
|
||||
|
@ -120,8 +119,8 @@ UINT rail_read_server_exec_result_order(wStream* s, RAIL_EXEC_RESULT_ORDER* exec
|
|||
Stream_Read_UINT16(s, execResult->execResult); /* execResult (2 bytes) */
|
||||
Stream_Read_UINT32(s, execResult->rawResult); /* rawResult (4 bytes) */
|
||||
Stream_Seek_UINT16(s); /* padding (2 bytes) */
|
||||
|
||||
return rail_read_unicode_string(s, &execResult->exeOrFile) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; /* exeOrFile */
|
||||
return rail_read_unicode_string(s,
|
||||
&execResult->exeOrFile) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; /* exeOrFile */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,7 +180,6 @@ UINT rail_read_server_minmaxinfo_order(wStream* s, RAIL_MINMAXINFO_ORDER* minmax
|
|||
Stream_Read_UINT16(s, minmaxinfo->minTrackHeight); /* minTrackHeight (2 bytes) */
|
||||
Stream_Read_UINT16(s, minmaxinfo->maxTrackWidth); /* maxTrackWidth (2 bytes) */
|
||||
Stream_Read_UINT16(s, minmaxinfo->maxTrackHeight); /* maxTrackHeight (2 bytes) */
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
|
@ -201,14 +199,11 @@ UINT rail_read_server_localmovesize_order(wStream* s, RAIL_LOCALMOVESIZE_ORDER*
|
|||
}
|
||||
|
||||
Stream_Read_UINT32(s, localMoveSize->windowId); /* windowId (4 bytes) */
|
||||
|
||||
Stream_Read_UINT16(s, isMoveSizeStart); /* isMoveSizeStart (2 bytes) */
|
||||
localMoveSize->isMoveSizeStart = (isMoveSizeStart != 0) ? TRUE : FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, localMoveSize->moveSizeType); /* moveSizeType (2 bytes) */
|
||||
Stream_Read_UINT16(s, localMoveSize->posX); /* posX (2 bytes) */
|
||||
Stream_Read_UINT16(s, localMoveSize->posY); /* posY (2 bytes) */
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
|
@ -226,8 +221,8 @@ UINT rail_read_server_get_appid_resp_order(wStream* s, RAIL_GET_APPID_RESP_ORDER
|
|||
}
|
||||
|
||||
Stream_Read_UINT32(s, getAppidResp->windowId); /* windowId (4 bytes) */
|
||||
Stream_Read(s, (BYTE*) &(getAppidResp->applicationId), 512); /* applicationId (256 UNICODE chars) */
|
||||
|
||||
Stream_Read(s, (BYTE*) & (getAppidResp->applicationId),
|
||||
512); /* applicationId (256 UNICODE chars) */
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
|
@ -245,7 +240,6 @@ UINT rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbarIn
|
|||
}
|
||||
|
||||
Stream_Read_UINT32(s, langbarInfo->languageBarStatus); /* languageBarStatus (4 bytes) */
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
|
@ -266,21 +260,25 @@ UINT rail_write_client_exec_order(wStream* s, RAIL_EXEC_ORDER* exec)
|
|||
Stream_Write_UINT16(s, exec->exeOrFile.length); /* exeOrFileLength (2 bytes) */
|
||||
Stream_Write_UINT16(s, exec->workingDir.length); /* workingDirLength (2 bytes) */
|
||||
Stream_Write_UINT16(s, exec->arguments.length); /* argumentsLength (2 bytes) */
|
||||
|
||||
if ((error = rail_write_unicode_string_value(s, &exec->exeOrFile)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %"PRIu32"", error);
|
||||
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %"PRIu32"", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if ((error = rail_write_unicode_string_value(s, &exec->workingDir)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %"PRIu32"", error);
|
||||
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %"PRIu32"", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if ((error = rail_write_unicode_string_value(s, &exec->arguments)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %"PRIu32"", error);
|
||||
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %"PRIu32"", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -293,7 +291,6 @@ UINT rail_write_client_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam)
|
|||
{
|
||||
BYTE body;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->param); /* systemParam (4 bytes) */
|
||||
|
||||
switch (sysparam->param)
|
||||
|
@ -350,9 +347,7 @@ UINT rail_write_client_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam)
|
|||
void rail_write_client_activate_order(wStream* s, RAIL_ACTIVATE_ORDER* activate)
|
||||
{
|
||||
BYTE enabled;
|
||||
|
||||
Stream_Write_UINT32(s, activate->windowId); /* windowId (4 bytes) */
|
||||
|
||||
enabled = activate->enabled;
|
||||
Stream_Write_UINT8(s, enabled); /* enabled (1 byte) */
|
||||
}
|
||||
|
@ -415,9 +410,10 @@ UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake
|
|||
if (context->custom)
|
||||
{
|
||||
IFCALLRET(context->ServerHandshake, error, context, handshake);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerHandshake failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerHandshake failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -427,7 +423,8 @@ UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake
|
|||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* handshakeEx, wStream* s)
|
||||
UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* handshakeEx,
|
||||
wStream* s)
|
||||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
UINT error;
|
||||
|
@ -441,10 +438,10 @@ UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* han
|
|||
if (context->custom)
|
||||
{
|
||||
IFCALLRET(context->ClientHandshakeEx, error, context, handshakeEx);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ClientHandshakeEx failed with error %"PRIu32"", error);
|
||||
|
||||
}
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ClientHandshakeEx failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -458,7 +455,6 @@ UINT rail_recv_exec_result_order(railPlugin* rail, RAIL_EXEC_RESULT_ORDER* execR
|
|||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
UINT error;
|
||||
|
||||
ZeroMemory(execResult, sizeof(RAIL_EXEC_RESULT_ORDER));
|
||||
|
||||
if ((error = rail_read_server_exec_result_order(s, execResult)))
|
||||
|
@ -470,10 +466,10 @@ UINT rail_recv_exec_result_order(railPlugin* rail, RAIL_EXEC_RESULT_ORDER* execR
|
|||
if (context->custom)
|
||||
{
|
||||
IFCALLRET(context->ServerExecuteResult, error, context, execResult);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerExecuteResult failed with error %"PRIu32"", error);
|
||||
|
||||
}
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerExecuteResult failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -497,9 +493,10 @@ UINT rail_recv_server_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysp
|
|||
if (context->custom)
|
||||
{
|
||||
IFCALLRET(context->ServerSystemParam, error, context, sysparam);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerSystemParam failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerSystemParam failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -509,7 +506,8 @@ UINT rail_recv_server_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysp
|
|||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ORDER* minMaxInfo, wStream* s)
|
||||
UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ORDER* minMaxInfo,
|
||||
wStream* s)
|
||||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
UINT error;
|
||||
|
@ -523,9 +521,10 @@ UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ORDER*
|
|||
if (context->custom)
|
||||
{
|
||||
IFCALLRET(context->ServerMinMaxInfo, error, context, minMaxInfo);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerMinMaxInfo failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerMinMaxInfo failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -535,7 +534,8 @@ UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ORDER*
|
|||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT rail_recv_server_localmovesize_order(railPlugin* rail, RAIL_LOCALMOVESIZE_ORDER* localMoveSize, wStream* s)
|
||||
UINT rail_recv_server_localmovesize_order(railPlugin* rail, RAIL_LOCALMOVESIZE_ORDER* localMoveSize,
|
||||
wStream* s)
|
||||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
UINT error;
|
||||
|
@ -549,9 +549,10 @@ UINT rail_recv_server_localmovesize_order(railPlugin* rail, RAIL_LOCALMOVESIZE_O
|
|||
if (context->custom)
|
||||
{
|
||||
IFCALLRET(context->ServerLocalMoveSize, error, context, localMoveSize);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerLocalMoveSize failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerLocalMoveSize failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -561,7 +562,8 @@ UINT rail_recv_server_localmovesize_order(railPlugin* rail, RAIL_LOCALMOVESIZE_O
|
|||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, RAIL_GET_APPID_RESP_ORDER* getAppIdResp, wStream* s)
|
||||
UINT rail_recv_server_get_appid_resp_order(railPlugin* rail,
|
||||
RAIL_GET_APPID_RESP_ORDER* getAppIdResp, wStream* s)
|
||||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
UINT error;
|
||||
|
@ -575,9 +577,10 @@ UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, RAIL_GET_APPID_RESP
|
|||
if (context->custom)
|
||||
{
|
||||
IFCALLRET(context->ServerGetAppIdResponse, error, context, getAppIdResp);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerGetAppIdResponse failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerGetAppIdResponse failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -587,7 +590,8 @@ UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, RAIL_GET_APPID_RESP
|
|||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* langBarInfo, wStream* s)
|
||||
UINT rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* langBarInfo,
|
||||
wStream* s)
|
||||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
UINT error;
|
||||
|
@ -601,9 +605,10 @@ UINT rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* lan
|
|||
if (context->custom)
|
||||
{
|
||||
IFCALLRET(context->ServerLanguageBarInfo, error, context, langBarInfo);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerLanguageBarInfo failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerLanguageBarInfo failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -626,57 +631,57 @@ UINT rail_order_recv(railPlugin* rail, wStream* s)
|
|||
}
|
||||
|
||||
WLog_Print(rail->log, WLOG_DEBUG, "Received %s PDU, length:%"PRIu16"",
|
||||
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength);
|
||||
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength);
|
||||
|
||||
switch (orderType)
|
||||
{
|
||||
case RDP_RAIL_ORDER_HANDSHAKE:
|
||||
{
|
||||
RAIL_HANDSHAKE_ORDER handshake;
|
||||
return rail_recv_handshake_order(rail, &handshake, s);
|
||||
}
|
||||
{
|
||||
RAIL_HANDSHAKE_ORDER handshake;
|
||||
return rail_recv_handshake_order(rail, &handshake, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_HANDSHAKE_EX:
|
||||
{
|
||||
RAIL_HANDSHAKE_EX_ORDER handshakeEx;
|
||||
return rail_recv_handshake_ex_order(rail, &handshakeEx, s);
|
||||
}
|
||||
{
|
||||
RAIL_HANDSHAKE_EX_ORDER handshakeEx;
|
||||
return rail_recv_handshake_ex_order(rail, &handshakeEx, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_EXEC_RESULT:
|
||||
{
|
||||
RAIL_EXEC_RESULT_ORDER execResult;
|
||||
return rail_recv_exec_result_order(rail, &execResult, s);
|
||||
}
|
||||
{
|
||||
RAIL_EXEC_RESULT_ORDER execResult;
|
||||
return rail_recv_exec_result_order(rail, &execResult, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_SYSPARAM:
|
||||
{
|
||||
RAIL_SYSPARAM_ORDER sysparam;
|
||||
return rail_recv_server_sysparam_order(rail, &sysparam, s);
|
||||
}
|
||||
{
|
||||
RAIL_SYSPARAM_ORDER sysparam;
|
||||
return rail_recv_server_sysparam_order(rail, &sysparam, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_MINMAXINFO:
|
||||
{
|
||||
RAIL_MINMAXINFO_ORDER minMaxInfo;
|
||||
return rail_recv_server_minmaxinfo_order(rail, &minMaxInfo, s);
|
||||
}
|
||||
{
|
||||
RAIL_MINMAXINFO_ORDER minMaxInfo;
|
||||
return rail_recv_server_minmaxinfo_order(rail, &minMaxInfo, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_LOCALMOVESIZE:
|
||||
{
|
||||
RAIL_LOCALMOVESIZE_ORDER localMoveSize;
|
||||
return rail_recv_server_localmovesize_order(rail, &localMoveSize, s);
|
||||
}
|
||||
{
|
||||
RAIL_LOCALMOVESIZE_ORDER localMoveSize;
|
||||
return rail_recv_server_localmovesize_order(rail, &localMoveSize, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_GET_APPID_RESP:
|
||||
{
|
||||
RAIL_GET_APPID_RESP_ORDER getAppIdResp;
|
||||
return rail_recv_server_get_appid_resp_order(rail, &getAppIdResp, s);
|
||||
}
|
||||
{
|
||||
RAIL_GET_APPID_RESP_ORDER getAppIdResp;
|
||||
return rail_recv_server_get_appid_resp_order(rail, &getAppIdResp, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_LANGBARINFO:
|
||||
{
|
||||
RAIL_LANGBAR_INFO_ORDER langBarInfo;
|
||||
return rail_recv_langbar_info_order(rail, &langBarInfo, s);
|
||||
}
|
||||
{
|
||||
RAIL_LANGBAR_INFO_ORDER langBarInfo;
|
||||
return rail_recv_langbar_info_order(rail, &langBarInfo, s);
|
||||
}
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "Unknown RAIL PDU order reveived.");
|
||||
|
@ -696,8 +701,8 @@ UINT rail_send_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake
|
|||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
||||
s = rail_pdu_init(RAIL_HANDSHAKE_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -720,6 +725,7 @@ UINT rail_send_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* han
|
|||
wStream* s;
|
||||
UINT error;
|
||||
s = rail_pdu_init(RAIL_HANDSHAKE_EX_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -741,8 +747,8 @@ UINT rail_send_client_status_order(railPlugin* rail, RAIL_CLIENT_STATUS_ORDER* c
|
|||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
||||
s = rail_pdu_init(RAIL_CLIENT_STATUS_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -765,13 +771,12 @@ UINT rail_send_client_exec_order(railPlugin* rail, RAIL_EXEC_ORDER* exec)
|
|||
wStream* s;
|
||||
UINT error;
|
||||
size_t length;
|
||||
|
||||
length = RAIL_EXEC_ORDER_LENGTH +
|
||||
exec->exeOrFile.length +
|
||||
exec->workingDir.length +
|
||||
exec->arguments.length;
|
||||
|
||||
exec->exeOrFile.length +
|
||||
exec->workingDir.length +
|
||||
exec->arguments.length;
|
||||
s = rail_pdu_init(length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -783,11 +788,13 @@ UINT rail_send_client_exec_order(railPlugin* rail, RAIL_EXEC_ORDER* exec)
|
|||
WLog_ERR(TAG, "rail_write_client_exec_order failed with error %"PRIu32"!", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if ((error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_EXEC)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_pdu failed with error %"PRIu32"!", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
@ -802,7 +809,6 @@ UINT rail_send_client_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysp
|
|||
wStream* s;
|
||||
int length;
|
||||
UINT error;
|
||||
|
||||
length = RAIL_SYSPARAM_ORDER_LENGTH;
|
||||
|
||||
switch (sysparam->param)
|
||||
|
@ -823,9 +829,14 @@ UINT rail_send_client_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysp
|
|||
case SPI_SET_HIGH_CONTRAST:
|
||||
length += sysparam->highContrast.colorSchemeLength + 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
length += 8;
|
||||
break;
|
||||
}
|
||||
|
||||
s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8);
|
||||
s = rail_pdu_init(length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -860,6 +871,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
|
|||
if (sysparam->params & SPI_MASK_SET_HIGH_CONTRAST)
|
||||
{
|
||||
sysparam->param = SPI_SET_HIGH_CONTRAST;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %"PRIu32"!", error);
|
||||
|
@ -870,6 +882,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
|
|||
if (sysparam->params & SPI_MASK_TASKBAR_POS)
|
||||
{
|
||||
sysparam->param = SPI_TASKBAR_POS;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %"PRIu32"!", error);
|
||||
|
@ -880,6 +893,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
|
|||
if (sysparam->params & SPI_MASK_SET_MOUSE_BUTTON_SWAP)
|
||||
{
|
||||
sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %"PRIu32"!", error);
|
||||
|
@ -890,6 +904,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
|
|||
if (sysparam->params & SPI_MASK_SET_KEYBOARD_PREF)
|
||||
{
|
||||
sysparam->param = SPI_SET_KEYBOARD_PREF;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %"PRIu32"!", error);
|
||||
|
@ -900,6 +915,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
|
|||
if (sysparam->params & SPI_MASK_SET_DRAG_FULL_WINDOWS)
|
||||
{
|
||||
sysparam->param = SPI_SET_DRAG_FULL_WINDOWS;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %"PRIu32"!", error);
|
||||
|
@ -910,6 +926,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
|
|||
if (sysparam->params & SPI_MASK_SET_KEYBOARD_CUES)
|
||||
{
|
||||
sysparam->param = SPI_SET_KEYBOARD_CUES;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %"PRIu32"!", error);
|
||||
|
@ -920,6 +937,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
|
|||
if (sysparam->params & SPI_MASK_SET_WORK_AREA)
|
||||
{
|
||||
sysparam->param = SPI_SET_WORK_AREA;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %"PRIu32"!", error);
|
||||
|
@ -939,8 +957,8 @@ UINT rail_send_client_activate_order(railPlugin* rail, RAIL_ACTIVATE_ORDER* acti
|
|||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
||||
s = rail_pdu_init(RAIL_ACTIVATE_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -962,8 +980,8 @@ UINT rail_send_client_sysmenu_order(railPlugin* rail, RAIL_SYSMENU_ORDER* sysmen
|
|||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
||||
s = rail_pdu_init(RAIL_SYSMENU_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -985,8 +1003,8 @@ UINT rail_send_client_syscommand_order(railPlugin* rail, RAIL_SYSCOMMAND_ORDER*
|
|||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
||||
s = rail_pdu_init(RAIL_SYSCOMMAND_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -1008,8 +1026,8 @@ UINT rail_send_client_notify_event_order(railPlugin* rail, RAIL_NOTIFY_EVENT_ORD
|
|||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
||||
s = rail_pdu_init(RAIL_NOTIFY_EVENT_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -1031,8 +1049,8 @@ UINT rail_send_client_window_move_order(railPlugin* rail, RAIL_WINDOW_MOVE_ORDER
|
|||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
||||
s = rail_pdu_init(RAIL_WINDOW_MOVE_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -1054,8 +1072,8 @@ UINT rail_send_client_get_appid_req_order(railPlugin* rail, RAIL_GET_APPID_REQ_O
|
|||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
||||
s = rail_pdu_init(RAIL_GET_APPID_REQ_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
@ -1077,8 +1095,8 @@ UINT rail_send_client_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORD
|
|||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
||||
s = rail_pdu_init(RAIL_LANGBAR_INFO_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
|
|
|
@ -1140,7 +1140,6 @@ static void* rdpdr_server_thread(void* arg)
|
|||
DWORD status;
|
||||
DWORD nCount;
|
||||
void* buffer;
|
||||
int position;
|
||||
HANDLE events[8];
|
||||
RDPDR_HEADER header;
|
||||
HANDLE ChannelEvent;
|
||||
|
@ -1215,7 +1214,6 @@ static void* rdpdr_server_thread(void* arg)
|
|||
|
||||
if (BytesReturned >= RDPDR_HEADER_LENGTH)
|
||||
{
|
||||
position = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
Stream_SetLength(s, BytesReturned);
|
||||
|
||||
|
|
|
@ -313,7 +313,7 @@ BOOL rdpei_write_4byte_signed(wStream* s, INT32 value)
|
|||
if (negative)
|
||||
byte |= 0x20;
|
||||
|
||||
Stream_Write_UINT8(s, value);
|
||||
Stream_Write_UINT8(s, byte);
|
||||
}
|
||||
else if (value <= 0x1FFF)
|
||||
{
|
||||
|
|
|
@ -1330,10 +1330,8 @@ static void* rdpgfx_server_thread_func(void* arg)
|
|||
DWORD nCount;
|
||||
void* buffer;
|
||||
HANDLE events[8];
|
||||
DWORD BytesReturned = 0;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
buffer = NULL;
|
||||
BytesReturned = 0;
|
||||
nCount = 0;
|
||||
|
||||
events[nCount++] = priv->stopEvent;
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
* Copyright 2011 Anthony Tong <atong@trustedcs.com>
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -1043,7 +1045,7 @@ static LONG smartcard_StatusA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
|
|||
LONG status;
|
||||
Status_Call* call;
|
||||
IRP* irp = operation->irp;
|
||||
operation->call = call = calloc(1, sizeof(State_Call));
|
||||
operation->call = call = calloc(1, sizeof(Status_Call));
|
||||
|
||||
if (!call)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
@ -1100,7 +1102,7 @@ static LONG smartcard_StatusW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
|
|||
LONG status;
|
||||
Status_Call* call;
|
||||
IRP* irp = operation->irp;
|
||||
operation->call = call = calloc(1, sizeof(State_Call));
|
||||
operation->call = call = calloc(1, sizeof(Status_Call));
|
||||
|
||||
if (!call)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
|
|
@ -2761,7 +2761,7 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS
|
|||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
call->rgAtrMasks = calloc(call->cAtrs, sizeof(SCARD_ATRMASK));
|
||||
call->rgAtrMasks = (LocateCards_ATRMask*)calloc(call->cAtrs, sizeof(SCARD_ATRMASK));
|
||||
|
||||
if (!call->rgAtrMasks)
|
||||
{
|
||||
|
@ -2789,7 +2789,7 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS
|
|||
|
||||
if (call->cReaders > 0)
|
||||
{
|
||||
call->rgReaderStates = calloc(call->cReaders, sizeof(SCARD_READERSTATEA));
|
||||
call->rgReaderStates = (ReaderStateA*)calloc(call->cReaders, sizeof(SCARD_READERSTATEA));
|
||||
|
||||
if (!call->rgReaderStates)
|
||||
{
|
||||
|
|
|
@ -1200,12 +1200,10 @@ static BOOL xf_post_connect(freerdp* instance)
|
|||
{
|
||||
rdpUpdate* update;
|
||||
rdpContext* context;
|
||||
rdpChannels* channels;
|
||||
rdpSettings* settings;
|
||||
ResizeWindowEventArgs e;
|
||||
xfContext* xfc = (xfContext*) instance->context;
|
||||
context = instance->context;
|
||||
channels = context->channels;
|
||||
settings = instance->settings;
|
||||
update = context->update;
|
||||
|
||||
|
@ -1320,6 +1318,7 @@ static int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
|
|||
|
||||
static void* xf_input_thread(void* arg)
|
||||
{
|
||||
BOOL running = TRUE;
|
||||
DWORD status;
|
||||
DWORD nCount;
|
||||
HANDLE events[3];
|
||||
|
@ -1336,48 +1335,61 @@ static void* xf_input_thread(void* arg)
|
|||
events[nCount++] = xfc->x11event;
|
||||
events[nCount++] = instance->context->abortEvent;
|
||||
|
||||
while (1)
|
||||
while (running)
|
||||
{
|
||||
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(events[0], 0) == WAIT_OBJECT_0)
|
||||
switch (status)
|
||||
{
|
||||
if (MessageQueue_Peek(queue, &msg, FALSE))
|
||||
{
|
||||
if (msg.id == WMQ_QUIT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(events[1], 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
do
|
||||
{
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
pending_status = XPending(xfc->display);
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
|
||||
if (pending_status)
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
case WAIT_OBJECT_0 + 2:
|
||||
if (WaitForSingleObject(events[0], 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
ZeroMemory(&xevent, sizeof(xevent));
|
||||
XNextEvent(xfc->display, &xevent);
|
||||
process_status = xf_event_process(instance, &xevent);
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
if (MessageQueue_Peek(queue, &msg, FALSE))
|
||||
{
|
||||
if (msg.id == WMQ_QUIT)
|
||||
running = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(events[1], 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
do
|
||||
{
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
pending_status = XPending(xfc->display);
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
|
||||
if (pending_status)
|
||||
{
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
ZeroMemory(&xevent, sizeof(xevent));
|
||||
XNextEvent(xfc->display, &xevent);
|
||||
process_status = xf_event_process(instance, &xevent);
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
|
||||
if (!process_status)
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (pending_status);
|
||||
|
||||
if (!process_status)
|
||||
{
|
||||
running = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (pending_status);
|
||||
|
||||
if (!process_status)
|
||||
if (WaitForSingleObject(events[2], 0) == WAIT_OBJECT_0)
|
||||
running = FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(events[2], 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
break;
|
||||
default:
|
||||
running = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1447,7 +1459,6 @@ static void* xf_client_thread(void* param)
|
|||
rdpContext* context;
|
||||
HANDLE inputEvent = NULL;
|
||||
HANDLE inputThread = NULL;
|
||||
rdpChannels* channels;
|
||||
rdpSettings* settings;
|
||||
exit_code = 0;
|
||||
instance = (freerdp*) param;
|
||||
|
@ -1482,13 +1493,12 @@ static void* xf_client_thread(void* param)
|
|||
if (freerdp_get_last_error(instance->context) ==
|
||||
FREERDP_ERROR_AUTHENTICATION_FAILED)
|
||||
exit_code = XF_EXIT_AUTH_FAILURE;
|
||||
else
|
||||
else if (exit_code == ERRINFO_SUCCESS)
|
||||
exit_code = XF_EXIT_CONN_FAILED;
|
||||
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
channels = context->channels;
|
||||
settings = context->settings;
|
||||
|
||||
if (!settings->AsyncInput)
|
||||
|
@ -1537,6 +1547,9 @@ static void* xf_client_thread(void* param)
|
|||
|
||||
waitStatus = WaitForMultipleObjects(nCount, handles, FALSE, 100);
|
||||
|
||||
if (waitStatus == WAIT_FAILED)
|
||||
break;
|
||||
|
||||
if (!settings->AsyncTransport)
|
||||
{
|
||||
if (!freerdp_check_event_handles(context))
|
||||
|
@ -1696,7 +1709,6 @@ static int xfreerdp_client_stop(rdpContext* context)
|
|||
|
||||
static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
rdpSettings* settings;
|
||||
xfContext* xfc = (xfContext*) instance->context;
|
||||
assert(context);
|
||||
assert(xfc);
|
||||
|
@ -1711,7 +1723,6 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
|||
instance->VerifyCertificate = client_cli_verify_certificate;
|
||||
instance->VerifyChangedCertificate = client_cli_verify_changed_certificate;
|
||||
instance->LogonErrorInfo = xf_logon_error_info;
|
||||
settings = instance->settings;
|
||||
PubSub_SubscribeTerminate(context->pubSub,
|
||||
(pTerminateEventHandler) xf_TerminateEventHandler);
|
||||
#ifdef WITH_XRENDER
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
#define CLAMP_COORDINATES(x, y) if (x < 0) x = 0; if (y < 0) y = 0
|
||||
|
||||
const char* const X11_EVENT_STRINGS[] =
|
||||
static const char* const X11_EVENT_STRINGS[] =
|
||||
{
|
||||
"", "",
|
||||
"KeyPress",
|
||||
|
@ -311,7 +311,6 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button,
|
|||
BOOL extended;
|
||||
rdpInput* input;
|
||||
Window childWindow;
|
||||
flags = 0;
|
||||
wheel = FALSE;
|
||||
extended = FALSE;
|
||||
input = xfc->context.input;
|
||||
|
@ -407,14 +406,14 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
|
|||
BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button,
|
||||
Window window, BOOL app)
|
||||
{
|
||||
int flags;
|
||||
BOOL wheel;
|
||||
BOOL extended;
|
||||
int flags = 0;
|
||||
BOOL extended = FALSE;
|
||||
rdpInput* input;
|
||||
Window childWindow;
|
||||
flags = 0;
|
||||
wheel = FALSE;
|
||||
extended = FALSE;
|
||||
|
||||
if (!xfc || !xfc->context.input)
|
||||
return FALSE;
|
||||
|
||||
input = xfc->context.input;
|
||||
|
||||
switch (button)
|
||||
|
|
|
@ -306,12 +306,12 @@ static BOOL xf_gdi_dstblt(rdpContext* context, const DSTBLT_ORDER* dstblt)
|
|||
XFillRectangle(xfc->display, xfc->drawing, xfc->gc,
|
||||
dstblt->nLeftRect, dstblt->nTopRect,
|
||||
dstblt->nWidth, dstblt->nHeight);
|
||||
ret = TRUE;
|
||||
|
||||
if (xfc->drawing == xfc->primary)
|
||||
ret = gdi_InvalidateRegion(xfc->hdc, dstblt->nLeftRect, dstblt->nTopRect,
|
||||
dstblt->nWidth, dstblt->nHeight);
|
||||
|
||||
ret = TRUE;
|
||||
fail:
|
||||
XSetFunction(xfc->display, xfc->gc, GXcopy);
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
|
@ -394,11 +394,12 @@ static BOOL xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
if (xfc->drawing == xfc->primary)
|
||||
ret = gdi_InvalidateRegion(xfc->hdc, patblt->nLeftRect, patblt->nTopRect,
|
||||
patblt->nWidth, patblt->nHeight);
|
||||
|
||||
ret = TRUE;
|
||||
fail:
|
||||
XSetFunction(xfc->display, xfc->gc, GXcopy);
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
|
@ -421,13 +422,13 @@ static BOOL xf_gdi_scrblt(rdpContext* context, const SCRBLT_ORDER* scrblt)
|
|||
XCopyArea(xfc->display, xfc->primary, xfc->drawing, xfc->gc, scrblt->nXSrc,
|
||||
scrblt->nYSrc,
|
||||
scrblt->nWidth, scrblt->nHeight, scrblt->nLeftRect, scrblt->nTopRect);
|
||||
ret = TRUE;
|
||||
|
||||
if (xfc->drawing == xfc->primary)
|
||||
ret = gdi_InvalidateRegion(xfc->hdc, scrblt->nLeftRect, scrblt->nTopRect,
|
||||
scrblt->nWidth, scrblt->nHeight);
|
||||
|
||||
XSetFunction(xfc->display, xfc->gc, GXcopy);
|
||||
ret = TRUE;
|
||||
fail:
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return ret;
|
||||
|
@ -708,6 +709,7 @@ static BOOL xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
|||
XCopyArea(xfc->display, bitmap->pixmap, xfc->drawing, xfc->gc,
|
||||
mem3blt->nXSrc, mem3blt->nYSrc, mem3blt->nWidth, mem3blt->nHeight,
|
||||
mem3blt->nLeftRect, mem3blt->nTopRect);
|
||||
ret = TRUE;
|
||||
|
||||
if (xfc->drawing == xfc->primary)
|
||||
ret = gdi_InvalidateRegion(xfc->hdc, mem3blt->nLeftRect, mem3blt->nTopRect,
|
||||
|
@ -719,7 +721,6 @@ static BOOL xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
|||
if (pattern != 0)
|
||||
XFreePixmap(xfc->display, pattern);
|
||||
|
||||
ret = TRUE;
|
||||
fail:
|
||||
XSetFunction(xfc->display, xfc->gc, GXcopy);
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
|
|
|
@ -100,19 +100,26 @@ BOOL xf_decode_color(xfContext* xfc, const UINT32 srcColor, XColor* color)
|
|||
/* Bitmap Class */
|
||||
static BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
|
||||
{
|
||||
int depth;
|
||||
BOOL rc = FALSE;
|
||||
UINT32 depth;
|
||||
BYTE* data;
|
||||
Pixmap pixmap;
|
||||
XImage* image;
|
||||
rdpGdi* gdi;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
if (!context || !bitmap || !context->gdi)
|
||||
return FALSE;
|
||||
|
||||
gdi = context->gdi;
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
data = bitmap->data;
|
||||
depth = GetBitsPerPixel(bitmap->format);
|
||||
pixmap = XCreatePixmap(xfc->display, xfc->drawable, bitmap->width,
|
||||
bitmap->height, xfc->depth);
|
||||
|
||||
if (!pixmap)
|
||||
goto unlock;
|
||||
|
||||
if (bitmap->data)
|
||||
{
|
||||
XSetFunction(xfc->display, xfc->gc, GXcopy);
|
||||
|
@ -120,15 +127,17 @@ static BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
|
|||
if (depth != xfc->depth)
|
||||
{
|
||||
if (!(data = _aligned_malloc(bitmap->width * bitmap->height * 4, 16)))
|
||||
goto unlock;
|
||||
|
||||
if (!freerdp_image_copy(data, gdi->dstFormat, 0, 0, 0,
|
||||
bitmap->width, bitmap->height,
|
||||
bitmap->data, bitmap->format,
|
||||
0, 0, 0, &context->gdi->palette, FREERDP_FLIP_NONE))
|
||||
{
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
_aligned_free(data);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
freerdp_image_copy(data, gdi->dstFormat, 0, 0, 0,
|
||||
bitmap->width, bitmap->height,
|
||||
bitmap->data, bitmap->format,
|
||||
0, 0, 0, &context->gdi->palette, FREERDP_FLIP_NONE);
|
||||
_aligned_free(bitmap->data);
|
||||
bitmap->data = data;
|
||||
bitmap->format = gdi->dstFormat;
|
||||
|
@ -137,14 +146,20 @@ static BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
|
|||
image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
|
||||
ZPixmap, 0, (char*) bitmap->data, bitmap->width, bitmap->height,
|
||||
xfc->scanline_pad, 0);
|
||||
|
||||
if (!image)
|
||||
goto unlock;
|
||||
|
||||
XPutImage(xfc->display, pixmap, xfc->gc, image, 0, 0, 0, 0, bitmap->width,
|
||||
bitmap->height);
|
||||
XFree(image);
|
||||
}
|
||||
|
||||
((xfBitmap*) bitmap)->pixmap = pixmap;
|
||||
rc = TRUE;
|
||||
unlock:
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return TRUE;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void xf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
|
||||
|
@ -163,7 +178,7 @@ static BOOL xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
|
|||
XImage* image;
|
||||
int width, height;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
BOOL ret = TRUE;
|
||||
BOOL ret;
|
||||
width = bitmap->right - bitmap->left + 1;
|
||||
height = bitmap->bottom - bitmap->top + 1;
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
@ -176,7 +191,7 @@ static BOOL xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
|
|||
XFree(image);
|
||||
ret = gdi_InvalidateRegion(xfc->hdc, bitmap->left, bitmap->top, width, height);
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap,
|
||||
|
@ -199,7 +214,6 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
|||
{
|
||||
#ifdef WITH_XCURSOR
|
||||
UINT32 CursorFormat;
|
||||
rdpGdi* gdi;
|
||||
size_t size;
|
||||
XcursorImage ci;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
@ -213,7 +227,6 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
|||
else
|
||||
CursorFormat = PIXEL_FORMAT_BGRA32;
|
||||
|
||||
gdi = context->gdi;
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
ZeroMemory(&ci, sizeof(ci));
|
||||
ci.version = XCURSOR_IMAGE_VERSION;
|
||||
|
|
|
@ -60,20 +60,17 @@ typedef struct touch_contact
|
|||
|
||||
} touchContact;
|
||||
|
||||
touchContact contacts[MAX_CONTACTS];
|
||||
static touchContact contacts[MAX_CONTACTS];
|
||||
|
||||
int active_contacts;
|
||||
int lastEvType;
|
||||
XIDeviceEvent lastEvent;
|
||||
double firstDist = -1.0;
|
||||
double lastDist;
|
||||
static int active_contacts;
|
||||
static int lastEvType;
|
||||
static XIDeviceEvent lastEvent;
|
||||
static double firstDist = -1.0;
|
||||
static double lastDist;
|
||||
|
||||
double z_vector;
|
||||
double px_vector;
|
||||
double py_vector;
|
||||
|
||||
int xinput_opcode;
|
||||
int scale_cnt;
|
||||
static double z_vector;
|
||||
static double px_vector;
|
||||
static double py_vector;
|
||||
|
||||
const char* xf_input_get_class_string(int class)
|
||||
{
|
||||
|
@ -207,7 +204,7 @@ int xf_input_init(xfContext* xfc, Window window)
|
|||
return 0;
|
||||
}
|
||||
|
||||
BOOL xf_input_is_duplicate(XGenericEventCookie* cookie)
|
||||
static BOOL xf_input_is_duplicate(XGenericEventCookie* cookie)
|
||||
{
|
||||
XIDeviceEvent* event;
|
||||
event = cookie->data;
|
||||
|
@ -224,7 +221,7 @@ BOOL xf_input_is_duplicate(XGenericEventCookie* cookie)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void xf_input_save_last_event(XGenericEventCookie* cookie)
|
||||
static void xf_input_save_last_event(XGenericEventCookie* cookie)
|
||||
{
|
||||
XIDeviceEvent* event;
|
||||
event = cookie->data;
|
||||
|
@ -235,7 +232,7 @@ void xf_input_save_last_event(XGenericEventCookie* cookie)
|
|||
lastEvent.event_y = event->event_y;
|
||||
}
|
||||
|
||||
void xf_input_detect_pan(xfContext* xfc)
|
||||
static void xf_input_detect_pan(xfContext* xfc)
|
||||
{
|
||||
double dx[2];
|
||||
double dy[2];
|
||||
|
@ -325,10 +322,9 @@ void xf_input_detect_pan(xfContext* xfc)
|
|||
}
|
||||
}
|
||||
|
||||
void xf_input_detect_pinch(xfContext* xfc)
|
||||
static void xf_input_detect_pinch(xfContext* xfc)
|
||||
{
|
||||
double dist;
|
||||
double zoom;
|
||||
double delta;
|
||||
ZoomingChangeEventArgs e;
|
||||
|
||||
|
@ -347,7 +343,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
|||
{
|
||||
firstDist = dist;
|
||||
lastDist = firstDist;
|
||||
scale_cnt = 0;
|
||||
z_vector = 0;
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
|
@ -364,7 +359,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
|||
delta = -1.0;
|
||||
|
||||
/* compare the current distance to the first one */
|
||||
zoom = (dist / firstDist);
|
||||
z_vector += delta;
|
||||
lastDist = dist;
|
||||
|
||||
|
@ -392,7 +386,7 @@ void xf_input_detect_pinch(xfContext* xfc)
|
|||
}
|
||||
}
|
||||
|
||||
void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
static void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -410,7 +404,7 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
|||
}
|
||||
}
|
||||
|
||||
void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
static void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -430,7 +424,7 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
|||
}
|
||||
}
|
||||
|
||||
void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
static void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -446,7 +440,7 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
|||
}
|
||||
}
|
||||
|
||||
int xf_input_handle_event_local(xfContext* xfc, XEvent* event)
|
||||
static int xf_input_handle_event_local(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
XGetEventData(xfc->display, cookie);
|
||||
|
@ -486,7 +480,7 @@ int xf_input_handle_event_local(xfContext* xfc, XEvent* event)
|
|||
return 0;
|
||||
}
|
||||
|
||||
char* xf_input_touch_state_string(DWORD flags)
|
||||
static char* xf_input_touch_state_string(DWORD flags)
|
||||
{
|
||||
if (flags & CONTACT_FLAG_DOWN)
|
||||
return "TouchBegin";
|
||||
|
@ -498,7 +492,7 @@ char* xf_input_touch_state_string(DWORD flags)
|
|||
return "TouchUnknown";
|
||||
}
|
||||
|
||||
void xf_input_hide_cursor(xfContext* xfc)
|
||||
static void xf_input_hide_cursor(xfContext* xfc)
|
||||
{
|
||||
#ifdef WITH_XCURSOR
|
||||
|
||||
|
@ -526,7 +520,7 @@ void xf_input_hide_cursor(xfContext* xfc)
|
|||
#endif
|
||||
}
|
||||
|
||||
void xf_input_show_cursor(xfContext* xfc)
|
||||
static void xf_input_show_cursor(xfContext* xfc)
|
||||
{
|
||||
#ifdef WITH_XCURSOR
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
@ -548,7 +542,7 @@ void xf_input_show_cursor(xfContext* xfc)
|
|||
#endif
|
||||
}
|
||||
|
||||
int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
static int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
{
|
||||
int x, y;
|
||||
int touchId;
|
||||
|
@ -583,7 +577,7 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
static int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
{
|
||||
xf_input_show_cursor(xfc);
|
||||
|
||||
|
@ -608,7 +602,7 @@ int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||
static int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
XGetEventData(xfc->display, cookie);
|
||||
|
|
|
@ -46,13 +46,12 @@
|
|||
static BOOL firstPressRightCtrl = TRUE;
|
||||
static BOOL ungrabKeyboardWithRightCtrl = TRUE;
|
||||
|
||||
BOOL xf_keyboard_action_script_init(xfContext* xfc)
|
||||
static BOOL xf_keyboard_action_script_init(xfContext* xfc)
|
||||
{
|
||||
FILE* keyScript;
|
||||
char* keyCombination;
|
||||
char buffer[1024] = { 0 };
|
||||
char command[1024] = { 0 };
|
||||
|
||||
xfc->actionScriptExists = PathFileExistsA(xfc->context.settings->ActionScript);
|
||||
|
||||
if (!xfc->actionScriptExists)
|
||||
|
@ -91,7 +90,7 @@ BOOL xf_keyboard_action_script_init(xfContext* xfc)
|
|||
return xf_event_action_script_init(xfc);
|
||||
}
|
||||
|
||||
void xf_keyboard_action_script_free(xfContext* xfc)
|
||||
static void xf_keyboard_action_script_free(xfContext* xfc)
|
||||
{
|
||||
xf_event_action_script_free(xfc);
|
||||
|
||||
|
@ -155,9 +154,7 @@ void xf_keyboard_key_release(xfContext* xfc, BYTE keycode, KeySym keysym)
|
|||
return;
|
||||
|
||||
xfc->KeyboardState[keycode] = FALSE;
|
||||
|
||||
xf_keyboard_handle_special_keys_release(xfc, keysym);
|
||||
|
||||
xf_keyboard_send_key(xfc, FALSE, keycode);
|
||||
}
|
||||
|
||||
|
@ -356,7 +353,6 @@ static int xf_keyboard_execute_action_script(xfContext* xfc,
|
|||
{
|
||||
int index;
|
||||
int count;
|
||||
int exitCode;
|
||||
int status = 1;
|
||||
FILE* keyScript;
|
||||
const char* keyStr;
|
||||
|
@ -424,11 +420,13 @@ static int xf_keyboard_execute_action_script(xfContext* xfc,
|
|||
status = 0;
|
||||
}
|
||||
|
||||
exitCode = pclose(keyScript);
|
||||
if (pclose(keyScript) == -1)
|
||||
status = -1;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xk_keyboard_get_modifier_keys(xfContext* xfc, XF_MODIFIER_KEYS* mod)
|
||||
static int xk_keyboard_get_modifier_keys(xfContext* xfc, XF_MODIFIER_KEYS* mod)
|
||||
{
|
||||
mod->LeftShift = xf_keyboard_key_pressed(xfc, XK_Shift_L);
|
||||
mod->RightShift = xf_keyboard_key_pressed(xfc, XK_Shift_R);
|
||||
|
@ -467,7 +465,7 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
|||
if (ungrabKeyboardWithRightCtrl)
|
||||
ungrabKeyboardWithRightCtrl = FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (!xf_keyboard_execute_action_script(xfc, &mod, keysym))
|
||||
{
|
||||
return TRUE;
|
||||
|
@ -581,25 +579,26 @@ void xf_keyboard_handle_special_keys_release(xfContext* xfc, KeySym keysym)
|
|||
{
|
||||
if (keysym != XK_Control_R)
|
||||
return;
|
||||
|
||||
|
||||
firstPressRightCtrl = TRUE;
|
||||
|
||||
|
||||
if (!ungrabKeyboardWithRightCtrl)
|
||||
return;
|
||||
|
||||
|
||||
// all requirements for ungrab are fulfilled, ungrabbing now
|
||||
XF_MODIFIER_KEYS mod = { 0 };
|
||||
xk_keyboard_get_modifier_keys(xfc, &mod);
|
||||
|
||||
|
||||
if (!mod.RightCtrl)
|
||||
{
|
||||
if (!xfc->fullscreen)
|
||||
{
|
||||
xf_toggle_control(xfc);
|
||||
}
|
||||
|
||||
XUngrabKeyboard(xfc->display, CurrentTime);
|
||||
}
|
||||
|
||||
|
||||
// ungrabbed
|
||||
ungrabKeyboardWithRightCtrl = FALSE;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ int xf_list_monitors(xfContext* xfc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
BOOL xf_is_monitor_id_active(xfContext* xfc, UINT32 id)
|
||||
static BOOL xf_is_monitor_id_active(xfContext* xfc, UINT32 id)
|
||||
{
|
||||
int index;
|
||||
rdpSettings* settings = xfc->context.settings;
|
||||
|
|
|
@ -216,7 +216,6 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
|
|||
updateRect.top = extents->top - appWindow->y;
|
||||
updateRect.right = extents->right - appWindow->x;
|
||||
updateRect.bottom = extents->bottom - appWindow->y;
|
||||
|
||||
xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top,
|
||||
updateRect.right - updateRect.left,
|
||||
updateRect.bottom - updateRect.top);
|
||||
|
@ -530,7 +529,6 @@ static BOOL xf_rail_window_delete(rdpContext* context,
|
|||
static BOOL xf_rail_window_icon(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon)
|
||||
{
|
||||
BOOL bigIcon;
|
||||
xfAppWindow* railWindow;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
railWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
|
||||
|
@ -539,8 +537,7 @@ static BOOL xf_rail_window_icon(rdpContext* context,
|
|||
if (!railWindow)
|
||||
return FALSE;
|
||||
|
||||
bigIcon = (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? TRUE : FALSE;
|
||||
return TRUE;
|
||||
return (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_window_cached_icon(rdpContext* context,
|
||||
|
@ -812,7 +809,6 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context,
|
|||
y = localMoveSize->posY;
|
||||
/* FIXME: local keyboard moves not working */
|
||||
return CHANNEL_RC_OK;
|
||||
break;
|
||||
|
||||
case RAIL_WMSZ_KEYSIZE:
|
||||
direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD;
|
||||
|
@ -820,17 +816,12 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context,
|
|||
y = localMoveSize->posY;
|
||||
/* FIXME: local keyboard moves not working */
|
||||
return CHANNEL_RC_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (localMoveSize->isMoveSizeStart)
|
||||
{
|
||||
xf_StartLocalMoveSize(xfc, appWindow, direction, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
xf_EndLocalMoveSize(xfc, appWindow);
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* FreeRDP Client Compatibility
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -94,7 +96,7 @@ BOOL freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32*
|
|||
char* p;
|
||||
|
||||
if (str[0] == '[' && (p = strchr(str, ']'))
|
||||
&& (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':'))))
|
||||
&& (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':'))))
|
||||
{
|
||||
/* Either "[...]" or "[...]:..." with at most one : after the brackets */
|
||||
if (!(*ServerHostname = _strdup(str + 1)))
|
||||
|
@ -120,12 +122,14 @@ BOOL freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32*
|
|||
*ServerPort = atoi(p + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args)
|
||||
{
|
||||
int args_handled = 0;
|
||||
|
||||
if (strcmp(args->argv[0], "cliprdr") == 0)
|
||||
{
|
||||
args_handled++;
|
||||
|
@ -135,12 +139,14 @@ int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args)
|
|||
else if (strcmp(args->argv[0], "rdpdr") == 0)
|
||||
{
|
||||
args_handled++;
|
||||
|
||||
if (args->argc < 2)
|
||||
return 1;
|
||||
|
||||
args_handled++;
|
||||
|
||||
if ((strcmp(args->argv[1], "disk") == 0) ||
|
||||
(strcmp(args->argv[1], "drive") == 0))
|
||||
(strcmp(args->argv[1], "drive") == 0))
|
||||
{
|
||||
freerdp_addin_replace_argument(args, "disk", "drive");
|
||||
freerdp_client_add_device_channel(settings, args->argc - 1, &args->argv[1]);
|
||||
|
@ -150,7 +156,7 @@ int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args)
|
|||
freerdp_client_add_device_channel(settings, args->argc - 1, &args->argv[1]);
|
||||
}
|
||||
else if ((strcmp(args->argv[1], "scard") == 0) ||
|
||||
(strcmp(args->argv[1], "smartcard") == 0))
|
||||
(strcmp(args->argv[1], "smartcard") == 0))
|
||||
{
|
||||
freerdp_addin_replace_argument(args, "scard", "smartcard");
|
||||
freerdp_client_add_device_channel(settings, args->argc - 1, &args->argv[1]);
|
||||
|
@ -172,6 +178,7 @@ int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args)
|
|||
else if (strcmp(args->argv[0], "rdpsnd") == 0)
|
||||
{
|
||||
args_handled++;
|
||||
|
||||
if (args->argc < 2)
|
||||
return 1;
|
||||
|
||||
|
@ -182,10 +189,12 @@ int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args)
|
|||
else if (strcmp(args->argv[0], "rail") == 0)
|
||||
{
|
||||
args_handled++;
|
||||
|
||||
if (args->argc < 2)
|
||||
return 1;
|
||||
|
||||
args_handled++;
|
||||
|
||||
if (!(settings->RemoteApplicationProgram = _strdup(args->argv[1])))
|
||||
return -1;
|
||||
}
|
||||
|
@ -206,17 +215,18 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
|||
if (argv[index][0] != '-')
|
||||
{
|
||||
if ((strcmp(argv[index - 1], "-v") == 0) ||
|
||||
(strcmp(argv[index - 1], "/v") == 0))
|
||||
(strcmp(argv[index - 1], "/v") == 0))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (_stricmp(&(argv[index])[strlen(argv[index])- 4], ".rdp") == 0)
|
||||
|
||||
if (_stricmp(&(argv[index])[strlen(argv[index]) - 4], ".rdp") == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!freerdp_client_old_parse_hostname((char*) argv[index],
|
||||
&settings->ServerHostname, &settings->ServerPort))
|
||||
&settings->ServerHostname, &settings->ServerPort))
|
||||
return -1;
|
||||
|
||||
return 2;
|
||||
|
@ -231,13 +241,11 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
|||
{
|
||||
int args_handled = 0;
|
||||
int length;
|
||||
char *a, *p;
|
||||
char* a, *p;
|
||||
int i, j, t;
|
||||
int old_index;
|
||||
ADDIN_ARGV* args;
|
||||
|
||||
old_index = index;
|
||||
|
||||
index++;
|
||||
t = index;
|
||||
|
||||
|
@ -245,14 +253,18 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
|||
return -1;
|
||||
|
||||
args = (ADDIN_ARGV*) malloc(sizeof(ADDIN_ARGV));
|
||||
|
||||
if (!args)
|
||||
return -1;
|
||||
|
||||
args->argv = (char**) calloc(argc, sizeof(char*));
|
||||
|
||||
if (!args->argv)
|
||||
{
|
||||
free(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
args->argc = 1;
|
||||
|
||||
if ((index < argc - 1) && strcmp("--data", argv[index + 1]) == 0)
|
||||
|
@ -264,6 +276,7 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
|||
{
|
||||
args_handled++;
|
||||
args->argc = 1;
|
||||
|
||||
if (!(args->argv[0] = _strdup(argv[t])))
|
||||
{
|
||||
free(args->argv);
|
||||
|
@ -276,7 +289,6 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
|||
if (*p == '\'')
|
||||
{
|
||||
a = p + 1;
|
||||
|
||||
p = strchr(p + 1, '\'');
|
||||
|
||||
if (p)
|
||||
|
@ -291,9 +303,11 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
|||
{
|
||||
p = strchr(p, ':');
|
||||
}
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
length = (int) (p - a);
|
||||
length = (int)(p - a);
|
||||
|
||||
if (!(args->argv[j + 1] = (char*) malloc(length + 1)))
|
||||
{
|
||||
for (; j >= 0; --j)
|
||||
|
@ -303,6 +317,7 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
|||
free(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CopyMemory(args->argv[j + 1], a, length);
|
||||
args->argv[j + 1][length] = '\0';
|
||||
p++;
|
||||
|
@ -317,7 +332,6 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
|||
free(args->argv);
|
||||
free(args);
|
||||
return -1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,8 +343,9 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
|||
freerdp_client_old_process_plugin(settings, args);
|
||||
}
|
||||
|
||||
for (i = 0; i < args->argc; i++)
|
||||
free(args->argv[i]);
|
||||
for (j = 0; j < args->argc; j++)
|
||||
free(args->argv[j]);
|
||||
|
||||
memset(args->argv, 0, argc * sizeof(char*));
|
||||
index++;
|
||||
i++;
|
||||
|
@ -346,14 +361,14 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
|||
free(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
args_handled = freerdp_client_old_process_plugin(settings, args);
|
||||
free (args->argv[0]);
|
||||
free(args->argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
free(args->argv);
|
||||
free(args);
|
||||
|
||||
return (index - old_index) + args_handled;
|
||||
}
|
||||
|
||||
|
@ -372,22 +387,19 @@ int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count)
|
|||
int detect_status;
|
||||
rdpSettings* settings;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
|
||||
*count = 0;
|
||||
detect_status = 0;
|
||||
flags = COMMAND_LINE_SEPARATOR_SPACE;
|
||||
flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH;
|
||||
flags |= COMMAND_LINE_SIGIL_NOT_ESCAPED;
|
||||
|
||||
settings = (rdpSettings*) calloc(1, sizeof(rdpSettings));
|
||||
|
||||
if (!settings)
|
||||
return -1;
|
||||
|
||||
CommandLineClearArgumentsA(old_args);
|
||||
|
||||
status = CommandLineParseArgumentsA(argc, (const char**) argv, old_args, flags, settings,
|
||||
freerdp_client_old_command_line_pre_filter, NULL);
|
||||
freerdp_client_old_command_line_pre_filter, NULL);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
|
@ -403,24 +415,19 @@ int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count)
|
|||
continue;
|
||||
|
||||
CommandLineSwitchStart(arg)
|
||||
|
||||
CommandLineSwitchCase(arg, "a")
|
||||
{
|
||||
if ((strcmp(arg->Value, "8") == 0) ||
|
||||
(strcmp(arg->Value, "15") == 0) || (strcmp(arg->Value, "16") == 0) ||
|
||||
(strcmp(arg->Value, "24") == 0) || (strcmp(arg->Value, "32") == 0))
|
||||
(strcmp(arg->Value, "15") == 0) || (strcmp(arg->Value, "16") == 0) ||
|
||||
(strcmp(arg->Value, "24") == 0) || (strcmp(arg->Value, "32") == 0))
|
||||
{
|
||||
detect_status = 1;
|
||||
}
|
||||
|
||||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CommandLineSwitchEnd(arg)
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
@ -436,7 +443,6 @@ int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count)
|
|||
|
||||
free(settings->ServerHostname);
|
||||
free(settings);
|
||||
|
||||
return detect_status;
|
||||
}
|
||||
|
||||
|
@ -447,16 +453,13 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
int status;
|
||||
DWORD flags;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
|
||||
freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
|
||||
|
||||
flags = COMMAND_LINE_SEPARATOR_SPACE;
|
||||
flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH;
|
||||
flags |= COMMAND_LINE_SIGIL_ENABLE_DISABLE;
|
||||
flags |= COMMAND_LINE_SIGIL_NOT_ESCAPED;
|
||||
|
||||
status = CommandLineParseArgumentsA(argc, (const char**) argv, old_args, flags, settings,
|
||||
freerdp_client_old_command_line_pre_filter, freerdp_client_old_command_line_post_filter);
|
||||
freerdp_client_old_command_line_pre_filter, freerdp_client_old_command_line_post_filter);
|
||||
|
||||
if (status == COMMAND_LINE_STATUS_PRINT_VERSION)
|
||||
{
|
||||
|
@ -471,8 +474,8 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
{
|
||||
if (status != COMMAND_LINE_STATUS_PRINT_HELP)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
freerdp_client_print_command_line_help(argc, argv);
|
||||
return COMMAND_LINE_STATUS_PRINT_HELP;
|
||||
}
|
||||
|
@ -485,7 +488,6 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
continue;
|
||||
|
||||
CommandLineSwitchStart(arg)
|
||||
|
||||
CommandLineSwitchCase(arg, "0")
|
||||
{
|
||||
settings->ConsoleSession = TRUE;
|
||||
|
@ -499,6 +501,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
CommandLineSwitchCase(arg, "c")
|
||||
{
|
||||
WLog_WARN(TAG, "-c %s -> /shell-dir:%s", arg->Value, arg->Value);
|
||||
|
||||
if (!(settings->ShellWorkingDirectory = _strdup(arg->Value)))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
}
|
||||
|
@ -511,12 +514,14 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
{
|
||||
if (!(settings->WindowTitle = _strdup(arg->Value)))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
|
||||
WLog_WARN(TAG, "-T %s -> /title:%s", arg->Value, arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "d")
|
||||
{
|
||||
if (!(settings->Domain = _strdup(arg->Value)))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
|
||||
WLog_WARN(TAG, "-d %s -> /d:%s", arg->Value, arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "f")
|
||||
|
@ -540,7 +545,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
|
||||
free(str);
|
||||
WLog_WARN(TAG, "-g %s -> /size:%s or /w:%"PRIu32" /h:%"PRIu32"", arg->Value, arg->Value,
|
||||
settings->DesktopWidth, settings->DesktopHeight);
|
||||
settings->DesktopWidth, settings->DesktopHeight);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "k")
|
||||
{
|
||||
|
@ -556,6 +561,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
{
|
||||
if (!(settings->ClientHostname = _strdup(arg->Value)))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
|
||||
WLog_WARN(TAG, "-n -> /client-hostname:%s", arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "o")
|
||||
|
@ -567,6 +573,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
{
|
||||
if (!(settings->Password = _strdup(arg->Value)))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
|
||||
WLog_WARN(TAG, "-p ****** -> /p:******");
|
||||
/* Hide the value from 'ps'. */
|
||||
FillMemory(arg->Value, strlen(arg->Value), '*');
|
||||
|
@ -575,6 +582,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
{
|
||||
if (!(settings->AlternateShell = _strdup(arg->Value)))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
|
||||
WLog_WARN(TAG, "-s %s -> /shell:%s", arg->Value, arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "t")
|
||||
|
@ -586,13 +594,13 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
{
|
||||
if (!(settings->Username = _strdup(arg->Value)))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
|
||||
WLog_WARN(TAG, "-u %s -> /u:%s", arg->Value, arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "x")
|
||||
{
|
||||
int type;
|
||||
char* pEnd;
|
||||
|
||||
type = strtol(arg->Value, &pEnd, 16);
|
||||
|
||||
if (type == 0)
|
||||
|
@ -642,7 +650,6 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
}
|
||||
CommandLineSwitchCase(arg, "ext")
|
||||
{
|
||||
|
||||
}
|
||||
CommandLineSwitchCase(arg, "no-auth")
|
||||
{
|
||||
|
@ -737,7 +744,6 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
}
|
||||
CommandLineSwitchCase(arg, "ntlm")
|
||||
{
|
||||
|
||||
}
|
||||
CommandLineSwitchCase(arg, "ignore-certificate")
|
||||
{
|
||||
|
@ -789,9 +795,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
|||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CommandLineSwitchEnd(arg)
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
|
|
@ -521,7 +521,7 @@ static BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, const BYTE
|
|||
char* type;
|
||||
char* context;
|
||||
char* d1, *d2;
|
||||
char* beg, *end;
|
||||
char* beg;
|
||||
char* name, *value;
|
||||
char* copy = calloc(1, size + sizeof(BYTE));
|
||||
|
||||
|
@ -539,7 +539,6 @@ static BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, const BYTE
|
|||
if (length > 1)
|
||||
{
|
||||
beg = line;
|
||||
end = &line[length - 1];
|
||||
|
||||
if (!freerdp_client_parse_rdp_file_add_line_ascii(file, line, index))
|
||||
return FALSE;
|
||||
|
@ -1354,12 +1353,13 @@ const char* freerdp_client_rdp_file_get_string_option(rdpFile* file, const char*
|
|||
int freerdp_client_rdp_file_set_integer_option(rdpFile* file, const char* name, int value)
|
||||
{
|
||||
int index;
|
||||
int length;
|
||||
char* text;
|
||||
rdpFileLine* line;
|
||||
line = freerdp_client_rdp_file_find_line_by_name(file, name);
|
||||
length = _scprintf("%s:i:%d", name, value);
|
||||
text = (char*) malloc(length + 1);
|
||||
const int length = _scprintf("%s:i:%d", name, value);
|
||||
char* text = (char*) malloc(length + 1);
|
||||
rdpFileLine* line = freerdp_client_rdp_file_find_line_by_name(file, name);
|
||||
|
||||
if (!text)
|
||||
return -1;
|
||||
|
||||
sprintf_s(text, length + 1, "%s:i:%d", name, value);
|
||||
text[length] = '\0';
|
||||
|
||||
|
@ -1379,7 +1379,11 @@ int freerdp_client_rdp_file_set_integer_option(rdpFile* file, const char* name,
|
|||
return -1;
|
||||
}
|
||||
|
||||
line = freerdp_client_rdp_file_find_line_index(file, index);
|
||||
if (!freerdp_client_rdp_file_find_line_index(file, index))
|
||||
{
|
||||
free(text);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (freerdp_client_rdp_file_set_integer(file, (char*) name, value, index) < 0)
|
||||
{
|
||||
|
|
|
@ -74,14 +74,12 @@ static BOOL update_process_glyph(rdpContext* context, const BYTE* data,
|
|||
INT32 sx = 0, sy = 0;
|
||||
INT32 dx, dy;
|
||||
rdpGlyph* glyph;
|
||||
rdpGraphics* graphics;
|
||||
rdpGlyphCache* glyph_cache;
|
||||
|
||||
if (!context || !data || !x || !y || !context->graphics
|
||||
|| !context->cache || !context->cache->glyph)
|
||||
return FALSE;
|
||||
|
||||
graphics = context->graphics;
|
||||
glyph_cache = context->cache->glyph;
|
||||
glyph = glyph_cache_get(glyph_cache, cacheId, cacheIndex);
|
||||
|
||||
|
@ -289,14 +287,11 @@ static BOOL update_process_glyph_fragments(rdpContext* context,
|
|||
static BOOL update_gdi_glyph_index(rdpContext* context,
|
||||
GLYPH_INDEX_ORDER* glyphIndex)
|
||||
{
|
||||
rdpGlyphCache* glyph_cache;
|
||||
INT32 bkWidth = 0, bkHeight = 0, opWidth = 0, opHeight = 0;
|
||||
|
||||
if (!context || !glyphIndex || !context->cache)
|
||||
return FALSE;
|
||||
|
||||
glyph_cache = context->cache->glyph;
|
||||
|
||||
if (glyphIndex->bkRight > glyphIndex->bkLeft)
|
||||
bkWidth = glyphIndex->bkRight - glyphIndex->bkLeft + 1;
|
||||
|
||||
|
@ -324,14 +319,12 @@ static BOOL update_gdi_fast_index(rdpContext* context,
|
|||
INT32 x, y;
|
||||
INT32 opLeft, opTop;
|
||||
INT32 opRight, opBottom;
|
||||
rdpGlyphCache* glyph_cache;
|
||||
INT32 opWidth = 0, opHeight = 0;
|
||||
INT32 bkWidth = 0, bkHeight = 0;
|
||||
|
||||
if (!context || !fastIndex || !context->cache)
|
||||
return FALSE;
|
||||
|
||||
glyph_cache = context->cache->glyph;
|
||||
opLeft = fastIndex->opLeft;
|
||||
opTop = fastIndex->opTop;
|
||||
opRight = fastIndex->opRight;
|
||||
|
|
|
@ -81,7 +81,6 @@ int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** p
|
|||
UINT32 LengthOfMatch;
|
||||
UINT32 accumulator;
|
||||
BYTE* HistoryPtr;
|
||||
UINT32 HistoryOffset;
|
||||
BYTE* HistoryBuffer;
|
||||
BYTE* HistoryBufferEnd;
|
||||
UINT32 HistoryBufferSize;
|
||||
|
@ -108,7 +107,6 @@ int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** p
|
|||
}
|
||||
|
||||
HistoryPtr = mppc->HistoryPtr;
|
||||
HistoryOffset = mppc->HistoryOffset;
|
||||
|
||||
if (!(flags & PACKET_COMPRESSED))
|
||||
{
|
||||
|
@ -159,8 +157,6 @@ int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** p
|
|||
/**
|
||||
* CopyOffset Encoding
|
||||
*/
|
||||
CopyOffset = 0;
|
||||
|
||||
if (CompressionLevel) /* RDP5 */
|
||||
{
|
||||
if ((accumulator & 0xF8000000) == 0xF8000000)
|
||||
|
@ -244,7 +240,6 @@ int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** p
|
|||
/**
|
||||
* LengthOfMatch Encoding
|
||||
*/
|
||||
LengthOfMatch = 0;
|
||||
accumulator = bs->accumulator;
|
||||
|
||||
if ((accumulator & 0x80000000) == 0x00000000)
|
||||
|
@ -419,7 +414,6 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppD
|
|||
{
|
||||
BYTE* pSrcPtr;
|
||||
BYTE* pSrcEnd;
|
||||
BYTE* pDstEnd;
|
||||
BYTE* MatchPtr;
|
||||
UINT32 DstSize;
|
||||
BYTE* pDstData;
|
||||
|
@ -439,7 +433,6 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppD
|
|||
HistoryBuffer = mppc->HistoryBuffer;
|
||||
HistoryBufferSize = mppc->HistoryBufferSize;
|
||||
CompressionLevel = mppc->CompressionLevel;
|
||||
HistoryPtr = mppc->HistoryPtr;
|
||||
HistoryOffset = mppc->HistoryOffset;
|
||||
*pFlags = 0;
|
||||
PacketFlushed = FALSE;
|
||||
|
@ -471,7 +464,6 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppD
|
|||
BitStream_Attach(bs, pDstData, DstSize);
|
||||
pSrcPtr = pSrcData;
|
||||
pSrcEnd = &(pSrcData[SrcSize - 1]);
|
||||
pDstEnd = &(pDstData[DstSize - 1]);
|
||||
|
||||
while (pSrcPtr < (pSrcEnd - 2))
|
||||
{
|
||||
|
|
|
@ -1134,7 +1134,7 @@ BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context,
|
|||
if (!freerdp_bitmap_planar_delta_encode_planes(
|
||||
context->planes, width, height,
|
||||
context->deltaPlanes))
|
||||
return NULL;;
|
||||
return NULL;
|
||||
|
||||
if (freerdp_bitmap_planar_compress_planes_rle(
|
||||
context->deltaPlanes, width, height,
|
||||
|
@ -1150,7 +1150,6 @@ BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context,
|
|||
context->rlePlanes[2] = &context->rlePlanesBuffer[offset];
|
||||
offset += dstSizes[2];
|
||||
context->rlePlanes[3] = &context->rlePlanesBuffer[offset];
|
||||
offset += dstSizes[3];
|
||||
//WLog_DBG(TAG, "R: [%"PRIu32"/%"PRIu32"] G: [%"PRIu32"/%"PRIu32"] B: [%"PRIu32"/%"PRIu32"]",
|
||||
// dstSizes[1], planeSize, dstSizes[2], planeSize, dstSizes[3], planeSize);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,20 @@
|
|||
|
||||
#define TAG FREERDP_TAG("codec.progressive")
|
||||
|
||||
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;
|
||||
|
||||
static const char* progressive_get_block_type_string(UINT16 blockType)
|
||||
{
|
||||
switch (blockType)
|
||||
|
@ -539,19 +553,16 @@ static INLINE void progressive_rfx_idwt_y(INT16* pLowBand, int nLowStep,
|
|||
*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
|
||||
|
@ -566,9 +577,7 @@ static INLINE void progressive_rfx_idwt_y(INT16* pLowBand, int nLowStep,
|
|||
*pX = X0;
|
||||
pX += nDstStep;
|
||||
L0 = *pL;
|
||||
pL += nLowStep;
|
||||
*pX = (X0 + L0) / 2;
|
||||
pX += nDstStep;
|
||||
}
|
||||
|
||||
pLowBand++;
|
||||
|
@ -620,14 +629,12 @@ static INLINE void progressive_rfx_dwt_2d_decode_block(INT16* buffer, INT16* tem
|
|||
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;
|
||||
|
@ -852,20 +859,6 @@ static INLINE int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progres
|
|||
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;
|
||||
|
||||
static INLINE INT16 progressive_rfx_srl_read(RFX_PROGRESSIVE_UPGRADE_STATE* state,
|
||||
UINT32 numBits)
|
||||
{
|
||||
|
@ -984,13 +977,11 @@ static INLINE int progressive_rfx_upgrade_block(RFX_PROGRESSIVE_UPGRADE_STATE* s
|
|||
{
|
||||
int index;
|
||||
INT16 input;
|
||||
wBitStream* srl;
|
||||
wBitStream* raw;
|
||||
|
||||
if (!numBits)
|
||||
return 1;
|
||||
|
||||
srl = state->srl;
|
||||
raw = state->raw;
|
||||
|
||||
if (!state->nonLL)
|
||||
|
@ -1931,7 +1922,7 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive,
|
|||
int progressive_compress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData,
|
||||
UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize)
|
||||
{
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOL progressive_context_reset(PROGRESSIVE_CONTEXT* progressive)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* Copyright 2014 Thincast Technologies GmbH
|
||||
* Copyright 2014 Hardening <contact@hardening-consulting.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -66,52 +68,52 @@
|
|||
* rectangles in the same places (of the same width, of course).
|
||||
*/
|
||||
|
||||
struct _REGION16_DATA {
|
||||
struct _REGION16_DATA
|
||||
{
|
||||
long size;
|
||||
long nbRects;
|
||||
};
|
||||
|
||||
static REGION16_DATA empty_region = { 0, 0 };
|
||||
|
||||
void region16_init(REGION16 *region)
|
||||
void region16_init(REGION16* region)
|
||||
{
|
||||
assert(region);
|
||||
|
||||
ZeroMemory(region, sizeof(REGION16));
|
||||
region->data = &empty_region;
|
||||
}
|
||||
|
||||
int region16_n_rects(const REGION16 *region)
|
||||
int region16_n_rects(const REGION16* region)
|
||||
{
|
||||
assert(region);
|
||||
assert(region->data);
|
||||
|
||||
return region->data->nbRects;
|
||||
}
|
||||
|
||||
const RECTANGLE_16 *region16_rects(const REGION16 *region, UINT32 *nbRects)
|
||||
{
|
||||
REGION16_DATA *data;
|
||||
|
||||
assert(region);
|
||||
|
||||
data = region->data;
|
||||
if (!data)
|
||||
{
|
||||
if (nbRects)
|
||||
*nbRects = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nbRects)
|
||||
*nbRects = data->nbRects;
|
||||
return (RECTANGLE_16 *)(data + 1);
|
||||
}
|
||||
|
||||
static INLINE RECTANGLE_16 *region16_rects_noconst(REGION16 *region)
|
||||
const RECTANGLE_16* region16_rects(const REGION16* region, UINT32* nbRects)
|
||||
{
|
||||
REGION16_DATA* data;
|
||||
|
||||
if (nbRects)
|
||||
*nbRects = 0;
|
||||
|
||||
if (!region)
|
||||
return NULL;
|
||||
|
||||
data = region->data;
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
if (nbRects)
|
||||
*nbRects = data->nbRects;
|
||||
|
||||
return (RECTANGLE_16*)(data + 1);
|
||||
}
|
||||
|
||||
static INLINE RECTANGLE_16* region16_rects_noconst(REGION16* region)
|
||||
{
|
||||
REGION16_DATA* data;
|
||||
data = region->data;
|
||||
|
||||
if (!data)
|
||||
|
@ -120,17 +122,23 @@ static INLINE RECTANGLE_16 *region16_rects_noconst(REGION16 *region)
|
|||
return (RECTANGLE_16*)(&data[1]);
|
||||
}
|
||||
|
||||
const RECTANGLE_16 *region16_extents(const REGION16 *region)
|
||||
const RECTANGLE_16* region16_extents(const REGION16* region)
|
||||
{
|
||||
if (!region)
|
||||
return NULL;
|
||||
|
||||
return ®ion->extents;
|
||||
}
|
||||
|
||||
static RECTANGLE_16 *region16_extents_noconst(REGION16 *region)
|
||||
static RECTANGLE_16* region16_extents_noconst(REGION16* region)
|
||||
{
|
||||
if (!region)
|
||||
return NULL;
|
||||
|
||||
return ®ion->extents;
|
||||
}
|
||||
|
||||
BOOL rectangle_is_empty(const RECTANGLE_16 *rect)
|
||||
BOOL rectangle_is_empty(const RECTANGLE_16* rect)
|
||||
{
|
||||
/* A rectangle with width = 0 or height = 0 should be regarded
|
||||
* as empty.
|
||||
|
@ -138,38 +146,36 @@ BOOL rectangle_is_empty(const RECTANGLE_16 *rect)
|
|||
return ((rect->left == rect->right) || (rect->top == rect->bottom)) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
BOOL region16_is_empty(const REGION16 *region)
|
||||
BOOL region16_is_empty(const REGION16* region)
|
||||
{
|
||||
assert(region);
|
||||
assert(region->data);
|
||||
|
||||
return (region->data->nbRects == 0);
|
||||
}
|
||||
|
||||
BOOL rectangles_equal(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2)
|
||||
BOOL rectangles_equal(const RECTANGLE_16* r1, const RECTANGLE_16* r2)
|
||||
{
|
||||
return ((r1->left == r2->left) && (r1->top == r2->top) &&
|
||||
(r1->right == r2->right) && (r1->bottom == r2->bottom)) ? TRUE : FALSE;
|
||||
(r1->right == r2->right) && (r1->bottom == r2->bottom)) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
BOOL rectangles_intersects(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2)
|
||||
BOOL rectangles_intersects(const RECTANGLE_16* r1, const RECTANGLE_16* r2)
|
||||
{
|
||||
RECTANGLE_16 tmp;
|
||||
return rectangles_intersection(r1, r2, &tmp);
|
||||
}
|
||||
|
||||
BOOL rectangles_intersection(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2,
|
||||
RECTANGLE_16 *dst)
|
||||
BOOL rectangles_intersection(const RECTANGLE_16* r1, const RECTANGLE_16* r2,
|
||||
RECTANGLE_16* dst)
|
||||
{
|
||||
dst->left = MAX(r1->left, r2->left);
|
||||
dst->right = MIN(r1->right, r2->right);
|
||||
dst->top = MAX(r1->top, r2->top);
|
||||
dst->bottom = MIN(r1->bottom, r2->bottom);
|
||||
|
||||
return (dst->left < dst->right) && (dst->top < dst->bottom);
|
||||
}
|
||||
|
||||
void region16_clear(REGION16 *region)
|
||||
void region16_clear(REGION16* region)
|
||||
{
|
||||
assert(region);
|
||||
assert(region->data);
|
||||
|
@ -178,14 +184,12 @@ void region16_clear(REGION16 *region)
|
|||
free(region->data);
|
||||
|
||||
region->data = &empty_region;
|
||||
|
||||
ZeroMemory(®ion->extents, sizeof(region->extents));
|
||||
}
|
||||
|
||||
static INLINE REGION16_DATA* allocateRegion(long nbItems)
|
||||
{
|
||||
long allocSize = sizeof(REGION16_DATA) + (nbItems * sizeof(RECTANGLE_16));
|
||||
|
||||
REGION16_DATA* ret = (REGION16_DATA*) malloc(allocSize);
|
||||
|
||||
if (!ret)
|
||||
|
@ -193,11 +197,10 @@ static INLINE REGION16_DATA* allocateRegion(long nbItems)
|
|||
|
||||
ret->size = allocSize;
|
||||
ret->nbRects = nbItems;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL region16_copy(REGION16 *dst, const REGION16 *src)
|
||||
BOOL region16_copy(REGION16* dst, const REGION16* src)
|
||||
{
|
||||
assert(dst);
|
||||
assert(dst->data);
|
||||
|
@ -229,12 +232,11 @@ BOOL region16_copy(REGION16 *dst, const REGION16 *src)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void region16_print(const REGION16 *region)
|
||||
void region16_print(const REGION16* region)
|
||||
{
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects, i;
|
||||
int currentBandY = -1;
|
||||
|
||||
rects = region16_rects(region, &nbRects);
|
||||
WLog_DBG(TAG, "nrects=%"PRIu32"", nbRects);
|
||||
|
||||
|
@ -246,19 +248,20 @@ void region16_print(const REGION16 *region)
|
|||
WLog_DBG(TAG, "band %d: ", currentBandY);
|
||||
}
|
||||
|
||||
WLog_DBG(TAG, "(%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16")", rects->left, rects->top, rects->right, rects->bottom);
|
||||
WLog_DBG(TAG, "(%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16")", rects->left, rects->top, rects->right,
|
||||
rects->bottom);
|
||||
}
|
||||
}
|
||||
|
||||
static void region16_copy_band_with_union(RECTANGLE_16 *dst,
|
||||
const RECTANGLE_16 *src, const RECTANGLE_16 *end,
|
||||
UINT16 newTop, UINT16 newBottom,
|
||||
const RECTANGLE_16 *unionRect,
|
||||
UINT32 *dstCounter,
|
||||
const RECTANGLE_16 **srcPtr, RECTANGLE_16 **dstPtr)
|
||||
static void region16_copy_band_with_union(RECTANGLE_16* dst,
|
||||
const RECTANGLE_16* src, const RECTANGLE_16* end,
|
||||
UINT16 newTop, UINT16 newBottom,
|
||||
const RECTANGLE_16* unionRect,
|
||||
UINT32* dstCounter,
|
||||
const RECTANGLE_16** srcPtr, RECTANGLE_16** dstPtr)
|
||||
{
|
||||
UINT16 refY = src->top;
|
||||
const RECTANGLE_16 *startOverlap, *endOverlap;
|
||||
const RECTANGLE_16* startOverlap, *endOverlap;
|
||||
|
||||
/* merges a band with the given rect
|
||||
* Input:
|
||||
|
@ -293,8 +296,9 @@ static void region16_copy_band_with_union(RECTANGLE_16 *dst,
|
|||
dst->bottom = newBottom;
|
||||
dst->right = src->right;
|
||||
dst->left = src->left;
|
||||
|
||||
src++; dst++; *dstCounter += 1;
|
||||
src++;
|
||||
dst++;
|
||||
*dstCounter += 1;
|
||||
}
|
||||
|
||||
/* treat items overlapping with unionRect */
|
||||
|
@ -319,7 +323,8 @@ static void region16_copy_band_with_union(RECTANGLE_16 *dst,
|
|||
dst->top = newTop;
|
||||
dst->left = startOverlap->left;
|
||||
dst->right = endOverlap->right;
|
||||
dst++; *dstCounter += 1;
|
||||
dst++;
|
||||
*dstCounter += 1;
|
||||
}
|
||||
|
||||
/* treat remaining items on the same band */
|
||||
|
@ -329,8 +334,9 @@ static void region16_copy_band_with_union(RECTANGLE_16 *dst,
|
|||
dst->bottom = newBottom;
|
||||
dst->right = src->right;
|
||||
dst->left = src->left;
|
||||
|
||||
src++; dst++; *dstCounter += 1;
|
||||
src++;
|
||||
dst++;
|
||||
*dstCounter += 1;
|
||||
}
|
||||
|
||||
if (srcPtr)
|
||||
|
@ -342,10 +348,9 @@ static void region16_copy_band_with_union(RECTANGLE_16 *dst,
|
|||
static RECTANGLE_16* next_band(RECTANGLE_16* band1, RECTANGLE_16* endPtr, int* nbItems)
|
||||
{
|
||||
UINT16 refY = band1->top;
|
||||
|
||||
*nbItems = 0;
|
||||
|
||||
while((band1 < endPtr) && (band1->top == refY))
|
||||
while ((band1 < endPtr) && (band1->top == refY))
|
||||
{
|
||||
band1++;
|
||||
*nbItems += 1;
|
||||
|
@ -380,8 +385,8 @@ static BOOL band_match(const RECTANGLE_16* band1, const RECTANGLE_16* band2, REC
|
|||
* @param rect the rectangle to test
|
||||
* @return if rect is fully included in an item of the band
|
||||
*/
|
||||
static BOOL rectangle_contained_in_band(const RECTANGLE_16 *band, const RECTANGLE_16 *endPtr,
|
||||
const RECTANGLE_16 *rect)
|
||||
static BOOL rectangle_contained_in_band(const RECTANGLE_16* band, const RECTANGLE_16* endPtr,
|
||||
const RECTANGLE_16* rect)
|
||||
{
|
||||
UINT16 refY = band->top;
|
||||
|
||||
|
@ -391,17 +396,18 @@ static BOOL rectangle_contained_in_band(const RECTANGLE_16 *band, const RECTANGL
|
|||
/* note: as the band is sorted from left to right, once we've seen an item
|
||||
* that is after rect->left we're sure that the result is False.
|
||||
*/
|
||||
while( (band < endPtr) && (band->top == refY) && (band->left <= rect->left))
|
||||
while ((band < endPtr) && (band->top == refY) && (band->left <= rect->left))
|
||||
{
|
||||
if (rect->right <= band->right)
|
||||
return TRUE;
|
||||
|
||||
band++;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL region16_simplify_bands(REGION16 *region)
|
||||
static BOOL region16_simplify_bands(REGION16* region)
|
||||
{
|
||||
/** Simplify consecutive bands that touch and have the same items
|
||||
*
|
||||
|
@ -414,10 +420,9 @@ BOOL region16_simplify_bands(REGION16 *region)
|
|||
* ==================== ====================
|
||||
*
|
||||
*/
|
||||
RECTANGLE_16 *band1, *band2, *endPtr, *endBand, *tmp;
|
||||
RECTANGLE_16* band1, *band2, *endPtr, *endBand, *tmp;
|
||||
int nbRects, finalNbRects;
|
||||
int bandItems, toMove;
|
||||
|
||||
finalNbRects = nbRects = region16_n_rects(region);
|
||||
|
||||
if (nbRects < 2)
|
||||
|
@ -437,6 +442,7 @@ BOOL region16_simplify_bands(REGION16 *region)
|
|||
{
|
||||
/* adjust the bottom of band1 items */
|
||||
tmp = band1;
|
||||
|
||||
while (tmp < band2)
|
||||
{
|
||||
tmp->bottom = band2->bottom;
|
||||
|
@ -459,7 +465,7 @@ BOOL region16_simplify_bands(REGION16 *region)
|
|||
band1 = band2;
|
||||
}
|
||||
}
|
||||
while(TRUE);
|
||||
while (TRUE);
|
||||
|
||||
if (finalNbRects != nbRects)
|
||||
{
|
||||
|
@ -479,20 +485,18 @@ BOOL region16_simplify_bands(REGION16 *region)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *rect)
|
||||
BOOL region16_union_rect(REGION16* dst, const REGION16* src, const RECTANGLE_16* rect)
|
||||
{
|
||||
const RECTANGLE_16* srcExtents;
|
||||
RECTANGLE_16* dstExtents;
|
||||
const RECTANGLE_16 *currentBand, *endSrcRect, *nextBand;
|
||||
const RECTANGLE_16* currentBand, *endSrcRect, *nextBand;
|
||||
REGION16_DATA* newItems = NULL;
|
||||
RECTANGLE_16* dstRect = NULL;
|
||||
UINT32 usedRects, srcNbRects;
|
||||
UINT16 topInterBand;
|
||||
|
||||
assert(src);
|
||||
assert(src->data);
|
||||
assert(dst);
|
||||
|
||||
srcExtents = region16_extents(src);
|
||||
dstExtents = region16_extents_noconst(dst);
|
||||
|
||||
|
@ -506,12 +510,10 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
return FALSE;
|
||||
|
||||
dstRect = region16_rects_noconst(dst);
|
||||
|
||||
dstRect->top = rect->top;
|
||||
dstRect->left = rect->left;
|
||||
dstRect->right = rect->right;
|
||||
dstRect->bottom = rect->bottom;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -520,7 +522,7 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
if (!newItems)
|
||||
return FALSE;
|
||||
|
||||
dstRect = (RECTANGLE_16*) (&newItems[1]);
|
||||
dstRect = (RECTANGLE_16*)(&newItems[1]);
|
||||
usedRects = 0;
|
||||
|
||||
/* adds the piece of rect that is on the top of src */
|
||||
|
@ -530,7 +532,6 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
dstRect->left = rect->left;
|
||||
dstRect->right = rect->right;
|
||||
dstRect->bottom = MIN(srcExtents->top, rect->bottom);
|
||||
|
||||
usedRects++;
|
||||
dstRect++;
|
||||
}
|
||||
|
@ -542,7 +543,7 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
while (currentBand < endSrcRect)
|
||||
{
|
||||
if ((currentBand->bottom <= rect->top) || (rect->bottom <= currentBand->top) ||
|
||||
rectangle_contained_in_band(currentBand, endSrcRect, rect))
|
||||
rectangle_contained_in_band(currentBand, endSrcRect, rect))
|
||||
{
|
||||
/* no overlap between rect and the band, rect is totally below or totally above
|
||||
* the current band, or rect is already covered by an item of the band.
|
||||
|
@ -552,33 +553,32 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
+----+
|
||||
|
||||
=================
|
||||
band of srcRect
|
||||
=================
|
||||
+----+
|
||||
| | rect (case 2)
|
||||
+----+
|
||||
*/
|
||||
band of srcRect
|
||||
=================
|
||||
+----+
|
||||
| | rect (case 2)
|
||||
+----+
|
||||
*/
|
||||
region16_copy_band_with_union(dstRect,
|
||||
currentBand, endSrcRect,
|
||||
currentBand->top, currentBand->bottom,
|
||||
NULL, &usedRects,
|
||||
&nextBand, &dstRect);
|
||||
currentBand, endSrcRect,
|
||||
currentBand->top, currentBand->bottom,
|
||||
NULL, &usedRects,
|
||||
&nextBand, &dstRect);
|
||||
topInterBand = rect->top;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* rect overlaps the band:
|
||||
| | | |
|
||||
====^=================| |==| |=========================== band
|
||||
| top split | | | |
|
||||
v | 1 | | 2 |
|
||||
^ | | | | +----+ +----+
|
||||
| merge zone | | | | | | | 4 |
|
||||
v +----+ | | | | +----+
|
||||
^ | | | 3 |
|
||||
| bottom split | | | |
|
||||
====v=========================| |==| |===================
|
||||
====^=================| |==| |=========================== band
|
||||
| top split | | | |
|
||||
v | 1 | | 2 |
|
||||
^ | | | | +----+ +----+
|
||||
| merge zone | | | | | | | 4 |
|
||||
v +----+ | | | | +----+
|
||||
^ | | | 3 |
|
||||
| bottom split | | | |
|
||||
====v=========================| |==| |===================
|
||||
| | | |
|
||||
|
||||
possible cases:
|
||||
|
@ -597,10 +597,10 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
if (rect->top > currentBand->top)
|
||||
{
|
||||
region16_copy_band_with_union(dstRect,
|
||||
currentBand, endSrcRect,
|
||||
currentBand->top, rect->top,
|
||||
NULL, &usedRects,
|
||||
&nextBand, &dstRect);
|
||||
currentBand, endSrcRect,
|
||||
currentBand->top, rect->top,
|
||||
NULL, &usedRects,
|
||||
&nextBand, &dstRect);
|
||||
mergeTop = rect->top;
|
||||
}
|
||||
|
||||
|
@ -609,20 +609,21 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
mergeBottom = rect->bottom;
|
||||
|
||||
region16_copy_band_with_union(dstRect,
|
||||
currentBand, endSrcRect,
|
||||
mergeTop, mergeBottom,
|
||||
rect, &usedRects,
|
||||
&nextBand, &dstRect);
|
||||
currentBand, endSrcRect,
|
||||
mergeTop, mergeBottom,
|
||||
rect, &usedRects,
|
||||
&nextBand, &dstRect);
|
||||
|
||||
/* test if we need a bottom split, case 1 and 4 */
|
||||
if (rect->bottom < currentBand->bottom)
|
||||
{
|
||||
region16_copy_band_with_union(dstRect,
|
||||
currentBand, endSrcRect,
|
||||
mergeBottom, currentBand->bottom,
|
||||
NULL, &usedRects,
|
||||
&nextBand, &dstRect);
|
||||
currentBand, endSrcRect,
|
||||
mergeBottom, currentBand->bottom,
|
||||
NULL, &usedRects,
|
||||
&nextBand, &dstRect);
|
||||
}
|
||||
|
||||
topInterBand = currentBand->bottom;
|
||||
}
|
||||
|
||||
|
@ -642,13 +643,14 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
*
|
||||
*/
|
||||
if ((nextBand < endSrcRect) && (nextBand->top != currentBand->bottom) &&
|
||||
(rect->bottom > currentBand->bottom) && (rect->top < nextBand->top))
|
||||
(rect->bottom > currentBand->bottom) && (rect->top < nextBand->top))
|
||||
{
|
||||
dstRect->right = rect->right;
|
||||
dstRect->left = rect->left;
|
||||
dstRect->top = topInterBand;
|
||||
dstRect->bottom = MIN(nextBand->top, rect->bottom);
|
||||
dstRect++; usedRects++;
|
||||
dstRect++;
|
||||
usedRects++;
|
||||
}
|
||||
|
||||
currentBand = nextBand;
|
||||
|
@ -661,7 +663,6 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
dstRect->left = rect->left;
|
||||
dstRect->right = rect->right;
|
||||
dstRect->bottom = rect->bottom;
|
||||
|
||||
usedRects++;
|
||||
dstRect++;
|
||||
}
|
||||
|
@ -673,7 +674,6 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
dstExtents->left = MIN(rect->left, srcExtents->left);
|
||||
dstExtents->bottom = MAX(rect->bottom, srcExtents->bottom);
|
||||
dstExtents->right = MAX(rect->right, srcExtents->right);
|
||||
|
||||
newItems->size = sizeof(REGION16_DATA) + (usedRects * sizeof(RECTANGLE_16));
|
||||
dst->data = realloc(newItems, newItems->size);
|
||||
|
||||
|
@ -684,17 +684,16 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16
|
|||
}
|
||||
|
||||
dst->data->nbRects = usedRects;
|
||||
|
||||
return region16_simplify_bands(dst);
|
||||
}
|
||||
|
||||
BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2)
|
||||
BOOL region16_intersects_rect(const REGION16* src, const RECTANGLE_16* arg2)
|
||||
{
|
||||
const RECTANGLE_16 *rect, *endPtr, *srcExtents;
|
||||
const RECTANGLE_16* rect, *endPtr, *srcExtents;
|
||||
UINT32 nbRects;
|
||||
|
||||
assert(src);
|
||||
assert(src->data);
|
||||
if (!src || !src->data || !arg2)
|
||||
return FALSE;
|
||||
|
||||
rect = region16_rects(src, &nbRects);
|
||||
|
||||
|
@ -709,8 +708,6 @@ BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2)
|
|||
if (!rectangles_intersects(srcExtents, arg2))
|
||||
return FALSE;
|
||||
|
||||
endPtr = rect + nbRects;
|
||||
|
||||
for (endPtr = rect + nbRects; (rect < endPtr) && (arg2->bottom > rect->top); rect++)
|
||||
{
|
||||
if (rectangles_intersects(rect, arg2))
|
||||
|
@ -720,17 +717,15 @@ BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *rect)
|
||||
BOOL region16_intersect_rect(REGION16* dst, const REGION16* src, const RECTANGLE_16* rect)
|
||||
{
|
||||
REGION16_DATA *newItems;
|
||||
const RECTANGLE_16 *srcPtr, *endPtr, *srcExtents;
|
||||
RECTANGLE_16 *dstPtr;
|
||||
REGION16_DATA* newItems;
|
||||
const RECTANGLE_16* srcPtr, *endPtr, *srcExtents;
|
||||
RECTANGLE_16* dstPtr;
|
||||
UINT32 nbRects, usedRects;
|
||||
RECTANGLE_16 common, newExtents;
|
||||
|
||||
assert(src);
|
||||
assert(src->data);
|
||||
|
||||
srcPtr = region16_rects(src, &nbRects);
|
||||
|
||||
if (!nbRects)
|
||||
|
@ -744,7 +739,6 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE
|
|||
if (nbRects == 1)
|
||||
{
|
||||
BOOL intersects = rectangles_intersection(srcExtents, rect, &common);
|
||||
|
||||
region16_clear(dst);
|
||||
|
||||
if (intersects)
|
||||
|
@ -758,7 +752,7 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE
|
|||
if (!newItems)
|
||||
return FALSE;
|
||||
|
||||
dstPtr = (RECTANGLE_16*) (&newItems[1]);
|
||||
dstPtr = (RECTANGLE_16*)(&newItems[1]);
|
||||
usedRects = 0;
|
||||
ZeroMemory(&newExtents, sizeof(newExtents));
|
||||
|
||||
|
@ -809,7 +803,7 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE
|
|||
return region16_simplify_bands(dst);
|
||||
}
|
||||
|
||||
void region16_uninit(REGION16 *region)
|
||||
void region16_uninit(REGION16* region)
|
||||
{
|
||||
assert(region);
|
||||
|
||||
|
|
|
@ -49,11 +49,12 @@
|
|||
do { _val = _mm_min_epi16(_max, _mm_max_epi16(_val, _min)); } while (0)
|
||||
|
||||
static __inline void __attribute__((ATTRIBUTES))
|
||||
_mm_prefetch_buffer(char * buffer, int num_bytes)
|
||||
_mm_prefetch_buffer(char* buffer, int num_bytes)
|
||||
{
|
||||
__m128i * buf = (__m128i*) buffer;
|
||||
__m128i* buf = (__m128i*) buffer;
|
||||
unsigned int i;
|
||||
for (i = 0; i < (num_bytes / sizeof(__m128i)); i+=(CACHE_LINE_BYTES / sizeof(__m128i)))
|
||||
|
||||
for (i = 0; i < (num_bytes / sizeof(__m128i)); i += (CACHE_LINE_BYTES / sizeof(__m128i)))
|
||||
{
|
||||
_mm_prefetch((char*)(&buf[i]), _MM_HINT_NTA);
|
||||
}
|
||||
|
@ -66,8 +67,8 @@ static __inline void __attribute__((ATTRIBUTES))
|
|||
rfx_quantization_decode_block_sse2(INT16* buffer, const int buffer_size, const UINT32 factor)
|
||||
{
|
||||
__m128i a;
|
||||
__m128i * ptr = (__m128i*) buffer;
|
||||
__m128i * buf_end = (__m128i*) (buffer + buffer_size);
|
||||
__m128i* ptr = (__m128i*) buffer;
|
||||
__m128i* buf_end = (__m128i*)(buffer + buffer_size);
|
||||
|
||||
if (factor == 0)
|
||||
return;
|
||||
|
@ -77,15 +78,14 @@ rfx_quantization_decode_block_sse2(INT16* buffer, const int buffer_size, const U
|
|||
a = _mm_load_si128(ptr);
|
||||
a = _mm_slli_epi16(a, factor);
|
||||
_mm_store_si128(ptr, a);
|
||||
|
||||
ptr++;
|
||||
} while(ptr < buf_end);
|
||||
}
|
||||
while (ptr < buf_end);
|
||||
}
|
||||
|
||||
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[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 */
|
||||
|
@ -103,28 +103,28 @@ rfx_quantization_encode_block_sse2(INT16* buffer, const int buffer_size, const U
|
|||
{
|
||||
__m128i a;
|
||||
__m128i* ptr = (__m128i*) buffer;
|
||||
__m128i* buf_end = (__m128i*) (buffer + buffer_size);
|
||||
__m128i* buf_end = (__m128i*)(buffer + buffer_size);
|
||||
__m128i half;
|
||||
|
||||
if (factor == 0)
|
||||
return;
|
||||
|
||||
half = _mm_set1_epi16(1 << (factor - 1));
|
||||
|
||||
do
|
||||
{
|
||||
a = _mm_load_si128(ptr);
|
||||
a = _mm_add_epi16(a, half);
|
||||
a = _mm_srai_epi16(a, factor);
|
||||
_mm_store_si128(ptr, a);
|
||||
|
||||
ptr++;
|
||||
} while(ptr < buf_end);
|
||||
}
|
||||
while (ptr < buf_end);
|
||||
}
|
||||
|
||||
static void rfx_quantization_encode_sse2(INT16* buffer, const UINT32* quantization_values)
|
||||
{
|
||||
_mm_prefetch_buffer((char*) buffer, 4096 * sizeof(INT16));
|
||||
|
||||
rfx_quantization_encode_block_sse2(buffer, 1024, quantization_values[8] - 6); /* HL1 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
|
||||
|
@ -135,7 +135,6 @@ static void rfx_quantization_encode_sse2(INT16* buffer, const UINT32* quantizati
|
|||
rfx_quantization_encode_block_sse2(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
|
||||
|
||||
rfx_quantization_encode_block_sse2(buffer, 4096, 5);
|
||||
}
|
||||
|
||||
|
@ -163,62 +162,50 @@ rfx_dwt_2d_decode_block_horiz_sse2(INT16* l, INT16* h, INT16* dst, int subband_w
|
|||
for (n = 0; n < subband_width; n += 8)
|
||||
{
|
||||
/* dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); */
|
||||
|
||||
l_n = _mm_load_si128((__m128i*) l_ptr);
|
||||
|
||||
h_n = _mm_load_si128((__m128i*) h_ptr);
|
||||
h_n_m = _mm_loadu_si128((__m128i*) (h_ptr - 1));
|
||||
h_n_m = _mm_loadu_si128((__m128i*)(h_ptr - 1));
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
first = _mm_extract_epi16(h_n_m, 1);
|
||||
h_n_m = _mm_insert_epi16(h_n_m, first, 0);
|
||||
}
|
||||
|
||||
|
||||
tmp_n = _mm_add_epi16(h_n, h_n_m);
|
||||
tmp_n = _mm_add_epi16(tmp_n, _mm_set1_epi16(1));
|
||||
tmp_n = _mm_srai_epi16(tmp_n, 1);
|
||||
|
||||
dst_n = _mm_sub_epi16(l_n, tmp_n);
|
||||
|
||||
_mm_store_si128((__m128i*) l_ptr, dst_n);
|
||||
|
||||
l_ptr += 8;
|
||||
h_ptr += 8;
|
||||
}
|
||||
|
||||
l_ptr -= subband_width;
|
||||
h_ptr -= subband_width;
|
||||
|
||||
|
||||
/* Odd coefficients */
|
||||
for (n = 0; n < subband_width; n += 8)
|
||||
{
|
||||
/* dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); */
|
||||
|
||||
h_n = _mm_load_si128((__m128i*) h_ptr);
|
||||
|
||||
h_n = _mm_slli_epi16(h_n, 1);
|
||||
|
||||
dst_n = _mm_load_si128((__m128i*) (l_ptr));
|
||||
dst_n_p = _mm_loadu_si128((__m128i*) (l_ptr + 1));
|
||||
dst_n = _mm_load_si128((__m128i*)(l_ptr));
|
||||
dst_n_p = _mm_loadu_si128((__m128i*)(l_ptr + 1));
|
||||
|
||||
if (n == subband_width - 8)
|
||||
{
|
||||
last = _mm_extract_epi16(dst_n_p, 6);
|
||||
dst_n_p = _mm_insert_epi16(dst_n_p, last, 7);
|
||||
}
|
||||
|
||||
|
||||
tmp_n = _mm_add_epi16(dst_n_p, dst_n);
|
||||
tmp_n = _mm_srai_epi16(tmp_n, 1);
|
||||
|
||||
tmp_n = _mm_add_epi16(tmp_n, h_n);
|
||||
|
||||
dst1 = _mm_unpacklo_epi16(dst_n, tmp_n);
|
||||
dst2 = _mm_unpackhi_epi16(dst_n, tmp_n);
|
||||
|
||||
_mm_store_si128((__m128i*) dst_ptr, dst1);
|
||||
_mm_store_si128((__m128i*) (dst_ptr + 8), dst2);
|
||||
|
||||
_mm_store_si128((__m128i*)(dst_ptr + 8), dst2);
|
||||
l_ptr += 8;
|
||||
h_ptr += 8;
|
||||
dst_ptr += 16;
|
||||
|
@ -240,98 +227,88 @@ rfx_dwt_2d_decode_block_vert_sse2(INT16* l, INT16* h, INT16* dst, int subband_wi
|
|||
__m128i dst_n;
|
||||
__m128i dst_n_m;
|
||||
__m128i dst_n_p;
|
||||
|
||||
int total_width = subband_width + subband_width;
|
||||
|
||||
/* Even coefficients */
|
||||
for (n = 0; n < subband_width; n++)
|
||||
{
|
||||
for (x = 0; x < total_width; x+=8)
|
||||
for (x = 0; x < total_width; x += 8)
|
||||
{
|
||||
/* dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); */
|
||||
|
||||
l_n = _mm_load_si128((__m128i*) l_ptr);
|
||||
h_n = _mm_load_si128((__m128i*) h_ptr);
|
||||
|
||||
tmp_n = _mm_add_epi16(h_n, _mm_set1_epi16(1));;
|
||||
tmp_n = _mm_add_epi16(h_n, _mm_set1_epi16(1));
|
||||
|
||||
if (n == 0)
|
||||
tmp_n = _mm_add_epi16(tmp_n, h_n);
|
||||
else
|
||||
{
|
||||
h_n_m = _mm_loadu_si128((__m128i*) (h_ptr - total_width));
|
||||
h_n_m = _mm_loadu_si128((__m128i*)(h_ptr - total_width));
|
||||
tmp_n = _mm_add_epi16(tmp_n, h_n_m);
|
||||
}
|
||||
|
||||
tmp_n = _mm_srai_epi16(tmp_n, 1);
|
||||
|
||||
dst_n = _mm_sub_epi16(l_n, tmp_n);
|
||||
_mm_store_si128((__m128i*) dst_ptr, dst_n);
|
||||
|
||||
l_ptr+=8;
|
||||
h_ptr+=8;
|
||||
dst_ptr+=8;
|
||||
l_ptr += 8;
|
||||
h_ptr += 8;
|
||||
dst_ptr += 8;
|
||||
}
|
||||
dst_ptr+=total_width;
|
||||
|
||||
dst_ptr += total_width;
|
||||
}
|
||||
|
||||
|
||||
h_ptr = h;
|
||||
dst_ptr = dst + total_width;
|
||||
|
||||
|
||||
/* Odd coefficients */
|
||||
for (n = 0; n < subband_width; n++)
|
||||
{
|
||||
for (x = 0; x < total_width; x+=8)
|
||||
for (x = 0; x < total_width; x += 8)
|
||||
{
|
||||
/* dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); */
|
||||
|
||||
h_n = _mm_load_si128((__m128i*) h_ptr);
|
||||
dst_n_m = _mm_load_si128((__m128i*) (dst_ptr - total_width));
|
||||
dst_n_m = _mm_load_si128((__m128i*)(dst_ptr - total_width));
|
||||
h_n = _mm_slli_epi16(h_n, 1);
|
||||
|
||||
tmp_n = dst_n_m;
|
||||
|
||||
if (n == subband_width - 1)
|
||||
tmp_n = _mm_add_epi16(tmp_n, dst_n_m);
|
||||
else
|
||||
{
|
||||
dst_n_p = _mm_loadu_si128((__m128i*) (dst_ptr + total_width));
|
||||
dst_n_p = _mm_loadu_si128((__m128i*)(dst_ptr + total_width));
|
||||
tmp_n = _mm_add_epi16(tmp_n, dst_n_p);
|
||||
}
|
||||
|
||||
tmp_n = _mm_srai_epi16(tmp_n, 1);
|
||||
|
||||
dst_n = _mm_add_epi16(tmp_n, h_n);
|
||||
_mm_store_si128((__m128i*) dst_ptr, dst_n);
|
||||
|
||||
h_ptr+=8;
|
||||
dst_ptr+=8;
|
||||
h_ptr += 8;
|
||||
dst_ptr += 8;
|
||||
}
|
||||
dst_ptr+=total_width;
|
||||
|
||||
dst_ptr += total_width;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void __attribute__((ATTRIBUTES))
|
||||
rfx_dwt_2d_decode_block_sse2(INT16* buffer, INT16* idwt, int subband_width)
|
||||
{
|
||||
INT16 *hl, *lh, *hh, *ll;
|
||||
INT16 *l_dst, *h_dst;
|
||||
|
||||
INT16* hl, *lh, *hh, *ll;
|
||||
INT16* l_dst, *h_dst;
|
||||
_mm_prefetch_buffer((char*) idwt, subband_width * 4 * sizeof(INT16));
|
||||
|
||||
/* Inverse DWT in horizontal direction, results in 2 sub-bands in L, H order in tmp buffer idwt. */
|
||||
/* The 4 sub-bands are stored in HL(0), LH(1), HH(2), LL(3) order. */
|
||||
/* The lower part L uses LL(3) and HL(0). */
|
||||
/* The higher part H uses LH(1) and HH(2). */
|
||||
|
||||
ll = buffer + subband_width * subband_width * 3;
|
||||
hl = buffer;
|
||||
l_dst = idwt;
|
||||
|
||||
rfx_dwt_2d_decode_block_horiz_sse2(ll, hl, l_dst, subband_width);
|
||||
|
||||
lh = buffer + subband_width * subband_width;
|
||||
hh = buffer + subband_width * subband_width * 2;
|
||||
h_dst = idwt + subband_width * subband_width * 2;
|
||||
|
||||
rfx_dwt_2d_decode_block_horiz_sse2(lh, hh, h_dst, subband_width);
|
||||
|
||||
/* Inverse DWT in vertical direction, results are stored in original buffer. */
|
||||
rfx_dwt_2d_decode_block_vert_sse2(l_dst, h_dst, buffer, subband_width);
|
||||
}
|
||||
|
@ -339,7 +316,6 @@ rfx_dwt_2d_decode_block_sse2(INT16* buffer, INT16* idwt, int subband_width)
|
|||
static void rfx_dwt_2d_decode_sse2(INT16* buffer, INT16* dwt_buffer)
|
||||
{
|
||||
_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[0], dwt_buffer, 32);
|
||||
|
@ -357,7 +333,6 @@ rfx_dwt_2d_encode_block_vert_sse2(INT16* src, INT16* l, INT16* h, int subband_wi
|
|||
__m128i h_n;
|
||||
__m128i h_n_m;
|
||||
__m128i l_n;
|
||||
|
||||
total_width = subband_width << 1;
|
||||
|
||||
for (n = 0; n < subband_width; n++)
|
||||
|
@ -365,38 +340,35 @@ rfx_dwt_2d_encode_block_vert_sse2(INT16* src, INT16* l, INT16* h, int subband_wi
|
|||
for (x = 0; x < total_width; x += 8)
|
||||
{
|
||||
src_2n = _mm_load_si128((__m128i*) src);
|
||||
src_2n_1 = _mm_load_si128((__m128i*) (src + total_width));
|
||||
src_2n_1 = _mm_load_si128((__m128i*)(src + total_width));
|
||||
|
||||
if (n < subband_width - 1)
|
||||
src_2n_2 = _mm_load_si128((__m128i*) (src + 2 * total_width));
|
||||
src_2n_2 = _mm_load_si128((__m128i*)(src + 2 * total_width));
|
||||
else
|
||||
src_2n_2 = src_2n;
|
||||
|
||||
/* h[n] = (src[2n + 1] - ((src[2n] + src[2n + 2]) >> 1)) >> 1 */
|
||||
|
||||
h_n = _mm_add_epi16(src_2n, src_2n_2);
|
||||
h_n = _mm_srai_epi16(h_n, 1);
|
||||
h_n = _mm_sub_epi16(src_2n_1, h_n);
|
||||
h_n = _mm_srai_epi16(h_n, 1);
|
||||
|
||||
_mm_store_si128((__m128i*) h, h_n);
|
||||
|
||||
if (n == 0)
|
||||
h_n_m = h_n;
|
||||
else
|
||||
h_n_m = _mm_load_si128((__m128i*) (h - total_width));
|
||||
h_n_m = _mm_load_si128((__m128i*)(h - total_width));
|
||||
|
||||
/* l[n] = src[2n] + ((h[n - 1] + h[n]) >> 1) */
|
||||
|
||||
l_n = _mm_add_epi16(h_n_m, h_n);
|
||||
l_n = _mm_srai_epi16(l_n, 1);
|
||||
l_n = _mm_add_epi16(l_n, src_2n);
|
||||
|
||||
_mm_store_si128((__m128i*) l, l_n);
|
||||
|
||||
src += 8;
|
||||
l += 8;
|
||||
h += 8;
|
||||
}
|
||||
|
||||
src += total_width;
|
||||
}
|
||||
}
|
||||
|
@ -422,18 +394,15 @@ rfx_dwt_2d_encode_block_horiz_sse2(INT16* src, INT16* l, INT16* h, int subband_w
|
|||
src_2n = _mm_set_epi16(src[14], src[12], src[10], src[8], src[6], src[4], src[2], src[0]);
|
||||
src_2n_1 = _mm_set_epi16(src[15], src[13], src[11], src[9], src[7], src[5], src[3], src[1]);
|
||||
src_2n_2 = _mm_set_epi16(n == subband_width - 8 ? src[14] : src[16],
|
||||
src[14], src[12], src[10], src[8], src[6], src[4], src[2]);
|
||||
|
||||
src[14], src[12], src[10], src[8], src[6], src[4], src[2]);
|
||||
/* h[n] = (src[2n + 1] - ((src[2n] + src[2n + 2]) >> 1)) >> 1 */
|
||||
|
||||
h_n = _mm_add_epi16(src_2n, src_2n_2);
|
||||
h_n = _mm_srai_epi16(h_n, 1);
|
||||
h_n = _mm_sub_epi16(src_2n_1, h_n);
|
||||
h_n = _mm_srai_epi16(h_n, 1);
|
||||
|
||||
_mm_store_si128((__m128i*) h, h_n);
|
||||
h_n_m = _mm_loadu_si128((__m128i*)(h - 1));
|
||||
|
||||
h_n_m = _mm_loadu_si128((__m128i*) (h - 1));
|
||||
if (n == 0)
|
||||
{
|
||||
first = _mm_extract_epi16(h_n_m, 1);
|
||||
|
@ -441,13 +410,10 @@ rfx_dwt_2d_encode_block_horiz_sse2(INT16* src, INT16* l, INT16* h, int subband_w
|
|||
}
|
||||
|
||||
/* l[n] = src[2n] + ((h[n - 1] + h[n]) >> 1) */
|
||||
|
||||
l_n = _mm_add_epi16(h_n_m, h_n);
|
||||
l_n = _mm_srai_epi16(l_n, 1);
|
||||
l_n = _mm_add_epi16(l_n, src_2n);
|
||||
|
||||
_mm_store_si128((__m128i*) l, l_n);
|
||||
|
||||
src += 16;
|
||||
l += 8;
|
||||
h += 8;
|
||||
|
@ -458,28 +424,20 @@ rfx_dwt_2d_encode_block_horiz_sse2(INT16* src, INT16* l, INT16* h, int subband_w
|
|||
static __inline void __attribute__((ATTRIBUTES))
|
||||
rfx_dwt_2d_encode_block_sse2(INT16* buffer, INT16* dwt, int subband_width)
|
||||
{
|
||||
INT16 *hl, *lh, *hh, *ll;
|
||||
INT16 *l_src, *h_src;
|
||||
|
||||
INT16* hl, *lh, *hh, *ll;
|
||||
INT16* l_src, *h_src;
|
||||
_mm_prefetch_buffer((char*) dwt, subband_width * 4 * sizeof(INT16));
|
||||
|
||||
/* DWT in vertical direction, results in 2 sub-bands in L, H order in tmp buffer dwt. */
|
||||
|
||||
l_src = dwt;
|
||||
h_src = dwt + subband_width * subband_width * 2;
|
||||
|
||||
rfx_dwt_2d_encode_block_vert_sse2(buffer, l_src, h_src, subband_width);
|
||||
|
||||
/* DWT in horizontal direction, results in 4 sub-bands in HL(0), LH(1), HH(2), LL(3) order, stored in original buffer. */
|
||||
/* The lower part L generates LL(3) and HL(0). */
|
||||
/* The higher part H generates LH(1) and HH(2). */
|
||||
|
||||
ll = buffer + subband_width * subband_width * 3;
|
||||
hl = buffer;
|
||||
|
||||
lh = buffer + subband_width * subband_width;
|
||||
hh = buffer + subband_width * subband_width * 2;
|
||||
|
||||
rfx_dwt_2d_encode_block_horiz_sse2(l_src, ll, hl, subband_width);
|
||||
rfx_dwt_2d_encode_block_horiz_sse2(h_src, lh, hh, subband_width);
|
||||
}
|
||||
|
@ -487,7 +445,6 @@ rfx_dwt_2d_encode_block_sse2(INT16* buffer, INT16* dwt, int subband_width)
|
|||
static void rfx_dwt_2d_encode_sse2(INT16* buffer, INT16* dwt_buffer)
|
||||
{
|
||||
_mm_prefetch_buffer((char*) buffer, 4096 * sizeof(INT16));
|
||||
|
||||
rfx_dwt_2d_encode_block_sse2(buffer, dwt_buffer, 32);
|
||||
rfx_dwt_2d_encode_block_sse2(buffer + 3072, dwt_buffer, 16);
|
||||
rfx_dwt_2d_encode_block_sse2(buffer + 3840, dwt_buffer, 8);
|
||||
|
@ -502,7 +459,6 @@ void rfx_init_sse2(RFX_CONTEXT* context)
|
|||
IF_PROFILER(context->priv->prof_rfx_quantization_encode->name = "rfx_quantization_encode_sse2");
|
||||
IF_PROFILER(context->priv->prof_rfx_dwt_2d_decode->name = "rfx_dwt_2d_decode_sse2");
|
||||
IF_PROFILER(context->priv->prof_rfx_dwt_2d_encode->name = "rfx_dwt_2d_encode_sse2");
|
||||
|
||||
context->quantization_decode = rfx_quantization_decode_sse2;
|
||||
context->quantization_encode = rfx_quantization_encode_sse2;
|
||||
context->dwt_2d_decode = rfx_dwt_2d_decode_sse2;
|
||||
|
|
|
@ -23,58 +23,65 @@
|
|||
#include <freerdp/codec/region.h>
|
||||
|
||||
|
||||
static BOOL compareRectangles(const RECTANGLE_16 *src1, const RECTANGLE_16 *src2, int nb)
|
||||
static BOOL compareRectangles(const RECTANGLE_16* src1, const RECTANGLE_16* src2, int nb)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i< nb; i++, src1++, src2++)
|
||||
|
||||
for (i = 0; i < nb; i++, src1++, src2++)
|
||||
{
|
||||
if (memcmp(src1, src2, sizeof(RECTANGLE_16)))
|
||||
{
|
||||
fprintf(stderr, "expecting rect %d (%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16") and have (%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16")\n",
|
||||
i, src2->left, src2->top, src2->right, src2->bottom,
|
||||
src1->left, src1->top, src1->right, src1->bottom
|
||||
);
|
||||
fprintf(stderr,
|
||||
"expecting rect %d (%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16") and have (%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16")\n",
|
||||
i, src2->left, src2->top, src2->right, src2->bottom,
|
||||
src1->left, src1->top, src1->right, src1->bottom
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static int test_basic(void) {
|
||||
static int test_basic(void)
|
||||
{
|
||||
REGION16 region;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
UINT32 nbRects;
|
||||
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
/* R1 + R2 ==> disjointed rects */
|
||||
RECTANGLE_16 r1 = { 0, 101, 200, 201};
|
||||
RECTANGLE_16 r2 = {150, 301, 250, 401};
|
||||
|
||||
RECTANGLE_16 r1_r2[] = {
|
||||
RECTANGLE_16 r1_r2[] =
|
||||
{
|
||||
{0, 101, 200, 201},
|
||||
{150, 301, 250, 401}
|
||||
};
|
||||
|
||||
/* r1 */
|
||||
region16_init(®ion);
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;;
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 1 || memcmp(rects, &r1, sizeof(RECTANGLE_16)))
|
||||
goto out;
|
||||
|
||||
/* r1 + r2 */
|
||||
if (!region16_union_rect(®ion, ®ion, &r2))
|
||||
goto out;;
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2, nbRects))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2, nbRects))
|
||||
goto out;
|
||||
|
||||
/* clear region */
|
||||
region16_clear(®ion);
|
||||
region16_rects(®ion, &nbRects);
|
||||
|
||||
if (nbRects)
|
||||
goto out;
|
||||
|
||||
|
@ -85,20 +92,20 @@ out:
|
|||
}
|
||||
|
||||
|
||||
static int test_r1_r3(void) {
|
||||
static int test_r1_r3(void)
|
||||
{
|
||||
REGION16 region;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
|
||||
RECTANGLE_16 r1 = { 0, 101, 200, 201};
|
||||
RECTANGLE_16 r3 = {150, 151, 250, 251};
|
||||
RECTANGLE_16 r1_r3[] = {
|
||||
RECTANGLE_16 r1_r3[] =
|
||||
{
|
||||
{ 0, 101, 200, 151},
|
||||
{ 0, 151, 250, 201},
|
||||
{150, 201, 250, 251}
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
/*
|
||||
* +===============================================================
|
||||
|
@ -115,20 +122,26 @@ static int test_r1_r3(void) {
|
|||
/* R1 + R3 */
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r3))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects))
|
||||
goto out;
|
||||
|
||||
|
||||
/* R3 + R1 */
|
||||
region16_clear(®ion);
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r3))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects))
|
||||
goto out;
|
||||
|
||||
|
@ -139,12 +152,12 @@ out:
|
|||
}
|
||||
|
||||
|
||||
static int test_r9_r10(void) {
|
||||
static int test_r9_r10(void)
|
||||
{
|
||||
REGION16 region;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
|
||||
/*
|
||||
* +===============================================================
|
||||
* |
|
||||
|
@ -160,18 +173,22 @@ static int test_r9_r10(void) {
|
|||
*/
|
||||
RECTANGLE_16 r9 = { 0, 100, 400, 200};
|
||||
RECTANGLE_16 r10 = {200, 0, 300, 300};
|
||||
RECTANGLE_16 r9_r10[] = {
|
||||
{200, 0, 300, 100},
|
||||
{ 0, 100, 400, 200},
|
||||
{200, 200, 300, 300},
|
||||
RECTANGLE_16 r9_r10[] =
|
||||
{
|
||||
{200, 0, 300, 100},
|
||||
{ 0, 100, 400, 200},
|
||||
{200, 200, 300, 300},
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r9))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r10))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 3 || !compareRectangles(rects, r9_r10, nbRects))
|
||||
goto out;
|
||||
|
||||
|
@ -182,22 +199,22 @@ out:
|
|||
}
|
||||
|
||||
|
||||
static int test_r1_r5(void) {
|
||||
static int test_r1_r5(void)
|
||||
{
|
||||
REGION16 region;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
|
||||
RECTANGLE_16 r1 = { 0, 101, 200, 201};
|
||||
RECTANGLE_16 r5 = {150, 121, 300, 131};
|
||||
|
||||
RECTANGLE_16 r1_r5[] = {
|
||||
RECTANGLE_16 r1_r5[] =
|
||||
{
|
||||
{ 0, 101, 200, 121},
|
||||
{ 0, 121, 300, 131},
|
||||
{ 0, 131, 200, 201}
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
|
||||
/*
|
||||
* +===============================================================
|
||||
* |
|
||||
|
@ -213,28 +230,29 @@ static int test_r1_r5(void) {
|
|||
*/
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r5))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r5, nbRects))
|
||||
goto out;
|
||||
|
||||
|
||||
retCode = 0;
|
||||
out:
|
||||
region16_uninit(®ion);
|
||||
return retCode;
|
||||
}
|
||||
|
||||
static int test_r1_r6(void) {
|
||||
static int test_r1_r6(void)
|
||||
{
|
||||
REGION16 region;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
|
||||
RECTANGLE_16 r1 = { 0, 101, 200, 201};
|
||||
RECTANGLE_16 r6 = {150, 121, 170, 131};
|
||||
|
||||
region16_init(®ion);
|
||||
/*
|
||||
* +===============================================================
|
||||
|
@ -249,11 +267,15 @@ static int test_r1_r6(void) {
|
|||
* |
|
||||
*/
|
||||
region16_clear(®ion);
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r6))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 1 || !compareRectangles(rects, &r1, nbRects))
|
||||
goto out;
|
||||
|
||||
|
@ -264,19 +286,20 @@ out:
|
|||
}
|
||||
|
||||
|
||||
static int test_r1_r2_r4(void) {
|
||||
static int test_r1_r2_r4(void)
|
||||
{
|
||||
REGION16 region;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
RECTANGLE_16 r1 = { 0, 101, 200, 201};
|
||||
RECTANGLE_16 r2 = {150, 301, 250, 401};
|
||||
RECTANGLE_16 r4 = {150, 251, 250, 301};
|
||||
RECTANGLE_16 r1_r2_r4[] = {
|
||||
RECTANGLE_16 r1_r2_r4[] =
|
||||
{
|
||||
{ 0, 101, 200, 201},
|
||||
{150, 251, 250, 401}
|
||||
};
|
||||
|
||||
/*
|
||||
* +===============================================================
|
||||
* |
|
||||
|
@ -295,13 +318,18 @@ static int test_r1_r2_r4(void) {
|
|||
*
|
||||
*/
|
||||
region16_init(®ion);
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r2))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r4))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2_r4, nbRects))
|
||||
goto out;
|
||||
|
||||
|
@ -312,23 +340,23 @@ out:
|
|||
}
|
||||
|
||||
|
||||
static int test_r1_r7_r8(void) {
|
||||
static int test_r1_r7_r8(void)
|
||||
{
|
||||
REGION16 region;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
RECTANGLE_16 r1 = { 0, 101, 200, 201};
|
||||
RECTANGLE_16 r7 = {300, 101, 500, 201};
|
||||
RECTANGLE_16 r8 = {150, 121, 400, 131};
|
||||
|
||||
RECTANGLE_16 r1_r7_r8[] = {
|
||||
RECTANGLE_16 r1_r7_r8[] =
|
||||
{
|
||||
{ 0, 101, 200, 121},
|
||||
{300, 101, 500, 121},
|
||||
{ 0, 121, 500, 131},
|
||||
{ 0, 131, 200, 201},
|
||||
{300, 131, 500, 201},
|
||||
};
|
||||
|
||||
/*
|
||||
* +===============================================================
|
||||
* |
|
||||
|
@ -342,35 +370,50 @@ static int test_r1_r7_r8(void) {
|
|||
* |
|
||||
*/
|
||||
region16_init(®ion);
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r7))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r8))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects))
|
||||
goto out;
|
||||
|
||||
region16_clear(®ion);
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r8))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r7))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects))
|
||||
goto out;
|
||||
|
||||
region16_clear(®ion);
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r8))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r7))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects))
|
||||
goto out;
|
||||
|
||||
|
@ -381,30 +424,31 @@ out:
|
|||
}
|
||||
|
||||
|
||||
static int test_r1_r2_r3_r4(void) {
|
||||
static int test_r1_r2_r3_r4(void)
|
||||
{
|
||||
REGION16 region;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
RECTANGLE_16 r1 = { 0, 101, 200, 201};
|
||||
RECTANGLE_16 r2 = {150, 301, 250, 401};
|
||||
RECTANGLE_16 r3 = {150, 151, 250, 251};
|
||||
RECTANGLE_16 r4 = {150, 251, 250, 301};
|
||||
|
||||
RECTANGLE_16 r1_r2_r3[] = {
|
||||
RECTANGLE_16 r1_r2_r3[] =
|
||||
{
|
||||
{ 0, 101, 200, 151},
|
||||
{ 0, 151, 250, 201},
|
||||
{150, 201, 250, 251},
|
||||
{150, 301, 250, 401}
|
||||
};
|
||||
|
||||
RECTANGLE_16 r1_r2_r3_r4[] = {
|
||||
RECTANGLE_16 r1_r2_r3_r4[] =
|
||||
{
|
||||
{ 0, 101, 200, 151},
|
||||
{ 0, 151, 250, 201},
|
||||
{150, 201, 250, 401}
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
|
||||
/*
|
||||
* +===============================================================
|
||||
* |
|
||||
|
@ -422,11 +466,15 @@ static int test_r1_r2_r3_r4(void) {
|
|||
*/
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r2))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r3))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 4 || !compareRectangles(rects, r1_r2_r3, 4))
|
||||
goto out;
|
||||
|
||||
|
@ -448,7 +496,9 @@ static int test_r1_r2_r3_r4(void) {
|
|||
*/
|
||||
if (!region16_union_rect(®ion, ®ion, &r4))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3_r4, 3))
|
||||
goto out;
|
||||
|
||||
|
@ -468,19 +518,19 @@ static int test_from_weston(void)
|
|||
*/
|
||||
REGION16 region;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
RECTANGLE_16 r1 = { 0, 0, 640, 32};
|
||||
RECTANGLE_16 r2 = {236, 169, 268, 201};
|
||||
RECTANGLE_16 r3 = {246, 258, 278, 290};
|
||||
|
||||
RECTANGLE_16 r1_r2_r3[] = {
|
||||
{ 0, 0, 640, 32},
|
||||
{236, 169, 268, 201},
|
||||
{246, 258, 278, 290}
|
||||
RECTANGLE_16 r1_r2_r3[] =
|
||||
{
|
||||
{ 0, 0, 640, 32},
|
||||
{236, 169, 268, 201},
|
||||
{246, 258, 278, 290}
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
|
||||
/*
|
||||
* +===============================================================
|
||||
* |+-------------------------------------------------------------+
|
||||
|
@ -498,12 +548,15 @@ static int test_from_weston(void)
|
|||
*/
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r2))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r3))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(®ion, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3, 3))
|
||||
goto out;
|
||||
|
||||
|
@ -513,18 +566,18 @@ out:
|
|||
return retCode;
|
||||
}
|
||||
|
||||
static int test_r1_inter_r3(void) {
|
||||
static int test_r1_inter_r3(void)
|
||||
{
|
||||
REGION16 region, intersection;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
RECTANGLE_16 r1 = { 0, 101, 200, 201};
|
||||
RECTANGLE_16 r3 = {150, 151, 250, 251};
|
||||
|
||||
RECTANGLE_16 r1_inter_r3[] = {
|
||||
RECTANGLE_16 r1_inter_r3[] =
|
||||
{
|
||||
{150, 151, 200, 201},
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
region16_init(&intersection);
|
||||
|
||||
|
@ -541,35 +594,37 @@ static int test_r1_inter_r3(void) {
|
|||
*/
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
if (!region16_intersects_rect(®ion, &r3))
|
||||
goto out;
|
||||
|
||||
if (!region16_intersect_rect(&intersection, ®ion, &r3))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(&intersection, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 1 || !compareRectangles(rects, r1_inter_r3, nbRects))
|
||||
goto out;
|
||||
|
||||
|
||||
retCode = 0;
|
||||
out:
|
||||
region16_uninit(®ion);
|
||||
return retCode;
|
||||
}
|
||||
|
||||
static int test_r1_r3_inter_r11(void) {
|
||||
static int test_r1_r3_inter_r11(void)
|
||||
{
|
||||
REGION16 region, intersection;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects;
|
||||
RECTANGLE_16 r1 = { 0, 101, 200, 201};
|
||||
RECTANGLE_16 r3 = {150, 151, 250, 251};
|
||||
RECTANGLE_16 r11 ={170, 151, 600, 301};
|
||||
|
||||
RECTANGLE_16 r1_r3_inter_r11[] = {
|
||||
RECTANGLE_16 r11 = {170, 151, 600, 301};
|
||||
RECTANGLE_16 r1_r3_inter_r11[] =
|
||||
{
|
||||
{170, 151, 250, 251},
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
region16_init(&intersection);
|
||||
|
||||
|
@ -595,6 +650,7 @@ static int test_r1_r3_inter_r11(void) {
|
|||
*/
|
||||
if (!region16_union_rect(®ion, ®ion, &r1))
|
||||
goto out;
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &r3))
|
||||
goto out;
|
||||
|
||||
|
@ -603,7 +659,9 @@ static int test_r1_r3_inter_r11(void) {
|
|||
|
||||
if (!region16_intersect_rect(&intersection, ®ion, &r11))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(&intersection, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 1 || !compareRectangles(rects, r1_r3_inter_r11, nbRects))
|
||||
goto out;
|
||||
|
||||
|
@ -614,27 +672,28 @@ out:
|
|||
return retCode;
|
||||
}
|
||||
|
||||
static int test_norbert_case(void) {
|
||||
static int test_norbert_case(void)
|
||||
{
|
||||
REGION16 region, intersection;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects, i;
|
||||
|
||||
RECTANGLE_16 inRectangles[5] = {
|
||||
{1680, 0, 1920, 242},
|
||||
{ 294, 242, 971, 776},
|
||||
{1680, 242, 1920, 776},
|
||||
{1680, 776, 1920, 1036},
|
||||
{ 2, 1040, 53, 1078}
|
||||
RECTANGLE_16 inRectangles[5] =
|
||||
{
|
||||
{1680, 0, 1920, 242},
|
||||
{ 294, 242, 971, 776},
|
||||
{1680, 242, 1920, 776},
|
||||
{1680, 776, 1920, 1036},
|
||||
{ 2, 1040, 53, 1078}
|
||||
};
|
||||
|
||||
RECTANGLE_16 screenRect = {
|
||||
RECTANGLE_16 screenRect =
|
||||
{
|
||||
0, 0, 1920, 1080
|
||||
};
|
||||
RECTANGLE_16 expected_inter_extents = {
|
||||
RECTANGLE_16 expected_inter_extents =
|
||||
{
|
||||
2, 0, 1920, 1078
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
region16_init(&intersection);
|
||||
|
||||
|
@ -670,16 +729,18 @@ static int test_norbert_case(void) {
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1) )
|
||||
if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1))
|
||||
goto out;
|
||||
|
||||
if (!region16_intersect_rect(&intersection, ®ion, &screenRect))
|
||||
goto out;
|
||||
|
||||
rects = region16_rects(&intersection, &nbRects);
|
||||
|
||||
if (!rects || nbRects != 5 || !compareRectangles(rects, inRectangles, nbRects))
|
||||
goto out;
|
||||
|
||||
if (!compareRectangles(region16_extents(&intersection), &expected_inter_extents, 1) )
|
||||
if (!compareRectangles(region16_extents(&intersection), &expected_inter_extents, 1))
|
||||
goto out;
|
||||
|
||||
retCode = 0;
|
||||
|
@ -689,57 +750,66 @@ out:
|
|||
return retCode;
|
||||
}
|
||||
|
||||
static int test_norbert2_case(void) {
|
||||
static int test_norbert2_case(void)
|
||||
{
|
||||
REGION16 region;
|
||||
int retCode = -1;
|
||||
const RECTANGLE_16 *rects;
|
||||
const RECTANGLE_16* rects;
|
||||
UINT32 nbRects = 0;
|
||||
RECTANGLE_16 rect1 = { 464, 696, 476, 709 };
|
||||
RECTANGLE_16 rect2 = { 0, 0, 1024, 32 };
|
||||
|
||||
region16_init(®ion);
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &rect1)) {
|
||||
if (!region16_union_rect(®ion, ®ion, &rect1))
|
||||
{
|
||||
fprintf(stderr, "%s: Error 1 - region16_union_rect failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(rects = region16_rects(®ion, &nbRects))) {
|
||||
if (!(rects = region16_rects(®ion, &nbRects)))
|
||||
{
|
||||
fprintf(stderr, "%s: Error 2 - region16_rects failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nbRects != 1) {
|
||||
if (nbRects != 1)
|
||||
{
|
||||
fprintf(stderr, "%s: Error 3 - expected nbRects == 1 but got %"PRIu32"\n", __FUNCTION__, nbRects);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!compareRectangles(&rects[0], &rect1, 1)) {
|
||||
if (!compareRectangles(&rects[0], &rect1, 1))
|
||||
{
|
||||
fprintf(stderr, "%s: Error 4 - compare failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!region16_union_rect(®ion, ®ion, &rect2)) {
|
||||
if (!region16_union_rect(®ion, ®ion, &rect2))
|
||||
{
|
||||
fprintf(stderr, "%s: Error 5 - region16_union_rect failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(rects = region16_rects(®ion, &nbRects))) {
|
||||
if (!(rects = region16_rects(®ion, &nbRects)))
|
||||
{
|
||||
fprintf(stderr, "%s: Error 6 - region16_rects failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nbRects != 2) {
|
||||
if (nbRects != 2)
|
||||
{
|
||||
fprintf(stderr, "%s: Error 7 - expected nbRects == 2 but got %"PRIu32"\n", __FUNCTION__, nbRects);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!compareRectangles(&rects[0], &rect2, 1)) {
|
||||
if (!compareRectangles(&rects[0], &rect2, 1))
|
||||
{
|
||||
fprintf(stderr, "%s: Error 8 - compare failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!compareRectangles(&rects[1], &rect1, 1)) {
|
||||
if (!compareRectangles(&rects[1], &rect1, 1))
|
||||
{
|
||||
fprintf(stderr, "%s: Error 9 - compare failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
@ -750,27 +820,29 @@ out:
|
|||
return retCode;
|
||||
}
|
||||
|
||||
static int test_empty_rectangle(void) {
|
||||
static int test_empty_rectangle(void)
|
||||
{
|
||||
REGION16 region, intersection;
|
||||
int retCode = -1;
|
||||
int i;
|
||||
|
||||
RECTANGLE_16 emptyRectangles[3] = {
|
||||
RECTANGLE_16 emptyRectangles[3] =
|
||||
{
|
||||
{ 0, 0, 0, 0},
|
||||
{ 10, 10, 10, 11},
|
||||
{ 10, 10, 11, 10}
|
||||
};
|
||||
|
||||
RECTANGLE_16 firstRect = {
|
||||
RECTANGLE_16 firstRect =
|
||||
{
|
||||
0, 0, 100, 100
|
||||
};
|
||||
RECTANGLE_16 anotherRect = {
|
||||
RECTANGLE_16 anotherRect =
|
||||
{
|
||||
100, 100, 200, 200
|
||||
};
|
||||
RECTANGLE_16 expected_inter_extents = {
|
||||
RECTANGLE_16 expected_inter_extents =
|
||||
{
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
region16_init(&intersection);
|
||||
|
||||
|
@ -792,7 +864,7 @@ static int test_empty_rectangle(void) {
|
|||
if (!region16_intersect_rect(®ion, ®ion, &anotherRect))
|
||||
goto out;
|
||||
|
||||
if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1) )
|
||||
if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1))
|
||||
goto out;
|
||||
|
||||
if (!region16_is_empty(®ion))
|
||||
|
@ -809,12 +881,14 @@ out:
|
|||
}
|
||||
|
||||
typedef int (*TestFunction)(void);
|
||||
struct UnitaryTest {
|
||||
const char *name;
|
||||
struct UnitaryTest
|
||||
{
|
||||
const char* name;
|
||||
TestFunction func;
|
||||
};
|
||||
|
||||
static struct UnitaryTest tests[] = {
|
||||
static struct UnitaryTest tests[] =
|
||||
{
|
||||
{"Basic trivial tests", test_basic},
|
||||
{"R1+R3 and R3+R1", test_r1_r3},
|
||||
{"R1+R5", test_r1_r5},
|
||||
|
@ -825,7 +899,7 @@ static struct UnitaryTest tests[] = {
|
|||
{"R1+R2+R3+R4", test_r1_r2_r3_r4},
|
||||
{"data from weston", test_from_weston},
|
||||
{"R1 & R3", test_r1_inter_r3},
|
||||
{"(R1+R3)&R11 (band merge)",test_r1_r3_inter_r11},
|
||||
{"(R1+R3)&R11 (band merge)", test_r1_r3_inter_r11},
|
||||
{"norbert's case", test_norbert_case},
|
||||
{"norbert's case 2", test_norbert2_case},
|
||||
{"empty rectangle case", test_empty_rectangle},
|
||||
|
@ -843,6 +917,7 @@ int TestFreeRDPRegion(int argc, char* argv[])
|
|||
testNb++;
|
||||
fprintf(stderr, "%d: %s\n", testNb, tests[i].name);
|
||||
retCode = tests[i].func();
|
||||
|
||||
if (retCode < 0)
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* XCrush (RDP6.1) Bulk Data Compression
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -30,7 +32,7 @@
|
|||
|
||||
#define TAG FREERDP_TAG("codec")
|
||||
|
||||
const char* xcrush_get_level_2_compression_flags_string(UINT32 flags)
|
||||
static const char* xcrush_get_level_2_compression_flags_string(UINT32 flags)
|
||||
{
|
||||
flags &= 0xE0;
|
||||
|
||||
|
@ -54,7 +56,7 @@ const char* xcrush_get_level_2_compression_flags_string(UINT32 flags)
|
|||
return "PACKET_UNKNOWN";
|
||||
}
|
||||
|
||||
const char* xcrush_get_level_1_compression_flags_string(UINT32 flags)
|
||||
static const char* xcrush_get_level_1_compression_flags_string(UINT32 flags)
|
||||
{
|
||||
flags &= 0x17;
|
||||
|
||||
|
@ -94,7 +96,7 @@ const char* xcrush_get_level_1_compression_flags_string(UINT32 flags)
|
|||
return "L1_UNKNOWN";
|
||||
}
|
||||
|
||||
UINT32 xcrush_update_hash(BYTE* data, UINT32 size)
|
||||
static UINT32 xcrush_update_hash(BYTE* data, UINT32 size)
|
||||
{
|
||||
BYTE* end;
|
||||
UINT32 seed = 5381; /* same value as in djb2 */
|
||||
|
@ -116,7 +118,7 @@ UINT32 xcrush_update_hash(BYTE* data, UINT32 size)
|
|||
return (UINT16) seed;
|
||||
}
|
||||
|
||||
int xcrush_append_chunk(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32* beg, UINT32 end)
|
||||
static int xcrush_append_chunk(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32* beg, UINT32 end)
|
||||
{
|
||||
UINT16 seed;
|
||||
UINT32 size;
|
||||
|
@ -141,13 +143,12 @@ int xcrush_append_chunk(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32* beg, UINT32
|
|||
return 1;
|
||||
}
|
||||
|
||||
int xcrush_compute_chunks(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32 size, UINT32* pIndex)
|
||||
static int xcrush_compute_chunks(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32 size, UINT32* pIndex)
|
||||
{
|
||||
UINT32 i = 0;
|
||||
UINT32 offset = 0;
|
||||
UINT32 rotation = 0;
|
||||
UINT32 accumulator = 0;
|
||||
|
||||
*pIndex = 0;
|
||||
xcrush->SignatureIndex = 0;
|
||||
|
||||
|
@ -170,8 +171,8 @@ int xcrush_compute_chunks(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32 size, UINT3
|
|||
if (!xcrush_append_chunk(xcrush, data, &offset, i + 32))
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
|
||||
i++;
|
||||
rotation = _rotl(accumulator, 1);
|
||||
accumulator = data[i + 32] ^ data[i] ^ rotation;
|
||||
|
||||
|
@ -180,8 +181,8 @@ int xcrush_compute_chunks(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32 size, UINT3
|
|||
if (!xcrush_append_chunk(xcrush, data, &offset, i + 32))
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
|
||||
i++;
|
||||
rotation = _rotl(accumulator, 1);
|
||||
accumulator = data[i + 32] ^ data[i] ^ rotation;
|
||||
|
||||
|
@ -190,8 +191,8 @@ int xcrush_compute_chunks(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32 size, UINT3
|
|||
if (!xcrush_append_chunk(xcrush, data, &offset, i + 32))
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
|
||||
i++;
|
||||
rotation = _rotl(accumulator, 1);
|
||||
accumulator = data[i + 32] ^ data[i] ^ rotation;
|
||||
|
||||
|
@ -211,7 +212,7 @@ int xcrush_compute_chunks(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32 size, UINT3
|
|||
return 0;
|
||||
}
|
||||
|
||||
UINT32 xcrush_compute_signatures(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32 size)
|
||||
static UINT32 xcrush_compute_signatures(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32 size)
|
||||
{
|
||||
UINT32 index = 0;
|
||||
|
||||
|
@ -221,7 +222,7 @@ UINT32 xcrush_compute_signatures(XCRUSH_CONTEXT* xcrush, BYTE* data, UINT32 size
|
|||
return 0;
|
||||
}
|
||||
|
||||
void xcrush_clear_hash_table_range(XCRUSH_CONTEXT* xcrush, UINT32 beg, UINT32 end)
|
||||
static void xcrush_clear_hash_table_range(XCRUSH_CONTEXT* xcrush, UINT32 beg, UINT32 end)
|
||||
{
|
||||
UINT32 index;
|
||||
|
||||
|
@ -238,7 +239,7 @@ void xcrush_clear_hash_table_range(XCRUSH_CONTEXT* xcrush, UINT32 beg, UINT32 en
|
|||
|
||||
for (index = 0; index < 65534; index++)
|
||||
{
|
||||
if (xcrush->Chunks[index].next >= beg )
|
||||
if (xcrush->Chunks[index].next >= beg)
|
||||
{
|
||||
if (xcrush->Chunks[index].next <= end)
|
||||
{
|
||||
|
@ -248,7 +249,8 @@ void xcrush_clear_hash_table_range(XCRUSH_CONTEXT* xcrush, UINT32 beg, UINT32 en
|
|||
}
|
||||
}
|
||||
|
||||
int xcrush_find_next_matching_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_CHUNK* chunk, XCRUSH_CHUNK** pNextChunk)
|
||||
static int xcrush_find_next_matching_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_CHUNK* chunk,
|
||||
XCRUSH_CHUNK** pNextChunk)
|
||||
{
|
||||
UINT32 index;
|
||||
XCRUSH_CHUNK* next = NULL;
|
||||
|
@ -273,11 +275,11 @@ int xcrush_find_next_matching_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_CHUNK* chunk,
|
|||
}
|
||||
|
||||
*pNextChunk = next;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xcrush_insert_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_SIGNATURE* signature, UINT32 offset, XCRUSH_CHUNK** pPrevChunk)
|
||||
static int xcrush_insert_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_SIGNATURE* signature, UINT32 offset,
|
||||
XCRUSH_CHUNK** pPrevChunk)
|
||||
{
|
||||
UINT32 seed;
|
||||
UINT32 index;
|
||||
|
@ -300,7 +302,6 @@ int xcrush_insert_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_SIGNATURE* signature, UIN
|
|||
return -3001; /* error */
|
||||
|
||||
xcrush->Chunks[index].offset = offset;
|
||||
|
||||
seed = signature->seed;
|
||||
|
||||
if (seed >= 65536)
|
||||
|
@ -316,11 +317,11 @@ int xcrush_insert_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_SIGNATURE* signature, UIN
|
|||
|
||||
xcrush->Chunks[index].next = xcrush->NextChunks[seed] & 0xFFFF;
|
||||
xcrush->NextChunks[seed] = index;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xcrush_find_match_length(XCRUSH_CONTEXT* xcrush, UINT32 MatchOffset, UINT32 ChunkOffset, UINT32 HistoryOffset, UINT32 SrcSize, UINT32 MaxMatchLength, XCRUSH_MATCH_INFO* MatchInfo)
|
||||
static int xcrush_find_match_length(XCRUSH_CONTEXT* xcrush, UINT32 MatchOffset, UINT32 ChunkOffset,
|
||||
UINT32 HistoryOffset, UINT32 SrcSize, UINT32 MaxMatchLength, XCRUSH_MATCH_INFO* MatchInfo)
|
||||
{
|
||||
UINT32 MatchSymbol;
|
||||
UINT32 ChunkSymbol;
|
||||
|
@ -337,10 +338,8 @@ int xcrush_find_match_length(XCRUSH_CONTEXT* xcrush, UINT32 MatchOffset, UINT32
|
|||
UINT32 TotalMatchLength;
|
||||
BYTE* HistoryBuffer;
|
||||
UINT32 HistoryBufferSize;
|
||||
|
||||
ForwardMatchLength = 0;
|
||||
ReverseMatchLength = 0;
|
||||
|
||||
HistoryBuffer = xcrush->HistoryBuffer;
|
||||
HistoryBufferSize = xcrush->HistoryBufferSize;
|
||||
HistoryBufferEnd = &HistoryBuffer[HistoryOffset + SrcSize];
|
||||
|
@ -357,7 +356,7 @@ int xcrush_find_match_length(XCRUSH_CONTEXT* xcrush, UINT32 MatchOffset, UINT32
|
|||
|
||||
if (MatchOffset == ChunkOffset)
|
||||
return -2003; /* error */
|
||||
|
||||
|
||||
if (MatchBuffer < HistoryBuffer)
|
||||
return -2004; /* error */
|
||||
|
||||
|
@ -368,7 +367,7 @@ int xcrush_find_match_length(XCRUSH_CONTEXT* xcrush, UINT32 MatchOffset, UINT32
|
|||
ForwardChunkPtr = &HistoryBuffer[ChunkOffset];
|
||||
|
||||
if ((&MatchBuffer[MaxMatchLength + 1] < HistoryBufferEnd)
|
||||
&& (MatchBuffer[MaxMatchLength + 1] != ChunkBuffer[MaxMatchLength + 1]))
|
||||
&& (MatchBuffer[MaxMatchLength + 1] != ChunkBuffer[MaxMatchLength + 1]))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -383,16 +382,16 @@ int xcrush_find_match_length(XCRUSH_CONTEXT* xcrush, UINT32 MatchOffset, UINT32
|
|||
|
||||
if (ForwardMatchPtr > HistoryBufferEnd)
|
||||
break;
|
||||
|
||||
|
||||
ForwardMatchLength++;
|
||||
}
|
||||
|
||||
ReverseMatchPtr = MatchBuffer - 1;
|
||||
ReverseChunkPtr = ChunkBuffer - 1;
|
||||
|
||||
while((ReverseMatchPtr > &HistoryBuffer[HistoryOffset])
|
||||
&& (ReverseChunkPtr > HistoryBuffer)
|
||||
&& (*ReverseMatchPtr == *ReverseChunkPtr))
|
||||
while ((ReverseMatchPtr > &HistoryBuffer[HistoryOffset])
|
||||
&& (ReverseChunkPtr > HistoryBuffer)
|
||||
&& (*ReverseMatchPtr == *ReverseChunkPtr))
|
||||
{
|
||||
ReverseMatchLength++;
|
||||
ReverseMatchPtr--;
|
||||
|
@ -411,11 +410,11 @@ int xcrush_find_match_length(XCRUSH_CONTEXT* xcrush, UINT32 MatchOffset, UINT32
|
|||
MatchInfo->MatchOffset = MatchStartPtr - HistoryBuffer;
|
||||
MatchInfo->ChunkOffset = ChunkBuffer - ReverseMatchLength - HistoryBuffer;
|
||||
MatchInfo->MatchLength = TotalMatchLength;
|
||||
|
||||
return (int) TotalMatchLength;
|
||||
}
|
||||
|
||||
int xcrush_find_all_matches(XCRUSH_CONTEXT* xcrush, UINT32 SignatureIndex, UINT32 HistoryOffset, UINT32 SrcOffset, UINT32 SrcSize)
|
||||
static int xcrush_find_all_matches(XCRUSH_CONTEXT* xcrush, UINT32 SignatureIndex,
|
||||
UINT32 HistoryOffset, UINT32 SrcOffset, UINT32 SrcSize)
|
||||
{
|
||||
UINT32 i = 0;
|
||||
UINT32 j = 0;
|
||||
|
@ -430,13 +429,12 @@ int xcrush_find_all_matches(XCRUSH_CONTEXT* xcrush, UINT32 SignatureIndex, UINT3
|
|||
XCRUSH_MATCH_INFO MatchInfo = { 0 };
|
||||
XCRUSH_MATCH_INFO MaxMatchInfo = { 0 };
|
||||
XCRUSH_SIGNATURE* Signatures = NULL;
|
||||
|
||||
Signatures = xcrush->Signatures;
|
||||
|
||||
for (i = 0; i < SignatureIndex; i++)
|
||||
{
|
||||
offset = SrcOffset + HistoryOffset;
|
||||
|
||||
|
||||
if (!Signatures[i].size)
|
||||
return -1001; /* error */
|
||||
|
||||
|
@ -452,13 +450,13 @@ int xcrush_find_all_matches(XCRUSH_CONTEXT* xcrush, UINT32 SignatureIndex, UINT3
|
|||
ZeroMemory(&MaxMatchInfo, sizeof(XCRUSH_MATCH_INFO));
|
||||
|
||||
while (chunk)
|
||||
{
|
||||
{
|
||||
if ((chunk->offset < HistoryOffset) || (chunk->offset < offset)
|
||||
|| (chunk->offset > SrcSize + HistoryOffset))
|
||||
|| (chunk->offset > SrcSize + HistoryOffset))
|
||||
{
|
||||
status = xcrush_find_match_length(xcrush, offset, chunk->offset,
|
||||
HistoryOffset, SrcSize, MaxMatchLength, &MatchInfo);
|
||||
|
||||
HistoryOffset, SrcSize, MaxMatchLength, &MatchInfo);
|
||||
|
||||
if (status < 0)
|
||||
return status; /* error */
|
||||
|
||||
|
@ -470,17 +468,17 @@ int xcrush_find_all_matches(XCRUSH_CONTEXT* xcrush, UINT32 SignatureIndex, UINT3
|
|||
MaxMatchInfo.MatchOffset = MatchInfo.MatchOffset;
|
||||
MaxMatchInfo.ChunkOffset = MatchInfo.ChunkOffset;
|
||||
MaxMatchInfo.MatchLength = MatchInfo.MatchLength;
|
||||
|
||||
|
||||
if (MatchLength > 256)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ChunkIndex = ChunkCount++;
|
||||
|
||||
if (ChunkIndex > 4)
|
||||
break;
|
||||
|
||||
|
||||
status = xcrush_find_next_matching_chunk(xcrush, chunk, &chunk);
|
||||
|
||||
if (status < 0)
|
||||
|
@ -492,19 +490,18 @@ int xcrush_find_all_matches(XCRUSH_CONTEXT* xcrush, UINT32 SignatureIndex, UINT3
|
|||
xcrush->OriginalMatches[j].MatchOffset = MaxMatchInfo.MatchOffset;
|
||||
xcrush->OriginalMatches[j].ChunkOffset = MaxMatchInfo.ChunkOffset;
|
||||
xcrush->OriginalMatches[j].MatchLength = MaxMatchInfo.MatchLength;
|
||||
|
||||
|
||||
if (xcrush->OriginalMatches[j].MatchOffset < HistoryOffset)
|
||||
return -1002; /* error */
|
||||
|
||||
PrevMatchEnd = xcrush->OriginalMatches[j].MatchLength + xcrush->OriginalMatches[j].MatchOffset;
|
||||
|
||||
j++;
|
||||
|
||||
|
||||
if (j >= 1000)
|
||||
return -1003; /* error */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SrcOffset += Signatures[i].size;
|
||||
|
||||
if (SrcOffset > SrcSize)
|
||||
|
@ -517,7 +514,7 @@ int xcrush_find_all_matches(XCRUSH_CONTEXT* xcrush, UINT32 SignatureIndex, UINT3
|
|||
return (int) j;
|
||||
}
|
||||
|
||||
int xcrush_optimize_matches(XCRUSH_CONTEXT* xcrush)
|
||||
static int xcrush_optimize_matches(XCRUSH_CONTEXT* xcrush)
|
||||
{
|
||||
UINT32 i, j;
|
||||
UINT32 MatchDiff;
|
||||
|
@ -529,29 +526,23 @@ int xcrush_optimize_matches(XCRUSH_CONTEXT* xcrush)
|
|||
XCRUSH_MATCH_INFO* OptimizedMatch;
|
||||
XCRUSH_MATCH_INFO* OriginalMatches;
|
||||
XCRUSH_MATCH_INFO* OptimizedMatches;
|
||||
|
||||
i = j = 0;
|
||||
j = 0;
|
||||
PrevMatchEnd = 0;
|
||||
TotalMatchLength = 0;
|
||||
|
||||
OriginalMatches = xcrush->OriginalMatches;
|
||||
OriginalMatchCount = xcrush->OriginalMatchCount;
|
||||
|
||||
OptimizedMatches = xcrush->OptimizedMatches;
|
||||
OptimizedMatchCount = xcrush->OptimizedMatchCount;
|
||||
|
||||
for (i = 0; i < OriginalMatchCount; i++)
|
||||
{
|
||||
if (OriginalMatches[i].MatchOffset <= PrevMatchEnd)
|
||||
{
|
||||
if ((OriginalMatches[i].MatchOffset < PrevMatchEnd)
|
||||
&& (OriginalMatches[i].MatchLength + OriginalMatches[i].MatchOffset > PrevMatchEnd + 6))
|
||||
&& (OriginalMatches[i].MatchLength + OriginalMatches[i].MatchOffset > PrevMatchEnd + 6))
|
||||
{
|
||||
MatchDiff = PrevMatchEnd - OriginalMatches[i].MatchOffset;
|
||||
|
||||
OriginalMatch = &OriginalMatches[i];
|
||||
OptimizedMatch = &OptimizedMatches[j];
|
||||
|
||||
OptimizedMatch->MatchOffset = OriginalMatch->MatchOffset;
|
||||
OptimizedMatch->ChunkOffset = OriginalMatch->ChunkOffset;
|
||||
OptimizedMatch->MatchLength = OriginalMatch->MatchLength;
|
||||
|
@ -561,14 +552,12 @@ int xcrush_optimize_matches(XCRUSH_CONTEXT* xcrush)
|
|||
|
||||
if (MatchDiff >= 20000)
|
||||
return -5002; /* error */
|
||||
|
||||
|
||||
OptimizedMatches[j].MatchLength -= MatchDiff;
|
||||
OptimizedMatches[j].MatchOffset += MatchDiff;
|
||||
OptimizedMatches[j].ChunkOffset += MatchDiff;
|
||||
|
||||
PrevMatchEnd = OptimizedMatches[j].MatchLength + OptimizedMatches[j].MatchOffset;
|
||||
TotalMatchLength += OptimizedMatches[j].MatchLength;
|
||||
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
@ -576,25 +565,22 @@ int xcrush_optimize_matches(XCRUSH_CONTEXT* xcrush)
|
|||
{
|
||||
OriginalMatch = &OriginalMatches[i];
|
||||
OptimizedMatch = &OptimizedMatches[j];
|
||||
|
||||
OptimizedMatch->MatchOffset = OriginalMatch->MatchOffset;
|
||||
OptimizedMatch->ChunkOffset = OriginalMatch->ChunkOffset;
|
||||
OptimizedMatch->MatchLength = OriginalMatch->MatchLength;
|
||||
|
||||
PrevMatchEnd = OptimizedMatches[j].MatchLength + OptimizedMatches[j].MatchOffset;
|
||||
TotalMatchLength += OptimizedMatches[j].MatchLength;
|
||||
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
OptimizedMatchCount = j;
|
||||
xcrush->OptimizedMatchCount = OptimizedMatchCount;
|
||||
|
||||
return (int) TotalMatchLength;
|
||||
}
|
||||
|
||||
int xcrush_generate_output(XCRUSH_CONTEXT* xcrush, BYTE* OutputBuffer, UINT32 OutputSize, UINT32 HistoryOffset, UINT32* pDstSize)
|
||||
static int xcrush_generate_output(XCRUSH_CONTEXT* xcrush, BYTE* OutputBuffer, UINT32 OutputSize,
|
||||
UINT32 HistoryOffset, UINT32* pDstSize)
|
||||
{
|
||||
BYTE* Literals;
|
||||
BYTE* OutputEnd;
|
||||
|
@ -606,36 +592,34 @@ int xcrush_generate_output(XCRUSH_CONTEXT* xcrush, BYTE* OutputBuffer, UINT32 Ou
|
|||
UINT32 MatchOffsetDiff;
|
||||
UINT32 HistoryOffsetDiff;
|
||||
RDP61_MATCH_DETAILS* MatchDetails;
|
||||
|
||||
MatchCount = xcrush->OptimizedMatchCount;
|
||||
|
||||
OutputEnd = &OutputBuffer[OutputSize];
|
||||
|
||||
if (&OutputBuffer[2] >= &OutputBuffer[OutputSize])
|
||||
return -6001; /* error */
|
||||
|
||||
*((UINT16*) OutputBuffer) = MatchCount;
|
||||
|
||||
MatchDetails = (RDP61_MATCH_DETAILS*) &OutputBuffer[2];
|
||||
Literals = (BYTE*) &MatchDetails[MatchCount];
|
||||
|
||||
if (Literals > OutputEnd)
|
||||
return -6002; /* error */
|
||||
|
||||
|
||||
for (MatchIndex = 0; MatchIndex < MatchCount; MatchIndex++)
|
||||
{
|
||||
MatchDetails[MatchIndex].MatchLength = (UINT16) (xcrush->OptimizedMatches[MatchIndex].MatchLength);
|
||||
MatchDetails[MatchIndex].MatchOutputOffset = (UINT16) (xcrush->OptimizedMatches[MatchIndex].MatchOffset - HistoryOffset);
|
||||
{
|
||||
MatchDetails[MatchIndex].MatchLength = (UINT16)(xcrush->OptimizedMatches[MatchIndex].MatchLength);
|
||||
MatchDetails[MatchIndex].MatchOutputOffset = (UINT16)(
|
||||
xcrush->OptimizedMatches[MatchIndex].MatchOffset - HistoryOffset);
|
||||
MatchDetails[MatchIndex].MatchHistoryOffset = xcrush->OptimizedMatches[MatchIndex].ChunkOffset;
|
||||
}
|
||||
|
||||
CurrentOffset = HistoryOffset;
|
||||
|
||||
|
||||
for (MatchIndex = 0; MatchIndex < MatchCount; MatchIndex++)
|
||||
{
|
||||
MatchLength = (UINT16) (xcrush->OptimizedMatches[MatchIndex].MatchLength);
|
||||
MatchLength = (UINT16)(xcrush->OptimizedMatches[MatchIndex].MatchLength);
|
||||
MatchOffset = xcrush->OptimizedMatches[MatchIndex].MatchOffset;
|
||||
|
||||
|
||||
if (MatchOffset <= CurrentOffset)
|
||||
{
|
||||
if (MatchOffset != CurrentOffset)
|
||||
|
@ -659,19 +643,18 @@ int xcrush_generate_output(XCRUSH_CONTEXT* xcrush, BYTE* OutputBuffer, UINT32 Ou
|
|||
CurrentOffset = MatchOffset + MatchLength;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HistoryOffsetDiff = xcrush->HistoryOffset - CurrentOffset;
|
||||
|
||||
|
||||
if (Literals + HistoryOffsetDiff >= OutputEnd)
|
||||
return -6006; /* error */
|
||||
|
||||
CopyMemory(Literals, &xcrush->HistoryBuffer[CurrentOffset], HistoryOffsetDiff);
|
||||
*pDstSize = Literals + HistoryOffsetDiff - OutputBuffer;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xcrush_copy_bytes(BYTE* dst, BYTE* src, int num)
|
||||
static int xcrush_copy_bytes(BYTE* dst, BYTE* src, int num)
|
||||
{
|
||||
int index;
|
||||
|
||||
|
@ -683,7 +666,8 @@ int xcrush_copy_bytes(BYTE* dst, BYTE* src, int num)
|
|||
return num;
|
||||
}
|
||||
|
||||
int xcrush_decompress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags)
|
||||
static int xcrush_decompress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize,
|
||||
BYTE** ppDstData, UINT32* pDstSize, UINT32 flags)
|
||||
{
|
||||
BYTE* pSrcEnd = NULL;
|
||||
BYTE* Literals = NULL;
|
||||
|
@ -726,7 +710,6 @@ int xcrush_decompress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize,
|
|||
return -1003;
|
||||
|
||||
Data_Read_UINT16(pSrcData, MatchCount);
|
||||
|
||||
MatchDetails = (RDP61_MATCH_DETAILS*) &pSrcData[2];
|
||||
Literals = (BYTE*) &MatchDetails[MatchCount];
|
||||
OutputOffset = 0;
|
||||
|
@ -756,11 +739,11 @@ int xcrush_decompress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize,
|
|||
|
||||
if (OutputLength > 0)
|
||||
{
|
||||
if ((&HistoryPtr[OutputLength] >= HistoryBufferEnd) || (Literals >= pSrcEnd) || (&Literals[OutputLength] > pSrcEnd))
|
||||
if ((&HistoryPtr[OutputLength] >= HistoryBufferEnd) || (Literals >= pSrcEnd) ||
|
||||
(&Literals[OutputLength] > pSrcEnd))
|
||||
return -1009;
|
||||
|
||||
xcrush_copy_bytes(HistoryPtr, Literals, OutputLength);
|
||||
|
||||
HistoryPtr += OutputLength;
|
||||
Literals += OutputLength;
|
||||
OutputOffset += OutputLength;
|
||||
|
@ -775,7 +758,6 @@ int xcrush_decompress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize,
|
|||
return -1011;
|
||||
|
||||
xcrush_copy_bytes(HistoryPtr, OutputPtr, MatchLength);
|
||||
|
||||
OutputOffset += MatchLength;
|
||||
HistoryPtr += MatchLength;
|
||||
}
|
||||
|
@ -795,11 +777,11 @@ int xcrush_decompress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize,
|
|||
xcrush->HistoryOffset = HistoryPtr - HistoryBuffer;
|
||||
*pDstSize = HistoryPtr - xcrush->HistoryPtr;
|
||||
*ppDstData = xcrush->HistoryPtr;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xcrush_decompress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags)
|
||||
int xcrush_decompress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
|
||||
UINT32* pDstSize, UINT32 flags)
|
||||
{
|
||||
int status = 0;
|
||||
UINT32 DstSize = 0;
|
||||
|
@ -812,7 +794,6 @@ int xcrush_decompress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||
|
||||
Level1ComprFlags = pSrcData[0];
|
||||
Level2ComprFlags = pSrcData[1];
|
||||
|
||||
pSrcData += 2;
|
||||
SrcSize -= 2;
|
||||
|
||||
|
@ -826,9 +807,7 @@ int xcrush_decompress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||
{
|
||||
pDstData = pSrcData;
|
||||
DstSize = SrcSize;
|
||||
|
||||
status = xcrush_decompress_l1(xcrush, pDstData, DstSize, ppDstData, pDstSize, Level1ComprFlags);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -838,11 +817,11 @@ int xcrush_decompress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||
return status;
|
||||
|
||||
status = xcrush_decompress_l1(xcrush, pDstData, DstSize, ppDstData, pDstSize, Level1ComprFlags);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xcrush_compress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags)
|
||||
static int xcrush_compress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize,
|
||||
BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags)
|
||||
{
|
||||
int status = 0;
|
||||
UINT32 Flags = 0;
|
||||
|
@ -860,7 +839,6 @@ int xcrush_compress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, B
|
|||
HistoryOffset = xcrush->HistoryOffset;
|
||||
HistoryBuffer = xcrush->HistoryBuffer;
|
||||
HistoryPtr = &HistoryBuffer[HistoryOffset];
|
||||
|
||||
MoveMemory(HistoryPtr, pSrcData, SrcSize);
|
||||
xcrush->HistoryOffset += SrcSize;
|
||||
|
||||
|
@ -871,13 +849,12 @@ int xcrush_compress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, B
|
|||
if (SignatureIndex)
|
||||
{
|
||||
status = xcrush_find_all_matches(xcrush,
|
||||
SignatureIndex, HistoryOffset, 0, SrcSize);
|
||||
SignatureIndex, HistoryOffset, 0, SrcSize);
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
xcrush->OriginalMatchCount = (UINT32) status;
|
||||
|
||||
xcrush->OptimizedMatchCount = 0;
|
||||
|
||||
if (xcrush->OriginalMatchCount)
|
||||
|
@ -908,11 +885,11 @@ int xcrush_compress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, B
|
|||
}
|
||||
|
||||
*pFlags = Flags;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xcrush_compress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags)
|
||||
int xcrush_compress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
|
||||
UINT32* pDstSize, UINT32* pFlags)
|
||||
{
|
||||
int status = 0;
|
||||
UINT32 DstSize = 0;
|
||||
|
@ -933,11 +910,10 @@ int xcrush_compress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
|||
|
||||
OriginalData = *ppDstData;
|
||||
OriginalDataSize = SrcSize;
|
||||
|
||||
pDstData = xcrush->BlockBuffer;
|
||||
CompressedDataSize = SrcSize;
|
||||
|
||||
status = xcrush_compress_l1(xcrush, pSrcData, SrcSize, &pDstData, &CompressedDataSize, &Level1ComprFlags);
|
||||
status = xcrush_compress_l1(xcrush, pSrcData, SrcSize, &pDstData, &CompressedDataSize,
|
||||
&Level1ComprFlags);
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
@ -958,13 +934,13 @@ int xcrush_compress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
|||
}
|
||||
|
||||
status = 0;
|
||||
|
||||
pDstData = &OriginalData[2];
|
||||
DstSize = OriginalDataSize - 2;
|
||||
|
||||
if (CompressedDataSize > 50)
|
||||
{
|
||||
status = mppc_compress(xcrush->mppc, CompressedData, CompressedDataSize, &pDstData, &DstSize, &Level2ComprFlags);
|
||||
status = mppc_compress(xcrush->mppc, CompressedData, CompressedDataSize, &pDstData, &DstSize,
|
||||
&Level2ComprFlags);
|
||||
}
|
||||
|
||||
if (status < 0)
|
||||
|
@ -996,14 +972,12 @@ int xcrush_compress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
|||
}
|
||||
|
||||
Level1ComprFlags |= L1_INNER_COMPRESSION;
|
||||
|
||||
OriginalData[0] = (BYTE) Level1ComprFlags;
|
||||
OriginalData[1] = (BYTE) Level2ComprFlags;
|
||||
|
||||
#if 0
|
||||
WLog_DBG(TAG, "XCrushCompress: Level1ComprFlags: %s Level2ComprFlags: %s",
|
||||
xcrush_get_level_1_compression_flags_string(Level1ComprFlags),
|
||||
xcrush_get_level_2_compression_flags_string(Level2ComprFlags));
|
||||
xcrush_get_level_1_compression_flags_string(Level1ComprFlags),
|
||||
xcrush_get_level_2_compression_flags_string(Level2ComprFlags));
|
||||
#endif
|
||||
|
||||
if (*pDstSize < (DstSize + 2))
|
||||
|
@ -1011,7 +985,6 @@ int xcrush_compress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
|||
|
||||
*pDstSize = DstSize + 2;
|
||||
*pFlags = PACKET_COMPRESSED | CompressionLevel;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1020,13 +993,10 @@ void xcrush_context_reset(XCRUSH_CONTEXT* xcrush, BOOL flush)
|
|||
xcrush->SignatureIndex = 0;
|
||||
xcrush->SignatureCount = 1000;
|
||||
ZeroMemory(&(xcrush->Signatures), sizeof(XCRUSH_SIGNATURE) * xcrush->SignatureCount);
|
||||
|
||||
xcrush->CompressionFlags = 0;
|
||||
|
||||
xcrush->ChunkHead = xcrush->ChunkTail = 1;
|
||||
ZeroMemory(&(xcrush->Chunks), sizeof(xcrush->Chunks));
|
||||
ZeroMemory(&(xcrush->NextChunks), sizeof(xcrush->NextChunks));
|
||||
|
||||
ZeroMemory(&(xcrush->OriginalMatches), sizeof(xcrush->OriginalMatches));
|
||||
ZeroMemory(&(xcrush->OptimizedMatches), sizeof(xcrush->OptimizedMatches));
|
||||
|
||||
|
@ -1041,17 +1011,14 @@ void xcrush_context_reset(XCRUSH_CONTEXT* xcrush, BOOL flush)
|
|||
XCRUSH_CONTEXT* xcrush_context_new(BOOL Compressor)
|
||||
{
|
||||
XCRUSH_CONTEXT* xcrush;
|
||||
|
||||
xcrush = (XCRUSH_CONTEXT*) calloc(1, sizeof(XCRUSH_CONTEXT));
|
||||
|
||||
if (xcrush)
|
||||
{
|
||||
xcrush->Compressor = Compressor;
|
||||
xcrush->mppc = mppc_context_new(1, Compressor);
|
||||
|
||||
xcrush->HistoryOffset = 0;
|
||||
xcrush->HistoryBufferSize = 2000000;
|
||||
|
||||
xcrush_context_reset(xcrush, FALSE);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* ZGFX (RDP8) Bulk Data Compression
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -108,7 +110,7 @@ static const ZGFX_TOKEN ZGFX_TOKEN_TABLE[] =
|
|||
_zgfx->bits = _zgfx->BitsCurrent >> _zgfx->cBitsCurrent; \
|
||||
_zgfx->BitsCurrent &= ((1 << _zgfx->cBitsCurrent) - 1);
|
||||
|
||||
void zgfx_history_buffer_ring_write(ZGFX_CONTEXT* zgfx, const BYTE* src, UINT32 count)
|
||||
static void zgfx_history_buffer_ring_write(ZGFX_CONTEXT* zgfx, const BYTE* src, UINT32 count)
|
||||
{
|
||||
UINT32 front;
|
||||
UINT32 residue;
|
||||
|
@ -121,7 +123,6 @@ void zgfx_history_buffer_ring_write(ZGFX_CONTEXT* zgfx, const BYTE* src, UINT32
|
|||
residue = count - zgfx->HistoryBufferSize;
|
||||
count = zgfx->HistoryBufferSize;
|
||||
src += residue;
|
||||
|
||||
zgfx->HistoryIndex = (zgfx->HistoryIndex + residue) % zgfx->HistoryBufferSize;
|
||||
}
|
||||
|
||||
|
@ -141,7 +142,7 @@ void zgfx_history_buffer_ring_write(ZGFX_CONTEXT* zgfx, const BYTE* src, UINT32
|
|||
}
|
||||
}
|
||||
|
||||
void zgfx_history_buffer_ring_read(ZGFX_CONTEXT* zgfx, int offset, BYTE* dst, UINT32 count)
|
||||
static void zgfx_history_buffer_ring_read(ZGFX_CONTEXT* zgfx, int offset, BYTE* dst, UINT32 count)
|
||||
{
|
||||
UINT32 front;
|
||||
UINT32 index;
|
||||
|
@ -155,9 +156,7 @@ void zgfx_history_buffer_ring_read(ZGFX_CONTEXT* zgfx, int offset, BYTE* dst, UI
|
|||
return;
|
||||
|
||||
bytesLeft = count;
|
||||
|
||||
index = (zgfx->HistoryIndex + zgfx->HistoryBufferSize - offset) % zgfx->HistoryBufferSize;
|
||||
|
||||
bytes = MIN(bytesLeft, offset);
|
||||
|
||||
if ((index + bytes) <= zgfx->HistoryBufferSize)
|
||||
|
@ -206,10 +205,8 @@ static int zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, const BYTE* pbSegment, UI
|
|||
return -1;
|
||||
|
||||
flags = pbSegment[0]; /* header (1 byte) */
|
||||
|
||||
pbSegment++;
|
||||
cbSegment--;
|
||||
|
||||
zgfx->OutputCount = 0;
|
||||
|
||||
if (!(flags & PACKET_COMPRESSED))
|
||||
|
@ -217,13 +214,11 @@ static int zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, const BYTE* pbSegment, UI
|
|||
zgfx_history_buffer_ring_write(zgfx, pbSegment, cbSegment);
|
||||
CopyMemory(zgfx->OutputBuffer, pbSegment, cbSegment);
|
||||
zgfx->OutputCount = cbSegment;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
zgfx->pbInputCurrent = pbSegment;
|
||||
zgfx->pbInputEnd = &pbSegment[cbSegment - 1];
|
||||
|
||||
/* NumberOfBitsToDecode = ((NumberOfBytesToDecode - 1) * 8) - ValueOfLastByte */
|
||||
zgfx->cBitsRemaining = 8 * (cbSegment - 1) - *zgfx->pbInputEnd;
|
||||
zgfx->cBitsCurrent = 0;
|
||||
|
@ -248,10 +243,8 @@ static int zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, const BYTE* pbSegment, UI
|
|||
if (ZGFX_TOKEN_TABLE[opIndex].tokenType == 0)
|
||||
{
|
||||
/* Literal */
|
||||
|
||||
zgfx_GetBits(zgfx, ZGFX_TOKEN_TABLE[opIndex].valueBits);
|
||||
c = (BYTE) (ZGFX_TOKEN_TABLE[opIndex].valueBase + zgfx->bits);
|
||||
|
||||
c = (BYTE)(ZGFX_TOKEN_TABLE[opIndex].valueBase + zgfx->bits);
|
||||
zgfx->HistoryBuffer[zgfx->HistoryIndex] = c;
|
||||
|
||||
if (++zgfx->HistoryIndex == zgfx->HistoryBufferSize)
|
||||
|
@ -267,7 +260,6 @@ static int zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, const BYTE* pbSegment, UI
|
|||
if (distance != 0)
|
||||
{
|
||||
/* Match */
|
||||
|
||||
zgfx_GetBits(zgfx, 1);
|
||||
|
||||
if (zgfx->bits == 0)
|
||||
|
@ -278,14 +270,12 @@ static int zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, const BYTE* pbSegment, UI
|
|||
{
|
||||
count = 4;
|
||||
extra = 2;
|
||||
|
||||
zgfx_GetBits(zgfx, 1);
|
||||
|
||||
while (zgfx->bits == 1)
|
||||
{
|
||||
count *= 2;
|
||||
extra++;
|
||||
|
||||
zgfx_GetBits(zgfx, 1);
|
||||
}
|
||||
|
||||
|
@ -300,17 +290,13 @@ static int zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, const BYTE* pbSegment, UI
|
|||
else
|
||||
{
|
||||
/* Unencoded */
|
||||
|
||||
zgfx_GetBits(zgfx, 15);
|
||||
count = zgfx->bits;
|
||||
|
||||
zgfx->cBitsRemaining -= zgfx->cBitsCurrent;
|
||||
zgfx->cBitsCurrent = 0;
|
||||
zgfx->BitsCurrent = 0;
|
||||
|
||||
CopyMemory(&(zgfx->OutputBuffer[zgfx->OutputCount]), zgfx->pbInputCurrent, count);
|
||||
zgfx_history_buffer_ring_write(zgfx, zgfx->pbInputCurrent, count);
|
||||
|
||||
zgfx->pbInputCurrent += count;
|
||||
zgfx->cBitsRemaining -= (8 * count);
|
||||
zgfx->OutputCount += count;
|
||||
|
@ -325,7 +311,8 @@ static int zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, const BYTE* pbSegment, UI
|
|||
return 1;
|
||||
}
|
||||
|
||||
int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags)
|
||||
int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
|
||||
UINT32* pDstSize, UINT32 flags)
|
||||
{
|
||||
int status;
|
||||
BYTE descriptor;
|
||||
|
@ -339,11 +326,15 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
|
|||
{
|
||||
status = zgfx_decompress_segment(zgfx, &pSrcData[1], SrcSize - 1);
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
*ppDstData = (BYTE*) malloc(zgfx->OutputCount);
|
||||
|
||||
if (!*ppDstData)
|
||||
return -1;
|
||||
*pDstSize = zgfx->OutputCount;
|
||||
|
||||
*pDstSize = zgfx->OutputCount;
|
||||
CopyMemory(*ppDstData, zgfx->OutputBuffer, zgfx->OutputCount);
|
||||
}
|
||||
else if (descriptor == ZGFX_SEGMENTED_MULTIPART)
|
||||
|
@ -354,12 +345,11 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
|
|||
UINT32 segmentOffset;
|
||||
UINT32 uncompressedSize;
|
||||
BYTE* pConcatenated;
|
||||
|
||||
segmentOffset = 7;
|
||||
segmentCount = *((UINT16*) &pSrcData[1]); /* segmentCount (2 bytes) */
|
||||
uncompressedSize = *((UINT32*) &pSrcData[3]); /* uncompressedSize (4 bytes) */
|
||||
|
||||
pConcatenated = (BYTE*) malloc(uncompressedSize);
|
||||
|
||||
if (!pConcatenated)
|
||||
return -1;
|
||||
|
||||
|
@ -370,10 +360,12 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
|
|||
{
|
||||
segmentSize = *((UINT32*) &pSrcData[segmentOffset]); /* segmentSize (4 bytes) */
|
||||
segmentOffset += 4;
|
||||
|
||||
status = zgfx_decompress_segment(zgfx, &pSrcData[segmentOffset], segmentSize);
|
||||
segmentOffset += segmentSize;
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
segmentOffset += segmentSize;
|
||||
CopyMemory(pConcatenated, zgfx->OutputBuffer, zgfx->OutputCount);
|
||||
pConcatenated += zgfx->OutputCount;
|
||||
}
|
||||
|
@ -386,23 +378,24 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int zgfx_compress_segment(ZGFX_CONTEXT* zgfx, wStream* s, const BYTE* pSrcData, UINT32 SrcSize, UINT32* pFlags)
|
||||
static int zgfx_compress_segment(ZGFX_CONTEXT* zgfx, wStream* s, const BYTE* pSrcData,
|
||||
UINT32 SrcSize, UINT32* pFlags)
|
||||
{
|
||||
/* FIXME: Currently compression not implemented. Just copy the raw source */
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, SrcSize + 1))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*pFlags) |= ZGFX_PACKET_COMPR_TYPE_RDP8; /* RDP 8.0 compression format */
|
||||
Stream_Write_UINT8(s, (*pFlags)); /* header (1 byte) */
|
||||
Stream_Write(s, pSrcData, SrcSize);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst, const BYTE* pUncompressed, UINT32 uncompressedSize, UINT32* pFlags)
|
||||
int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst, const BYTE* pUncompressed,
|
||||
UINT32 uncompressedSize, UINT32* pFlags)
|
||||
{
|
||||
int fragment;
|
||||
UINT16 maxLength;
|
||||
|
@ -410,18 +403,16 @@ int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst, const BYTE* pUnco
|
|||
size_t posSegmentCount = 0;
|
||||
const BYTE* pSrcData;
|
||||
int status = 0;
|
||||
|
||||
maxLength = ZGFX_SEGMENTED_MAXSIZE;
|
||||
|
||||
totalLength = uncompressedSize;
|
||||
pSrcData = pUncompressed;
|
||||
pSrcData = pUncompressed;
|
||||
|
||||
for (fragment = 0; (totalLength > 0) || (fragment == 0); fragment++)
|
||||
{
|
||||
UINT32 SrcSize;
|
||||
size_t posDstSize;
|
||||
size_t posDataStart;
|
||||
UINT32 DstSize;
|
||||
|
||||
SrcSize = (totalLength > maxLength) ? maxLength : totalLength;
|
||||
posDstSize = 0;
|
||||
totalLength -= SrcSize;
|
||||
|
@ -436,10 +427,10 @@ int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst, const BYTE* pUnco
|
|||
if (fragment == 0)
|
||||
{
|
||||
/* First fragment */
|
||||
|
||||
/* descriptor (1 byte) */
|
||||
Stream_Write_UINT8(sDst, (totalLength == 0) ?
|
||||
Stream_Write_UINT8(sDst, (totalLength == 0) ?
|
||||
ZGFX_SEGMENTED_SINGLE : ZGFX_SEGMENTED_MULTIPART);
|
||||
|
||||
if (totalLength > 0)
|
||||
{
|
||||
posSegmentCount = Stream_GetPosition(sDst); /* segmentCount (2 bytes) */
|
||||
|
@ -456,6 +447,7 @@ int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst, const BYTE* pUnco
|
|||
}
|
||||
|
||||
posDataStart = Stream_GetPosition(sDst);
|
||||
|
||||
if ((status = zgfx_compress_segment(zgfx, sDst, pSrcData, SrcSize, pFlags)) < 0)
|
||||
{
|
||||
return status;
|
||||
|
@ -486,15 +478,14 @@ int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst, const BYTE* pUnco
|
|||
return status;
|
||||
}
|
||||
|
||||
int zgfx_compress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags)
|
||||
int zgfx_compress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
|
||||
UINT32* pDstSize, UINT32* pFlags)
|
||||
{
|
||||
int status;
|
||||
wStream* s = Stream_New(NULL, SrcSize);
|
||||
|
||||
status = zgfx_compress_to_stream(zgfx, s, pSrcData, SrcSize, pFlags);
|
||||
(*ppDstData) = Stream_Buffer(s);
|
||||
(*pDstSize) = Stream_GetPosition(s);
|
||||
|
||||
Stream_Free(s, FALSE);
|
||||
return status;
|
||||
}
|
||||
|
@ -508,15 +499,12 @@ void zgfx_context_reset(ZGFX_CONTEXT* zgfx, BOOL flush)
|
|||
ZGFX_CONTEXT* zgfx_context_new(BOOL Compressor)
|
||||
{
|
||||
ZGFX_CONTEXT* zgfx;
|
||||
|
||||
zgfx = (ZGFX_CONTEXT*) calloc(1, sizeof(ZGFX_CONTEXT));
|
||||
|
||||
if (zgfx)
|
||||
{
|
||||
zgfx->Compressor = Compressor;
|
||||
|
||||
zgfx->HistoryBufferSize = sizeof(zgfx->HistoryBuffer);
|
||||
|
||||
zgfx_context_reset(zgfx, FALSE);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
*
|
||||
* Copyright 2011 Vic Lee
|
||||
* Copyright 2014 Norbert Federa <norbert.federa@thincast.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -79,10 +81,12 @@ UINT16 fastpath_header_length(wStream* s)
|
|||
{
|
||||
BYTE length1;
|
||||
|
||||
if (!s || (Stream_GetRemainingLength(s) < 2))
|
||||
return 0;
|
||||
|
||||
Stream_Seek_UINT8(s);
|
||||
Stream_Read_UINT8(s, length1);
|
||||
Stream_Rewind(s, 2);
|
||||
|
||||
return ((length1 & 0x80) != 0 ? 3 : 2);
|
||||
}
|
||||
|
||||
|
@ -97,6 +101,9 @@ UINT16 fastpath_read_header(rdpFastPath* fastpath, wStream* s)
|
|||
BYTE header;
|
||||
UINT16 length;
|
||||
|
||||
if (!s || (Stream_GetRemainingLength(s) < 1))
|
||||
return 0;
|
||||
|
||||
Stream_Read_UINT8(s, header);
|
||||
|
||||
if (fastpath)
|
||||
|
@ -105,64 +112,108 @@ UINT16 fastpath_read_header(rdpFastPath* fastpath, wStream* s)
|
|||
fastpath->numberEvents = (header & 0x3C) >> 2;
|
||||
}
|
||||
|
||||
per_read_length(s, &length);
|
||||
if (!per_read_length(s, &length))
|
||||
return 0;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void fastpath_read_update_header(wStream* s, BYTE* updateCode, BYTE* fragmentation, BYTE* compression)
|
||||
static BOOL fastpath_read_update_header(wStream* s, BYTE* updateCode, BYTE* fragmentation,
|
||||
BYTE* compression)
|
||||
{
|
||||
BYTE updateHeader;
|
||||
|
||||
if (!s || !updateCode || !fragmentation || !compression)
|
||||
return FALSE;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT8(s, updateHeader);
|
||||
*updateCode = updateHeader & 0x0F;
|
||||
*fragmentation = (updateHeader >> 4) & 0x03;
|
||||
*compression = (updateHeader >> 6) & 0x03;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void fastpath_write_update_header(wStream* s, FASTPATH_UPDATE_HEADER* fpUpdateHeader)
|
||||
static BOOL fastpath_write_update_header(wStream* s, FASTPATH_UPDATE_HEADER* fpUpdateHeader)
|
||||
{
|
||||
if (!s || !fpUpdateHeader)
|
||||
return FALSE;
|
||||
|
||||
fpUpdateHeader->updateHeader = 0;
|
||||
fpUpdateHeader->updateHeader |= fpUpdateHeader->updateCode & 0x0F;
|
||||
fpUpdateHeader->updateHeader |= (fpUpdateHeader->fragmentation & 0x03) << 4;
|
||||
fpUpdateHeader->updateHeader |= (fpUpdateHeader->compression & 0x03) << 6;
|
||||
|
||||
Stream_Write_UINT8(s, fpUpdateHeader->updateHeader);
|
||||
|
||||
if (fpUpdateHeader->compression)
|
||||
{
|
||||
if (Stream_GetRemainingCapacity(s) < 1)
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT8(s, fpUpdateHeader->compressionFlags);
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingCapacity(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, fpUpdateHeader->size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UINT32 fastpath_get_update_header_size(FASTPATH_UPDATE_HEADER* fpUpdateHeader)
|
||||
static UINT32 fastpath_get_update_header_size(FASTPATH_UPDATE_HEADER* fpUpdateHeader)
|
||||
{
|
||||
if (!fpUpdateHeader)
|
||||
return 0;
|
||||
|
||||
return (fpUpdateHeader->compression) ? 4 : 3;
|
||||
}
|
||||
|
||||
void fastpath_write_update_pdu_header(wStream* s, FASTPATH_UPDATE_PDU_HEADER* fpUpdatePduHeader, rdpRdp* rdp)
|
||||
static BOOL fastpath_write_update_pdu_header(wStream* s,
|
||||
FASTPATH_UPDATE_PDU_HEADER* fpUpdatePduHeader,
|
||||
rdpRdp* rdp)
|
||||
{
|
||||
if (!s || !fpUpdatePduHeader || !rdp)
|
||||
return FALSE;
|
||||
|
||||
if (Stream_GetRemainingCapacity(s) < 3)
|
||||
return FALSE;
|
||||
|
||||
fpUpdatePduHeader->fpOutputHeader = 0;
|
||||
fpUpdatePduHeader->fpOutputHeader |= (fpUpdatePduHeader->action & 0x03);
|
||||
fpUpdatePduHeader->fpOutputHeader |= (fpUpdatePduHeader->secFlags & 0x03) << 6;
|
||||
|
||||
Stream_Write_UINT8(s, fpUpdatePduHeader->fpOutputHeader); /* fpOutputHeader (1 byte) */
|
||||
|
||||
Stream_Write_UINT8(s, 0x80 | (fpUpdatePduHeader->length >> 8)); /* length1 */
|
||||
Stream_Write_UINT8(s, fpUpdatePduHeader->length & 0xFF); /* length2 */
|
||||
|
||||
if (fpUpdatePduHeader->secFlags)
|
||||
{
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
if (Stream_GetRemainingCapacity(s) < 4)
|
||||
return FALSE;
|
||||
|
||||
Stream_Write(s, fpUpdatePduHeader->fipsInformation, 4);
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingCapacity(s) < 8)
|
||||
return FALSE;
|
||||
|
||||
Stream_Write(s, fpUpdatePduHeader->dataSignature, 8);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UINT32 fastpath_get_update_pdu_header_size(FASTPATH_UPDATE_PDU_HEADER* fpUpdatePduHeader, rdpRdp* rdp)
|
||||
static UINT32 fastpath_get_update_pdu_header_size(FASTPATH_UPDATE_PDU_HEADER* fpUpdatePduHeader,
|
||||
rdpRdp* rdp)
|
||||
{
|
||||
UINT32 size = 3; /* fpUpdatePduHeader + length1 + length2 */
|
||||
|
||||
if (!fpUpdatePduHeader || !rdp)
|
||||
return 0;
|
||||
|
||||
if (fpUpdatePduHeader->secFlags)
|
||||
{
|
||||
size += 8; /* dataSignature */
|
||||
|
@ -174,10 +225,16 @@ UINT32 fastpath_get_update_pdu_header_size(FASTPATH_UPDATE_PDU_HEADER* fpUpdateP
|
|||
return size;
|
||||
}
|
||||
|
||||
BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, wStream* s, UINT16 *length)
|
||||
BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, wStream* s, UINT16* length)
|
||||
{
|
||||
BYTE header;
|
||||
|
||||
if (!s || !length)
|
||||
return FALSE;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT8(s, header);
|
||||
|
||||
if (fastpath)
|
||||
|
@ -195,9 +252,20 @@ BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, wStream* s, UINT16 *length)
|
|||
|
||||
static BOOL fastpath_recv_orders(rdpFastPath* fastpath, wStream* s)
|
||||
{
|
||||
rdpUpdate* update = fastpath->rdp->update;
|
||||
rdpUpdate* update;
|
||||
UINT16 numberOrders;
|
||||
|
||||
if (!fastpath || !fastpath->rdp || !s)
|
||||
return FALSE;
|
||||
|
||||
update = fastpath->rdp->update;
|
||||
|
||||
if (!update)
|
||||
return FALSE;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, numberOrders); /* numberOrders (2 bytes) */
|
||||
|
||||
while (numberOrders > 0)
|
||||
|
@ -214,8 +282,18 @@ static BOOL fastpath_recv_orders(rdpFastPath* fastpath, wStream* s)
|
|||
static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s)
|
||||
{
|
||||
UINT16 updateType;
|
||||
rdpUpdate* update = fastpath->rdp->update;
|
||||
rdpContext* context = update->context;
|
||||
rdpUpdate* update;
|
||||
rdpContext* context;
|
||||
|
||||
if (!fastpath || !s || !fastpath->rdp)
|
||||
return FALSE;
|
||||
|
||||
update = fastpath->rdp->update;
|
||||
|
||||
if (!update || !update->context)
|
||||
return FALSE;
|
||||
|
||||
context = update->context;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
@ -227,15 +305,18 @@ static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s)
|
|||
case UPDATE_TYPE_BITMAP:
|
||||
if (!update_read_bitmap_update(update, s, &update->bitmap_update))
|
||||
return FALSE;
|
||||
|
||||
IFCALL(update->BitmapUpdate, context, &update->bitmap_update);
|
||||
break;
|
||||
|
||||
case UPDATE_TYPE_PALETTE:
|
||||
if (!update_read_palette(update, s, &update->palette_update))
|
||||
return FALSE;
|
||||
|
||||
IFCALL(update->Palette, context, &update->palette_update);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -250,13 +331,24 @@ static BOOL fastpath_recv_update_synchronize(rdpFastPath* fastpath, wStream* s)
|
|||
static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 size, wStream* s)
|
||||
{
|
||||
int status = 0;
|
||||
rdpUpdate* update = fastpath->rdp->update;
|
||||
rdpContext* context = fastpath->rdp->update->context;
|
||||
rdpPointerUpdate* pointer = update->pointer;
|
||||
rdpUpdate* update;
|
||||
rdpContext* context;
|
||||
rdpPointerUpdate* pointer;
|
||||
|
||||
if (!fastpath || !fastpath->rdp || !s)
|
||||
return -1;
|
||||
|
||||
update = fastpath->rdp->update;
|
||||
|
||||
if (!update || !update->pointer || !update->context)
|
||||
return -1;
|
||||
|
||||
context = update->context;
|
||||
pointer = update->pointer;
|
||||
#ifdef WITH_DEBUG_RDP
|
||||
DEBUG_RDP("recv Fast-Path %s Update (0x%02"PRIX8"), length:%"PRIu32"",
|
||||
updateCode < ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] : "???", updateCode, size);
|
||||
updateCode < ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] :
|
||||
"???", updateCode, size);
|
||||
#endif
|
||||
|
||||
switch (updateCode)
|
||||
|
@ -267,6 +359,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
|||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_ORDERS - fastpath_recv_orders()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_BITMAP:
|
||||
|
@ -276,6 +369,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
|||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_ORDERS - fastpath_recv_orders()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
|
||||
|
@ -283,12 +377,15 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
|||
WLog_ERR(TAG, "fastpath_recv_update_synchronize failure but we continue");
|
||||
else
|
||||
IFCALL(update->Synchronize, context);
|
||||
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_SURFCMDS:
|
||||
status = update_recv_surfcmds(update, size, s);
|
||||
|
||||
if (status < 0)
|
||||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_SURFCMDS - update_recv_surfcmds() - %i", status);
|
||||
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_PTR_NULL:
|
||||
|
@ -307,6 +404,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
|||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_PTR_POSITION - update_read_pointer_position()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
IFCALL(pointer->PointerPosition, context, &pointer->pointer_position);
|
||||
break;
|
||||
|
||||
|
@ -316,6 +414,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
|||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_COLOR - update_read_pointer_color()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
|
||||
break;
|
||||
|
||||
|
@ -325,6 +424,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
|||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_CACHED - update_read_pointer_cached()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
IFCALL(pointer->PointerCached, context, &pointer->pointer_cached);
|
||||
break;
|
||||
|
||||
|
@ -334,6 +434,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
|||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_POINTER - update_read_pointer_new()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
IFCALL(pointer->PointerNew, context, &pointer->pointer_new);
|
||||
break;
|
||||
|
||||
|
@ -345,7 +446,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
|||
return status;
|
||||
}
|
||||
|
||||
const char* fastpath_get_fragmentation_string(BYTE fragmentation)
|
||||
static const char* fastpath_get_fragmentation_string(BYTE fragmentation)
|
||||
{
|
||||
if (fragmentation == FASTPATH_FRAGMENT_SINGLE)
|
||||
return "FASTPATH_FRAGMENT_SINGLE";
|
||||
|
@ -376,17 +477,36 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||
BYTE* pDstData = NULL;
|
||||
rdpTransport* transport;
|
||||
|
||||
if (!fastpath || !s)
|
||||
return -1;
|
||||
|
||||
status = 0;
|
||||
rdp = fastpath->rdp;
|
||||
|
||||
if (!rdp)
|
||||
return -1;
|
||||
|
||||
transport = fastpath->rdp->transport;
|
||||
|
||||
fastpath_read_update_header(s, &updateCode, &fragmentation, &compression);
|
||||
if (!transport)
|
||||
return -1;
|
||||
|
||||
if (!fastpath_read_update_header(s, &updateCode, &fragmentation, &compression))
|
||||
return -1;
|
||||
|
||||
if (compression == FASTPATH_OUTPUT_COMPRESSION_USED)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return -1;
|
||||
|
||||
Stream_Read_UINT8(s, compressionFlags);
|
||||
}
|
||||
else
|
||||
compressionFlags = 0;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return -1;
|
||||
|
||||
Stream_Read_UINT16(s, size);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < size)
|
||||
|
@ -397,8 +517,8 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||
|
||||
cs = s;
|
||||
next_pos = Stream_GetPosition(s) + size;
|
||||
|
||||
bulkStatus = bulk_decompress(rdp->bulk, Stream_Pointer(s), size, &pDstData, &DstSize, compressionFlags);
|
||||
bulkStatus = bulk_decompress(rdp->bulk, Stream_Pointer(s), size, &pDstData, &DstSize,
|
||||
compressionFlags);
|
||||
|
||||
if (bulkStatus < 0)
|
||||
{
|
||||
|
@ -409,8 +529,8 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||
if (bulkStatus > 0)
|
||||
{
|
||||
/* data was compressed, copy from decompression buffer */
|
||||
|
||||
size = DstSize;
|
||||
|
||||
if (!(cs = StreamPool_Take(transport->ReceivePool, DstSize)))
|
||||
return -1;
|
||||
|
||||
|
@ -448,13 +568,12 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||
}
|
||||
|
||||
fastpath->fragmentation = FASTPATH_FRAGMENT_FIRST;
|
||||
|
||||
totalSize = size;
|
||||
|
||||
if (totalSize > transport->settings->MultifragMaxRequestSize)
|
||||
{
|
||||
WLog_ERR(TAG, "Total size (%"PRIu32") exceeds MultifragMaxRequestSize (%"PRIu32")",
|
||||
totalSize, transport->settings->MultifragMaxRequestSize);
|
||||
totalSize, transport->settings->MultifragMaxRequestSize);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
|
@ -462,26 +581,24 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||
goto out_fail;
|
||||
|
||||
Stream_SetPosition(fastpath->updateData, 0);
|
||||
|
||||
Stream_Copy(cs, fastpath->updateData, size);
|
||||
}
|
||||
else if (fragmentation == FASTPATH_FRAGMENT_NEXT)
|
||||
{
|
||||
if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) &&
|
||||
(fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT))
|
||||
(fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT))
|
||||
{
|
||||
WLog_ERR(TAG, "fastpath_recv_update_data: Unexpected FASTPATH_FRAGMENT_NEXT");
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
fastpath->fragmentation = FASTPATH_FRAGMENT_NEXT;
|
||||
|
||||
totalSize = Stream_GetPosition(fastpath->updateData) + size;
|
||||
|
||||
if (totalSize > transport->settings->MultifragMaxRequestSize)
|
||||
{
|
||||
WLog_ERR(TAG, "Total size (%"PRIu32") exceeds MultifragMaxRequestSize (%"PRIu32")",
|
||||
totalSize, transport->settings->MultifragMaxRequestSize);
|
||||
totalSize, transport->settings->MultifragMaxRequestSize);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
|
@ -496,20 +613,19 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||
else if (fragmentation == FASTPATH_FRAGMENT_LAST)
|
||||
{
|
||||
if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) &&
|
||||
(fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT))
|
||||
(fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT))
|
||||
{
|
||||
WLog_ERR(TAG, "fastpath_recv_update_data: Unexpected FASTPATH_FRAGMENT_LAST");
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
fastpath->fragmentation = -1;
|
||||
|
||||
totalSize = Stream_GetPosition(fastpath->updateData) + size;
|
||||
|
||||
if (totalSize > transport->settings->MultifragMaxRequestSize)
|
||||
{
|
||||
WLog_ERR(TAG, "Total size (%"PRIu32") exceeds MultifragMaxRequestSize (%"PRIu32")",
|
||||
totalSize, transport->settings->MultifragMaxRequestSize);
|
||||
totalSize, transport->settings->MultifragMaxRequestSize);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
|
@ -520,12 +636,9 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||
}
|
||||
|
||||
Stream_Copy(cs, fastpath->updateData, size);
|
||||
|
||||
Stream_SealLength(fastpath->updateData);
|
||||
Stream_SetPosition(fastpath->updateData, 0);
|
||||
|
||||
status = fastpath_recv_update(fastpath, updateCode, totalSize, fastpath->updateData);
|
||||
|
||||
Stream_Release(fastpath->updateData);
|
||||
|
||||
if (status < 0)
|
||||
|
@ -542,20 +655,24 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||
Stream_Release(cs);
|
||||
|
||||
return status;
|
||||
|
||||
out_fail:
|
||||
|
||||
if (cs != s) {
|
||||
Stream_Release(cs);
|
||||
}
|
||||
if (cs != s)
|
||||
{
|
||||
Stream_Release(cs);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s)
|
||||
{
|
||||
rdpUpdate* update = fastpath->rdp->update;
|
||||
rdpUpdate* update;
|
||||
|
||||
if (!fastpath || !fastpath->rdp || !fastpath->rdp->update || !s)
|
||||
return -1;
|
||||
|
||||
update = fastpath->rdp->update;
|
||||
IFCALL(update->BeginPaint, update->context);
|
||||
|
||||
while (Stream_GetRemainingLength(s) >= 3)
|
||||
|
@ -568,7 +685,6 @@ int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s)
|
|||
}
|
||||
|
||||
IFCALL(update->EndPaint, update->context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -576,27 +692,33 @@ static BOOL fastpath_read_input_event_header(wStream* s, BYTE* eventFlags, BYTE*
|
|||
{
|
||||
BYTE eventHeader;
|
||||
|
||||
if (!s || !eventFlags || !eventCode)
|
||||
return FALSE;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT8(s, eventHeader); /* eventHeader (1 byte) */
|
||||
|
||||
*eventFlags = (eventHeader & 0x1F);
|
||||
*eventCode = (eventHeader >> 5);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL fastpath_recv_input_event_scancode(rdpFastPath* fastpath, wStream* s, BYTE eventFlags)
|
||||
{
|
||||
rdpInput* input;
|
||||
UINT16 flags;
|
||||
UINT16 code;
|
||||
|
||||
if (!fastpath || !fastpath->rdp || !fastpath->rdp->input || !s)
|
||||
return FALSE;
|
||||
|
||||
input = fastpath->rdp->input;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT8(s, code); /* keyCode (1 byte) */
|
||||
|
||||
flags = 0;
|
||||
|
||||
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE))
|
||||
|
@ -607,52 +729,60 @@ static BOOL fastpath_recv_input_event_scancode(rdpFastPath* fastpath, wStream* s
|
|||
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED))
|
||||
flags |= KBD_FLAGS_EXTENDED;
|
||||
|
||||
IFCALL(fastpath->rdp->input->KeyboardEvent, fastpath->rdp->input, flags, code);
|
||||
|
||||
return TRUE;
|
||||
return IFCALLRESULT(TRUE, input->KeyboardEvent, input, flags, code);
|
||||
}
|
||||
|
||||
static BOOL fastpath_recv_input_event_mouse(rdpFastPath* fastpath, wStream* s, BYTE eventFlags)
|
||||
{
|
||||
rdpInput* input;
|
||||
UINT16 pointerFlags;
|
||||
UINT16 xPos;
|
||||
UINT16 yPos;
|
||||
|
||||
if (!fastpath || !fastpath->rdp || !fastpath->rdp->input || !s)
|
||||
return FALSE;
|
||||
|
||||
input = fastpath->rdp->input;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 6)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, pointerFlags); /* pointerFlags (2 bytes) */
|
||||
Stream_Read_UINT16(s, xPos); /* xPos (2 bytes) */
|
||||
Stream_Read_UINT16(s, yPos); /* yPos (2 bytes) */
|
||||
|
||||
IFCALL(fastpath->rdp->input->MouseEvent, fastpath->rdp->input, pointerFlags, xPos, yPos);
|
||||
|
||||
return TRUE;
|
||||
return IFCALLRESULT(TRUE, input->MouseEvent, input, pointerFlags, xPos, yPos);
|
||||
}
|
||||
|
||||
static BOOL fastpath_recv_input_event_mousex(rdpFastPath* fastpath, wStream* s, BYTE eventFlags)
|
||||
{
|
||||
rdpInput* input;
|
||||
UINT16 pointerFlags;
|
||||
UINT16 xPos;
|
||||
UINT16 yPos;
|
||||
|
||||
if (!fastpath || !fastpath->rdp || !fastpath->rdp->input || !s)
|
||||
return FALSE;
|
||||
|
||||
input = fastpath->rdp->input;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 6)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, pointerFlags); /* pointerFlags (2 bytes) */
|
||||
Stream_Read_UINT16(s, xPos); /* xPos (2 bytes) */
|
||||
Stream_Read_UINT16(s, yPos); /* yPos (2 bytes) */
|
||||
|
||||
IFCALL(fastpath->rdp->input->ExtendedMouseEvent, fastpath->rdp->input, pointerFlags, xPos, yPos);
|
||||
|
||||
return TRUE;
|
||||
return IFCALLRESULT(TRUE, input->ExtendedMouseEvent, input, pointerFlags, xPos, yPos);
|
||||
}
|
||||
|
||||
static BOOL fastpath_recv_input_event_sync(rdpFastPath* fastpath, wStream* s, BYTE eventFlags)
|
||||
{
|
||||
IFCALL(fastpath->rdp->input->SynchronizeEvent, fastpath->rdp->input, eventFlags);
|
||||
rdpInput* input;
|
||||
|
||||
return TRUE;
|
||||
if (!fastpath || !fastpath->rdp || !fastpath->rdp->input || !s)
|
||||
return FALSE;
|
||||
|
||||
input = fastpath->rdp->input;
|
||||
return IFCALLRESULT(TRUE, input->SynchronizeEvent, input, eventFlags);
|
||||
}
|
||||
|
||||
static BOOL fastpath_recv_input_event_unicode(rdpFastPath* fastpath, wStream* s, BYTE eventFlags)
|
||||
|
@ -660,11 +790,13 @@ static BOOL fastpath_recv_input_event_unicode(rdpFastPath* fastpath, wStream* s,
|
|||
UINT16 unicodeCode;
|
||||
UINT16 flags;
|
||||
|
||||
if (!fastpath || !s)
|
||||
return FALSE;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, unicodeCode); /* unicodeCode (2 bytes) */
|
||||
|
||||
flags = 0;
|
||||
|
||||
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE))
|
||||
|
@ -673,7 +805,6 @@ static BOOL fastpath_recv_input_event_unicode(rdpFastPath* fastpath, wStream* s,
|
|||
flags |= KBD_FLAGS_DOWN;
|
||||
|
||||
IFCALL(fastpath->rdp->input->UnicodeKeyboardEvent, fastpath->rdp->input, flags, unicodeCode);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -682,6 +813,9 @@ static BOOL fastpath_recv_input_event(rdpFastPath* fastpath, wStream* s)
|
|||
BYTE eventFlags;
|
||||
BYTE eventCode;
|
||||
|
||||
if (!fastpath || !s)
|
||||
return FALSE;
|
||||
|
||||
if (!fastpath_read_input_event_header(s, &eventFlags, &eventCode))
|
||||
return FALSE;
|
||||
|
||||
|
@ -690,26 +824,31 @@ static BOOL fastpath_recv_input_event(rdpFastPath* fastpath, wStream* s)
|
|||
case FASTPATH_INPUT_EVENT_SCANCODE:
|
||||
if (!fastpath_recv_input_event_scancode(fastpath, s, eventFlags))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_MOUSE:
|
||||
if (!fastpath_recv_input_event_mouse(fastpath, s, eventFlags))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_MOUSEX:
|
||||
if (!fastpath_recv_input_event_mousex(fastpath, s, eventFlags))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_SYNC:
|
||||
if (!fastpath_recv_input_event_sync(fastpath, s, eventFlags))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_UNICODE:
|
||||
if (!fastpath_recv_input_event_unicode(fastpath, s, eventFlags))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -724,13 +863,15 @@ int fastpath_recv_inputs(rdpFastPath* fastpath, wStream* s)
|
|||
{
|
||||
BYTE i;
|
||||
|
||||
if (!fastpath || !s)
|
||||
return -1;
|
||||
|
||||
if (fastpath->numberEvents == 0)
|
||||
{
|
||||
/**
|
||||
* If numberEvents is not provided in fpInputHeader, it will be provided
|
||||
* as one additional byte here.
|
||||
*/
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return -1;
|
||||
|
||||
|
@ -749,9 +890,11 @@ int fastpath_recv_inputs(rdpFastPath* fastpath, wStream* s)
|
|||
static UINT32 fastpath_get_sec_bytes(rdpRdp* rdp)
|
||||
{
|
||||
UINT32 sec_bytes;
|
||||
|
||||
sec_bytes = 0;
|
||||
|
||||
if (!rdp)
|
||||
return 0;
|
||||
|
||||
if (rdp->do_crypt)
|
||||
{
|
||||
sec_bytes = 8;
|
||||
|
@ -765,12 +908,15 @@ static UINT32 fastpath_get_sec_bytes(rdpRdp* rdp)
|
|||
|
||||
wStream* fastpath_input_pdu_init_header(rdpFastPath* fastpath)
|
||||
{
|
||||
rdpRdp *rdp;
|
||||
rdpRdp* rdp;
|
||||
wStream* s;
|
||||
|
||||
rdp = fastpath->rdp;
|
||||
if (!fastpath || !fastpath->rdp)
|
||||
return NULL;
|
||||
|
||||
rdp = fastpath->rdp;
|
||||
s = transport_send_stream_init(rdp->transport, 256);
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
|
@ -785,22 +931,18 @@ wStream* fastpath_input_pdu_init_header(rdpFastPath* fastpath)
|
|||
}
|
||||
|
||||
Stream_Seek(s, fastpath_get_sec_bytes(rdp));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE eventCode)
|
||||
{
|
||||
rdpRdp *rdp;
|
||||
wStream* s;
|
||||
|
||||
rdp = fastpath->rdp;
|
||||
|
||||
s = fastpath_input_pdu_init_header(fastpath);
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
Stream_Write_UINT8(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */
|
||||
|
||||
Stream_Write_UINT8(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -810,6 +952,9 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
|
|||
UINT16 length;
|
||||
BYTE eventHeader;
|
||||
|
||||
if (!fastpath || !fastpath->rdp || !s)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* A maximum of 15 events are allowed per request
|
||||
* if the optional numEvents field isn't used
|
||||
|
@ -819,7 +964,6 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
|
|||
return FALSE;
|
||||
|
||||
rdp = fastpath->rdp;
|
||||
|
||||
length = Stream_GetPosition(s);
|
||||
|
||||
if (length >= (2 << 14))
|
||||
|
@ -833,12 +977,12 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
|
|||
|
||||
if (rdp->sec_flags & SEC_ENCRYPT)
|
||||
eventHeader |= (FASTPATH_INPUT_ENCRYPTED << 6);
|
||||
|
||||
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
|
||||
eventHeader |= (FASTPATH_INPUT_SECURE_CHECKSUM << 6);
|
||||
|
||||
Stream_SetPosition(s, 0);
|
||||
Stream_Write_UINT8(s, eventHeader);
|
||||
|
||||
/* Write length later, RDP encryption might add a padding */
|
||||
Stream_Seek(s, 2);
|
||||
|
||||
|
@ -875,7 +1019,8 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
|
|||
BOOL status;
|
||||
|
||||
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
|
||||
status = security_salted_mac_signature(rdp, fpInputEvents, fpInputEvents_length, TRUE, Stream_Pointer(s));
|
||||
status = security_salted_mac_signature(rdp, fpInputEvents, fpInputEvents_length, TRUE,
|
||||
Stream_Pointer(s));
|
||||
else
|
||||
status = security_mac_signature(rdp, fpInputEvents, fpInputEvents_length, Stream_Pointer(s));
|
||||
|
||||
|
@ -885,7 +1030,6 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
|
|||
}
|
||||
|
||||
rdp->sec_flags = 0;
|
||||
|
||||
/*
|
||||
* We always encode length in two bytes, even though we could use
|
||||
* only one byte if length <= 0x7F. It is just easier that way,
|
||||
|
@ -894,7 +1038,6 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
|
|||
*/
|
||||
Stream_SetPosition(s, 1);
|
||||
Stream_Write_UINT16_BE(s, 0x8000 | length);
|
||||
|
||||
Stream_SetPosition(s, length);
|
||||
Stream_SealLength(s);
|
||||
|
||||
|
@ -921,7 +1064,8 @@ wStream* fastpath_update_pdu_init_new(rdpFastPath* fastpath)
|
|||
return s;
|
||||
}
|
||||
|
||||
BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s, BOOL skipCompression)
|
||||
BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s,
|
||||
BOOL skipCompression)
|
||||
{
|
||||
int fragment;
|
||||
UINT16 maxLength;
|
||||
|
@ -929,7 +1073,7 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
|||
BOOL status = TRUE;
|
||||
wStream* fs = NULL;
|
||||
rdpSettings* settings;
|
||||
rdpRdp* rdp = fastpath->rdp;
|
||||
rdpRdp* rdp;
|
||||
UINT32 fpHeaderSize = 6;
|
||||
UINT32 fpUpdatePduHeaderSize;
|
||||
UINT32 fpUpdateHeaderSize;
|
||||
|
@ -937,9 +1081,16 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
|||
FASTPATH_UPDATE_PDU_HEADER fpUpdatePduHeader = { 0 };
|
||||
FASTPATH_UPDATE_HEADER fpUpdateHeader = { 0 };
|
||||
|
||||
if (!fastpath || !fastpath->rdp || !fastpath->fs || !s)
|
||||
return FALSE;
|
||||
|
||||
rdp = fastpath->rdp;
|
||||
fs = fastpath->fs;
|
||||
settings = rdp->settings;
|
||||
|
||||
if (!settings)
|
||||
return FALSE;
|
||||
|
||||
maxLength = FASTPATH_MAX_PACKET_SIZE - 20;
|
||||
|
||||
if (settings->CompressionEnabled && !skipCompression)
|
||||
|
@ -962,8 +1113,9 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
|||
/* check if the client's fast path pdu buffer is large enough */
|
||||
if (totalLength > settings->MultifragMaxRequestSize)
|
||||
{
|
||||
WLog_ERR(TAG, "fast path update size (%"PRIu32") exceeds the client's maximum request size (%"PRIu32")",
|
||||
totalLength, settings->MultifragMaxRequestSize);
|
||||
WLog_ERR(TAG,
|
||||
"fast path update size (%"PRIu32") exceeds the client's maximum request size (%"PRIu32")",
|
||||
totalLength, settings->MultifragMaxRequestSize);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -984,20 +1136,18 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
|||
UINT32 compressionFlags = 0;
|
||||
BYTE pad = 0;
|
||||
BYTE* pSignature = NULL;
|
||||
|
||||
fpUpdatePduHeader.action = 0;
|
||||
fpUpdatePduHeader.secFlags = 0;
|
||||
|
||||
fpUpdateHeader.compression = 0;
|
||||
fpUpdateHeader.compressionFlags = 0;
|
||||
fpUpdateHeader.updateCode = updateCode;
|
||||
fpUpdateHeader.size = (totalLength > maxLength) ? maxLength : totalLength;
|
||||
|
||||
pSrcData = pDstData = Stream_Pointer(s);
|
||||
SrcSize = DstSize = fpUpdateHeader.size;
|
||||
|
||||
if (rdp->sec_flags & SEC_ENCRYPT)
|
||||
fpUpdatePduHeader.secFlags |= FASTPATH_OUTPUT_ENCRYPTED;
|
||||
|
||||
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
|
||||
fpUpdatePduHeader.secFlags |= FASTPATH_OUTPUT_SECURE_CHECKSUM;
|
||||
|
||||
|
@ -1050,7 +1200,6 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
|||
}
|
||||
|
||||
fpUpdatePduHeader.length = fpUpdateHeader.size + fpHeaderSize + pad;
|
||||
|
||||
Stream_SetPosition(fs, 0);
|
||||
fastpath_write_update_pdu_header(fs, &fpUpdatePduHeader, rdp);
|
||||
fastpath_write_update_header(fs, &fpUpdateHeader);
|
||||
|
@ -1062,12 +1211,13 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
|||
if (rdp->sec_flags & SEC_ENCRYPT)
|
||||
{
|
||||
UINT32 dataSize = fpUpdateHeaderSize + DstSize + pad;
|
||||
BYTE *data = Stream_Pointer(fs) - dataSize;
|
||||
BYTE* data = Stream_Pointer(fs) - dataSize;
|
||||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
if (!security_hmac_signature(data, dataSize - pad, pSignature, rdp))
|
||||
return FALSE;
|
||||
|
||||
security_fips_encrypt(data, dataSize, rdp);
|
||||
}
|
||||
else
|
||||
|
@ -1094,26 +1244,25 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
|||
}
|
||||
|
||||
rdp->sec_flags = 0;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
rdpFastPath* fastpath_new(rdpRdp* rdp)
|
||||
{
|
||||
rdpFastPath* fastpath;
|
||||
|
||||
fastpath = (rdpFastPath*) calloc(1, sizeof(rdpFastPath));
|
||||
|
||||
if (!fastpath)
|
||||
return NULL;
|
||||
|
||||
fastpath->rdp = rdp;
|
||||
fastpath->fragmentation = -1;
|
||||
fastpath->fs = Stream_New(NULL, FASTPATH_MAX_PACKET_SIZE);
|
||||
|
||||
if (!fastpath->fs)
|
||||
goto out_free;
|
||||
|
||||
return fastpath;
|
||||
|
||||
out_free:
|
||||
free(fastpath);
|
||||
return NULL;
|
||||
|
|
|
@ -50,7 +50,6 @@ static void rpc_pdu_reset(RPC_PDU* pdu)
|
|||
RPC_PDU* rpc_pdu_new()
|
||||
{
|
||||
RPC_PDU* pdu;
|
||||
|
||||
pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU));
|
||||
|
||||
if (!pdu)
|
||||
|
@ -65,7 +64,6 @@ RPC_PDU* rpc_pdu_new()
|
|||
}
|
||||
|
||||
rpc_pdu_reset(pdu);
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
|
@ -82,7 +80,6 @@ int rpc_client_receive_pipe_write(rdpRpc* rpc, const BYTE* buffer, size_t length
|
|||
{
|
||||
int status = 0;
|
||||
RpcClient* client = rpc->client;
|
||||
|
||||
EnterCriticalSection(&(rpc->client->PipeLock));
|
||||
|
||||
if (ringbuffer_write(&(client->ReceivePipe), buffer, length))
|
||||
|
@ -92,7 +89,6 @@ int rpc_client_receive_pipe_write(rdpRpc* rpc, const BYTE* buffer, size_t length
|
|||
SetEvent(client->PipeEvent);
|
||||
|
||||
LeaveCriticalSection(&(rpc->client->PipeLock));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -103,9 +99,7 @@ int rpc_client_receive_pipe_read(rdpRpc* rpc, BYTE* buffer, size_t length)
|
|||
int nchunks = 0;
|
||||
DataChunk chunks[2];
|
||||
RpcClient* client = rpc->client;
|
||||
|
||||
EnterCriticalSection(&(client->PipeLock));
|
||||
|
||||
nchunks = ringbuffer_peek(&(client->ReceivePipe), chunks, length);
|
||||
|
||||
for (index = 0; index < nchunks; index++)
|
||||
|
@ -121,7 +115,6 @@ int rpc_client_receive_pipe_read(rdpRpc* rpc, BYTE* buffer, size_t length)
|
|||
ResetEvent(client->PipeEvent);
|
||||
|
||||
LeaveCriticalSection(&(client->PipeLock));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -132,42 +125,41 @@ int rpc_client_transition_to_state(rdpRpc* rpc, RPC_CLIENT_STATE state)
|
|||
|
||||
switch (state)
|
||||
{
|
||||
case RPC_CLIENT_STATE_INITIAL:
|
||||
str = "RPC_CLIENT_STATE_INITIAL";
|
||||
break;
|
||||
case RPC_CLIENT_STATE_INITIAL:
|
||||
str = "RPC_CLIENT_STATE_INITIAL";
|
||||
break;
|
||||
|
||||
case RPC_CLIENT_STATE_ESTABLISHED:
|
||||
str = "RPC_CLIENT_STATE_ESTABLISHED";
|
||||
break;
|
||||
case RPC_CLIENT_STATE_ESTABLISHED:
|
||||
str = "RPC_CLIENT_STATE_ESTABLISHED";
|
||||
break;
|
||||
|
||||
case RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK:
|
||||
str = "RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK";
|
||||
break;
|
||||
case RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK:
|
||||
str = "RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK";
|
||||
break;
|
||||
|
||||
case RPC_CLIENT_STATE_WAIT_UNSECURE_BIND_ACK:
|
||||
str = "RPC_CLIENT_STATE_WAIT_UNSECURE_BIND_ACK";
|
||||
break;
|
||||
case RPC_CLIENT_STATE_WAIT_UNSECURE_BIND_ACK:
|
||||
str = "RPC_CLIENT_STATE_WAIT_UNSECURE_BIND_ACK";
|
||||
break;
|
||||
|
||||
case RPC_CLIENT_STATE_WAIT_SECURE_ALTER_CONTEXT_RESPONSE:
|
||||
str = "RPC_CLIENT_STATE_WAIT_SECURE_ALTER_CONTEXT_RESPONSE";
|
||||
break;
|
||||
case RPC_CLIENT_STATE_WAIT_SECURE_ALTER_CONTEXT_RESPONSE:
|
||||
str = "RPC_CLIENT_STATE_WAIT_SECURE_ALTER_CONTEXT_RESPONSE";
|
||||
break;
|
||||
|
||||
case RPC_CLIENT_STATE_CONTEXT_NEGOTIATED:
|
||||
str = "RPC_CLIENT_STATE_CONTEXT_NEGOTIATED";
|
||||
break;
|
||||
case RPC_CLIENT_STATE_CONTEXT_NEGOTIATED:
|
||||
str = "RPC_CLIENT_STATE_CONTEXT_NEGOTIATED";
|
||||
break;
|
||||
|
||||
case RPC_CLIENT_STATE_WAIT_RESPONSE:
|
||||
str = "RPC_CLIENT_STATE_WAIT_RESPONSE";
|
||||
break;
|
||||
case RPC_CLIENT_STATE_WAIT_RESPONSE:
|
||||
str = "RPC_CLIENT_STATE_WAIT_RESPONSE";
|
||||
break;
|
||||
|
||||
case RPC_CLIENT_STATE_FINAL:
|
||||
str = "RPC_CLIENT_STATE_FINAL";
|
||||
break;
|
||||
case RPC_CLIENT_STATE_FINAL:
|
||||
str = "RPC_CLIENT_STATE_FINAL";
|
||||
break;
|
||||
}
|
||||
|
||||
rpc->State = state;
|
||||
WLog_DBG(TAG, "%s", str);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -181,77 +173,70 @@ int rpc_client_recv_pdu(rdpRpc* rpc, RPC_PDU* pdu)
|
|||
{
|
||||
switch (rpc->VirtualConnection->State)
|
||||
{
|
||||
case VIRTUAL_CONNECTION_STATE_INITIAL:
|
||||
break;
|
||||
case VIRTUAL_CONNECTION_STATE_INITIAL:
|
||||
break;
|
||||
|
||||
case VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT:
|
||||
break;
|
||||
case VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT:
|
||||
break;
|
||||
|
||||
case VIRTUAL_CONNECTION_STATE_WAIT_A3W:
|
||||
case VIRTUAL_CONNECTION_STATE_WAIT_A3W:
|
||||
rts = (rpcconn_rts_hdr_t*) Stream_Buffer(pdu->s);
|
||||
|
||||
rts = (rpcconn_rts_hdr_t*) Stream_Buffer(pdu->s);
|
||||
if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_A3_SIGNATURE, rts))
|
||||
{
|
||||
WLog_ERR(TAG, "unexpected RTS PDU: Expected CONN/A3");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_A3_SIGNATURE, rts))
|
||||
{
|
||||
WLog_ERR(TAG, "unexpected RTS PDU: Expected CONN/A3");
|
||||
return -1;
|
||||
}
|
||||
status = rts_recv_CONN_A3_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s));
|
||||
|
||||
status = rts_recv_CONN_A3_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s));
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rts_recv_CONN_A3_pdu failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rts_recv_CONN_A3_pdu failure");
|
||||
return -1;
|
||||
}
|
||||
rpc_virtual_connection_transition_to_state(rpc,
|
||||
rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_C2);
|
||||
status = 1;
|
||||
break;
|
||||
|
||||
rpc_virtual_connection_transition_to_state(rpc,
|
||||
rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_C2);
|
||||
case VIRTUAL_CONNECTION_STATE_WAIT_C2:
|
||||
rts = (rpcconn_rts_hdr_t*) Stream_Buffer(pdu->s);
|
||||
|
||||
status = 1;
|
||||
if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts))
|
||||
{
|
||||
WLog_ERR(TAG, "unexpected RTS PDU: Expected CONN/C2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
status = rts_recv_CONN_C2_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s));
|
||||
|
||||
case VIRTUAL_CONNECTION_STATE_WAIT_C2:
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rts_recv_CONN_C2_pdu failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rts = (rpcconn_rts_hdr_t*) Stream_Buffer(pdu->s);
|
||||
rpc_virtual_connection_transition_to_state(rpc,
|
||||
rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_OPENED);
|
||||
rpc_client_transition_to_state(rpc, RPC_CLIENT_STATE_ESTABLISHED);
|
||||
|
||||
if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts))
|
||||
{
|
||||
WLog_ERR(TAG, "unexpected RTS PDU: Expected CONN/C2");
|
||||
return -1;
|
||||
}
|
||||
if (rpc_send_bind_pdu(rpc) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_send_bind_pdu failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = rts_recv_CONN_C2_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s));
|
||||
rpc_client_transition_to_state(rpc, RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK);
|
||||
status = 1;
|
||||
break;
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rts_recv_CONN_C2_pdu failure");
|
||||
return -1;
|
||||
}
|
||||
case VIRTUAL_CONNECTION_STATE_OPENED:
|
||||
break;
|
||||
|
||||
rpc_virtual_connection_transition_to_state(rpc,
|
||||
rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_OPENED);
|
||||
|
||||
rpc_client_transition_to_state(rpc, RPC_CLIENT_STATE_ESTABLISHED);
|
||||
|
||||
if (rpc_send_bind_pdu(rpc) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_send_bind_pdu failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rpc_client_transition_to_state(rpc, RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK);
|
||||
|
||||
status = 1;
|
||||
|
||||
break;
|
||||
|
||||
case VIRTUAL_CONNECTION_STATE_OPENED:
|
||||
break;
|
||||
|
||||
case VIRTUAL_CONNECTION_STATE_FINAL:
|
||||
break;
|
||||
case VIRTUAL_CONNECTION_STATE_FINAL:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (rpc->State < RPC_CLIENT_STATE_CONTEXT_NEGOTIATED)
|
||||
|
@ -268,7 +253,8 @@ int rpc_client_recv_pdu(rdpRpc* rpc, RPC_PDU* pdu)
|
|||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK unexpected pdu type: 0x%08"PRIX32"", pdu->Type);
|
||||
WLog_ERR(TAG, "RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK unexpected pdu type: 0x%08"PRIX32"",
|
||||
pdu->Type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -309,7 +295,6 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment)
|
|||
UINT32 StubLength;
|
||||
RpcClientCall* call;
|
||||
rpcconn_hdr_t* header;
|
||||
|
||||
pdu = rpc->client->pdu;
|
||||
buffer = (BYTE*) Stream_Buffer(fragment);
|
||||
header = (rpcconn_hdr_t*) Stream_Buffer(fragment);
|
||||
|
@ -337,9 +322,7 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment)
|
|||
{
|
||||
/* End of TsProxySetupReceivePipe */
|
||||
TerminateEventArgs e;
|
||||
|
||||
rpc->result = *((UINT32*) &buffer[StubOffset]);
|
||||
|
||||
freerdp_abort_connect(rpc->context->instance);
|
||||
rpc->transport->tsg->state = TSG_STATE_TUNNEL_CLOSE_PENDING;
|
||||
EventArgsInit(&e, "freerdp");
|
||||
|
@ -361,7 +344,7 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment)
|
|||
if (rpc->StubCallId != header->common.call_id)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid call_id: actual: %"PRIu32", expected: %"PRIu32", frag_count: %"PRIu32"",
|
||||
rpc->StubCallId, header->common.call_id, rpc->StubFragCount);
|
||||
rpc->StubCallId, header->common.call_id, rpc->StubFragCount);
|
||||
}
|
||||
|
||||
call = rpc_client_call_find_by_id(rpc, rpc->StubCallId);
|
||||
|
@ -373,6 +356,7 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment)
|
|||
{
|
||||
if (!Stream_EnsureCapacity(pdu->s, header->response.alloc_hint))
|
||||
return -1;
|
||||
|
||||
Stream_Write(pdu->s, &buffer[StubOffset], StubLength);
|
||||
rpc->StubFragCount++;
|
||||
|
||||
|
@ -409,12 +393,16 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment)
|
|||
pdu->Flags = 0;
|
||||
pdu->Type = header->common.ptype;
|
||||
pdu->CallId = header->common.call_id;
|
||||
|
||||
if (!Stream_EnsureCapacity(pdu->s, Stream_Length(fragment)))
|
||||
return -1;
|
||||
|
||||
Stream_Write(pdu->s, buffer, Stream_Length(fragment));
|
||||
Stream_SealLength(pdu->s);
|
||||
|
||||
if (rpc_client_recv_pdu(rpc, pdu) < 0)
|
||||
return -1;
|
||||
|
||||
rpc_pdu_reset(pdu);
|
||||
}
|
||||
else
|
||||
|
@ -433,14 +421,17 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment)
|
|||
pdu->Flags = 0;
|
||||
pdu->Type = header->common.ptype;
|
||||
pdu->CallId = header->common.call_id;
|
||||
|
||||
if (!Stream_EnsureCapacity(pdu->s, Stream_Length(fragment)))
|
||||
return -1;
|
||||
|
||||
Stream_Write(pdu->s, buffer, Stream_Length(fragment));
|
||||
Stream_SealLength(pdu->s);
|
||||
|
||||
if (rpc_client_recv_pdu(rpc, pdu) < 0)
|
||||
return -1;
|
||||
rpc_pdu_reset(pdu);
|
||||
|
||||
rpc_pdu_reset(pdu);
|
||||
return 1;
|
||||
}
|
||||
else if (header->common.ptype == PTYPE_FAULT)
|
||||
|
@ -466,10 +457,8 @@ int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
|||
RpcOutChannel* outChannel;
|
||||
HANDLE outChannelEvent = NULL;
|
||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
|
||||
inChannel = connection->DefaultInChannel;
|
||||
outChannel = connection->DefaultOutChannel;
|
||||
|
||||
BIO_get_event(outChannel->tls->bio, &outChannelEvent);
|
||||
|
||||
if (outChannel->State < CLIENT_OUT_CHANNEL_STATE_OPENED)
|
||||
|
@ -485,7 +474,6 @@ int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
|||
if (outChannel->State == CLIENT_OUT_CHANNEL_STATE_SECURITY)
|
||||
{
|
||||
/* Receive OUT Channel Response */
|
||||
|
||||
if (rpc_ncacn_http_recv_out_channel_response(rpc, outChannel, response) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_ncacn_http_recv_out_channel_response failure");
|
||||
|
@ -501,9 +489,8 @@ int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
|||
}
|
||||
|
||||
rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*)outChannel);
|
||||
|
||||
rpc_out_channel_transition_to_state(outChannel,
|
||||
CLIENT_OUT_CHANNEL_STATE_NEGOTIATED);
|
||||
CLIENT_OUT_CHANNEL_STATE_NEGOTIATED);
|
||||
|
||||
/* Send CONN/A1 PDU over OUT channel */
|
||||
|
||||
|
@ -514,12 +501,12 @@ int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
|||
}
|
||||
|
||||
rpc_out_channel_transition_to_state(outChannel,
|
||||
CLIENT_OUT_CHANNEL_STATE_OPENED);
|
||||
CLIENT_OUT_CHANNEL_STATE_OPENED);
|
||||
|
||||
if (inChannel->State == CLIENT_IN_CHANNEL_STATE_OPENED)
|
||||
{
|
||||
rpc_virtual_connection_transition_to_state(rpc,
|
||||
connection, VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT);
|
||||
connection, VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT);
|
||||
}
|
||||
|
||||
status = 1;
|
||||
|
@ -530,7 +517,6 @@ int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
|||
else if (connection->State == VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT)
|
||||
{
|
||||
/* Receive OUT channel response */
|
||||
|
||||
if (WaitForSingleObject(outChannelEvent, 0) != WAIT_OBJECT_0)
|
||||
return 1;
|
||||
|
||||
|
@ -557,17 +543,14 @@ int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
|||
}
|
||||
|
||||
http_response_free(response);
|
||||
|
||||
rpc_virtual_connection_transition_to_state(rpc,
|
||||
rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_A3W);
|
||||
|
||||
rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_A3W);
|
||||
status = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
wStream* fragment;
|
||||
rpcconn_common_hdr_t* header;
|
||||
|
||||
fragment = rpc->client->ReceiveFragment;
|
||||
|
||||
while (1)
|
||||
|
@ -575,7 +558,7 @@ int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
|||
while (Stream_GetPosition(fragment) < RPC_COMMON_FIELDS_LENGTH)
|
||||
{
|
||||
status = rpc_out_channel_read(outChannel, Stream_Pointer(fragment),
|
||||
RPC_COMMON_FIELDS_LENGTH - Stream_GetPosition(fragment));
|
||||
RPC_COMMON_FIELDS_LENGTH - Stream_GetPosition(fragment));
|
||||
|
||||
if (status < 0)
|
||||
return -1;
|
||||
|
@ -594,7 +577,7 @@ int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
|||
if (header->frag_length > rpc->max_recv_frag)
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_client_recv: invalid fragment size: %"PRIu16" (max: %"PRIu16")",
|
||||
header->frag_length, rpc->max_recv_frag);
|
||||
header->frag_length, rpc->max_recv_frag);
|
||||
winpr_HexDump(TAG, WLOG_ERROR, Stream_Buffer(fragment), Stream_GetPosition(fragment));
|
||||
return -1;
|
||||
}
|
||||
|
@ -602,7 +585,7 @@ int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
|||
while (Stream_GetPosition(fragment) < header->frag_length)
|
||||
{
|
||||
status = rpc_out_channel_read(outChannel, Stream_Pointer(fragment),
|
||||
header->frag_length - Stream_GetPosition(fragment));
|
||||
header->frag_length - Stream_GetPosition(fragment));
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
|
@ -622,26 +605,22 @@ int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
|||
if (Stream_GetPosition(fragment) >= header->frag_length)
|
||||
{
|
||||
/* complete fragment received */
|
||||
|
||||
Stream_SealLength(fragment);
|
||||
Stream_SetPosition(fragment, 0);
|
||||
|
||||
status = rpc_client_recv_fragment(rpc, fragment);
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
/* channel recycling may update channel pointers */
|
||||
inChannel = connection->DefaultInChannel;
|
||||
if (outChannel->State == CLIENT_OUT_CHANNEL_STATE_RECYCLED && connection->NonDefaultOutChannel)
|
||||
{
|
||||
rpc_out_channel_free(connection->DefaultOutChannel);
|
||||
connection->DefaultOutChannel = connection->NonDefaultOutChannel;
|
||||
connection->NonDefaultOutChannel = NULL;
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED);
|
||||
rpc_virtual_connection_transition_to_state(rpc, connection, VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT);
|
||||
|
||||
rpc_virtual_connection_transition_to_state(rpc, connection,
|
||||
VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -659,9 +638,7 @@ int rpc_client_nondefault_out_channel_recv(rdpRpc* rpc)
|
|||
HttpResponse* response;
|
||||
RpcOutChannel* nextOutChannel;
|
||||
HANDLE nextOutChannelEvent = NULL;
|
||||
|
||||
nextOutChannel = rpc->VirtualConnection->NonDefaultOutChannel;
|
||||
|
||||
BIO_get_event(nextOutChannel->tls->bio, &nextOutChannelEvent);
|
||||
|
||||
if (WaitForSingleObject(nextOutChannelEvent, 0) != WAIT_OBJECT_0)
|
||||
|
@ -682,7 +659,6 @@ int rpc_client_nondefault_out_channel_recv(rdpRpc* rpc)
|
|||
if (status >= 0)
|
||||
{
|
||||
rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*) nextOutChannel);
|
||||
|
||||
status = rts_send_OUT_R1_A3_pdu(rpc);
|
||||
|
||||
if (status >= 0)
|
||||
|
@ -743,10 +719,8 @@ int rpc_client_in_channel_recv(rdpRpc* rpc)
|
|||
RpcOutChannel* outChannel;
|
||||
HANDLE InChannelEvent = NULL;
|
||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
|
||||
inChannel = connection->DefaultInChannel;
|
||||
outChannel = connection->DefaultOutChannel;
|
||||
|
||||
BIO_get_event(inChannel->tls->bio, &InChannelEvent);
|
||||
|
||||
if (WaitForSingleObject(InChannelEvent, 0) != WAIT_OBJECT_0)
|
||||
|
@ -776,9 +750,8 @@ int rpc_client_in_channel_recv(rdpRpc* rpc)
|
|||
}
|
||||
|
||||
rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*) inChannel);
|
||||
|
||||
rpc_in_channel_transition_to_state(inChannel,
|
||||
CLIENT_IN_CHANNEL_STATE_NEGOTIATED);
|
||||
CLIENT_IN_CHANNEL_STATE_NEGOTIATED);
|
||||
|
||||
/* Send CONN/B1 PDU over IN channel */
|
||||
|
||||
|
@ -789,12 +762,12 @@ int rpc_client_in_channel_recv(rdpRpc* rpc)
|
|||
}
|
||||
|
||||
rpc_in_channel_transition_to_state(inChannel,
|
||||
CLIENT_IN_CHANNEL_STATE_OPENED);
|
||||
CLIENT_IN_CHANNEL_STATE_OPENED);
|
||||
|
||||
if (outChannel->State == CLIENT_OUT_CHANNEL_STATE_OPENED)
|
||||
{
|
||||
rpc_virtual_connection_transition_to_state(rpc,
|
||||
connection, VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT);
|
||||
connection, VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT);
|
||||
}
|
||||
|
||||
status = 1;
|
||||
|
@ -810,7 +783,6 @@ int rpc_client_in_channel_recv(rdpRpc* rpc)
|
|||
return -1;
|
||||
|
||||
/* We can receive an unauthorized HTTP response on the IN channel */
|
||||
|
||||
http_response_free(response);
|
||||
}
|
||||
|
||||
|
@ -827,9 +799,7 @@ RpcClientCall* rpc_client_call_find_by_id(rdpRpc* rpc, UINT32 CallId)
|
|||
int index;
|
||||
int count;
|
||||
RpcClientCall* clientCall = NULL;
|
||||
|
||||
ArrayList_Lock(rpc->client->ClientCallList);
|
||||
|
||||
count = ArrayList_Count(rpc->client->ClientCallList);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
|
@ -841,14 +811,12 @@ RpcClientCall* rpc_client_call_find_by_id(rdpRpc* rpc, UINT32 CallId)
|
|||
}
|
||||
|
||||
ArrayList_Unlock(rpc->client->ClientCallList);
|
||||
|
||||
return clientCall;
|
||||
}
|
||||
|
||||
RpcClientCall* rpc_client_call_new(UINT32 CallId, UINT32 OpNum)
|
||||
{
|
||||
RpcClientCall* clientCall;
|
||||
|
||||
clientCall = (RpcClientCall*) calloc(1, sizeof(RpcClientCall));
|
||||
|
||||
if (!clientCall)
|
||||
|
@ -857,7 +825,6 @@ RpcClientCall* rpc_client_call_new(UINT32 CallId, UINT32 OpNum)
|
|||
clientCall->CallId = CallId;
|
||||
clientCall->OpNum = OpNum;
|
||||
clientCall->State = RPC_CLIENT_CALL_STATE_SEND_PDUS;
|
||||
|
||||
return clientCall;
|
||||
}
|
||||
|
||||
|
@ -872,7 +839,6 @@ int rpc_in_channel_send_pdu(RpcInChannel* inChannel, BYTE* buffer, UINT32 length
|
|||
RpcClientCall* clientCall;
|
||||
rpcconn_common_hdr_t* header;
|
||||
rdpRpc* rpc = inChannel->rpc;
|
||||
|
||||
status = rpc_in_channel_write(inChannel, buffer, length);
|
||||
|
||||
if (status <= 0)
|
||||
|
@ -883,11 +849,11 @@ int rpc_in_channel_send_pdu(RpcInChannel* inChannel, BYTE* buffer, UINT32 length
|
|||
clientCall->State = RPC_CLIENT_CALL_STATE_DISPATCHED;
|
||||
|
||||
/*
|
||||
* This protocol specifies that only RPC PDUs are subject to the flow control abstract
|
||||
* data model. RTS PDUs and the HTTP request and response headers are not subject to flow control.
|
||||
* Implementations of this protocol MUST NOT include them when computing any of the variables
|
||||
* specified by this abstract data model.
|
||||
*/
|
||||
* This protocol specifies that only RPC PDUs are subject to the flow control abstract
|
||||
* data model. RTS PDUs and the HTTP request and response headers are not subject to flow control.
|
||||
* Implementations of this protocol MUST NOT include them when computing any of the variables
|
||||
* specified by this abstract data model.
|
||||
*/
|
||||
|
||||
if (header->ptype == PTYPE_REQUEST)
|
||||
{
|
||||
|
@ -919,16 +885,17 @@ int rpc_client_write_call(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
|||
return -1;
|
||||
}
|
||||
|
||||
status = ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes);
|
||||
status = ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES,
|
||||
&ntlm->ContextSizes);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure %s [0x%08"PRIX32"]",
|
||||
GetSecurityStatusString(status), status);
|
||||
GetSecurityStatusString(status), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ZeroMemory(&Buffers, sizeof(Buffers));
|
||||
|
||||
request_pdu = (rpcconn_request_hdr_t*) calloc(1, sizeof(rpcconn_request_hdr_t));
|
||||
|
||||
if (!request_pdu)
|
||||
|
@ -942,7 +909,6 @@ int rpc_client_write_call(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
|||
request_pdu->alloc_hint = length;
|
||||
request_pdu->p_cont_id = 0x0000;
|
||||
request_pdu->opnum = opnum;
|
||||
|
||||
clientCall = rpc_client_call_new(request_pdu->call_id, request_pdu->opnum);
|
||||
|
||||
if (!clientCall)
|
||||
|
@ -956,7 +922,6 @@ int rpc_client_write_call(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
|||
|
||||
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);
|
||||
|
@ -966,7 +931,6 @@ int rpc_client_write_call(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
|||
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)
|
||||
|
@ -998,7 +962,7 @@ int rpc_client_write_call(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
|||
if (encrypt_status != SEC_E_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "EncryptMessage status %s [0x%08"PRIX32"]",
|
||||
GetSecurityStatusString(encrypt_status), encrypt_status);
|
||||
GetSecurityStatusString(encrypt_status), encrypt_status);
|
||||
goto out_free_pdu;
|
||||
}
|
||||
|
||||
|
@ -1011,9 +975,7 @@ int rpc_client_write_call(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
|||
|
||||
free(request_pdu);
|
||||
free(buffer);
|
||||
|
||||
return length;
|
||||
|
||||
out_free_clientCall:
|
||||
rpc_client_call_free(clientCall);
|
||||
out_free_pdu:
|
||||
|
@ -1026,9 +988,7 @@ out_free_pdu:
|
|||
int rpc_client_new(rdpRpc* rpc)
|
||||
{
|
||||
RpcClient* client;
|
||||
|
||||
client = (RpcClient*) calloc(1, sizeof(RpcClient));
|
||||
|
||||
rpc->client = client;
|
||||
|
||||
if (!client)
|
||||
|
@ -1056,11 +1016,11 @@ int rpc_client_new(rdpRpc* rpc)
|
|||
return -1;
|
||||
|
||||
client->ClientCallList = ArrayList_New(TRUE);
|
||||
|
||||
if (!client->ClientCallList)
|
||||
return -1;
|
||||
|
||||
ArrayList_Object(client->ClientCallList)->fnObjectFree = (OBJECT_FREE_FN) rpc_client_call_free;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1078,7 +1038,6 @@ void rpc_client_free(rdpRpc* rpc)
|
|||
CloseHandle(client->PipeEvent);
|
||||
|
||||
ringbuffer_destroy(&(client->ReceivePipe));
|
||||
|
||||
DeleteCriticalSection(&(client->PipeLock));
|
||||
|
||||
if (client->pdu)
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#define TAG FREERDP_TAG("core.gateway.rts")
|
||||
|
||||
const char* const RTS_CMD_STRINGS[] =
|
||||
static const char* const RTS_CMD_STRINGS[] =
|
||||
{
|
||||
"ReceiveWindowSize",
|
||||
"FlowControlAck",
|
||||
|
@ -84,7 +84,7 @@ const char* const RTS_CMD_STRINGS[] =
|
|||
*
|
||||
*/
|
||||
|
||||
void rts_pdu_header_init(rpcconn_rts_hdr_t* header)
|
||||
static void rts_pdu_header_init(rpcconn_rts_hdr_t* header)
|
||||
{
|
||||
ZeroMemory(header, sizeof(*header));
|
||||
header->rpc_vers = 5;
|
||||
|
@ -99,7 +99,8 @@ void rts_pdu_header_init(rpcconn_rts_hdr_t* header)
|
|||
header->call_id = 0;
|
||||
}
|
||||
|
||||
int rts_receive_window_size_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length, UINT32* ReceiveWindowSize)
|
||||
int rts_receive_window_size_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length,
|
||||
UINT32* ReceiveWindowSize)
|
||||
{
|
||||
if (ReceiveWindowSize)
|
||||
*ReceiveWindowSize = *((UINT32*) &buffer[0]); /* ReceiveWindowSize (4 bytes) */
|
||||
|
@ -119,10 +120,9 @@ int rts_receive_window_size_command_write(BYTE* buffer, UINT32 ReceiveWindowSize
|
|||
}
|
||||
|
||||
int rts_flow_control_ack_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length,
|
||||
UINT32* BytesReceived, UINT32* AvailableWindow, BYTE* ChannelCookie)
|
||||
UINT32* BytesReceived, UINT32* AvailableWindow, BYTE* ChannelCookie)
|
||||
{
|
||||
/* Ack (24 bytes) */
|
||||
|
||||
if (BytesReceived)
|
||||
*BytesReceived = *((UINT32*) &buffer[0]); /* BytesReceived (4 bytes) */
|
||||
|
||||
|
@ -135,12 +135,12 @@ int rts_flow_control_ack_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length,
|
|||
return 24;
|
||||
}
|
||||
|
||||
int rts_flow_control_ack_command_write(BYTE* buffer, UINT32 BytesReceived, UINT32 AvailableWindow, BYTE* ChannelCookie)
|
||||
int rts_flow_control_ack_command_write(BYTE* buffer, UINT32 BytesReceived, UINT32 AvailableWindow,
|
||||
BYTE* ChannelCookie)
|
||||
{
|
||||
if (buffer)
|
||||
{
|
||||
*((UINT32*) &buffer[0]) = RTS_CMD_FLOW_CONTROL_ACK; /* CommandType (4 bytes) */
|
||||
|
||||
/* Ack (24 bytes) */
|
||||
*((UINT32*) &buffer[4]) = BytesReceived; /* BytesReceived (4 bytes) */
|
||||
*((UINT32*) &buffer[8]) = AvailableWindow; /* AvailableWindow (4 bytes) */
|
||||
|
@ -150,7 +150,8 @@ int rts_flow_control_ack_command_write(BYTE* buffer, UINT32 BytesReceived, UINT3
|
|||
return 28;
|
||||
}
|
||||
|
||||
int rts_connection_timeout_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length, UINT32* ConnectionTimeout)
|
||||
int rts_connection_timeout_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length,
|
||||
UINT32* ConnectionTimeout)
|
||||
{
|
||||
if (ConnectionTimeout)
|
||||
*ConnectionTimeout = *((UINT32*) &buffer[0]); /* ConnectionTimeout (4 bytes) */
|
||||
|
@ -172,7 +173,6 @@ int rts_connection_timeout_command_write(BYTE* buffer, UINT32 ConnectionTimeout)
|
|||
int rts_cookie_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
/* Cookie (16 bytes) */
|
||||
|
||||
return 16;
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,6 @@ int rts_cookie_command_write(BYTE* buffer, BYTE* Cookie)
|
|||
int rts_channel_lifetime_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
/* ChannelLifetime (4 bytes) */
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
@ -208,7 +207,6 @@ int rts_channel_lifetime_command_write(BYTE* buffer, UINT32 ChannelLifetime)
|
|||
int rts_client_keepalive_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
/* ClientKeepalive (4 bytes) */
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
@ -219,7 +217,6 @@ int rts_client_keepalive_command_write(BYTE* buffer, UINT32 ClientKeepalive)
|
|||
* that this connection is configured to use. This value MUST be 0 or in the inclusive
|
||||
* range of 60,000 through 4,294,967,295. If it is 0, it MUST be interpreted as 300,000.
|
||||
*/
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
*((UINT32*) &buffer[0]) = RTS_CMD_CLIENT_KEEPALIVE; /* CommandType (4 bytes) */
|
||||
|
@ -232,7 +229,6 @@ int rts_client_keepalive_command_write(BYTE* buffer, UINT32 ClientKeepalive)
|
|||
int rts_version_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
/* Version (4 bytes) */
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
@ -265,10 +261,8 @@ int rts_empty_command_write(BYTE* buffer)
|
|||
int rts_padding_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
UINT32 ConformanceCount;
|
||||
|
||||
ConformanceCount = *((UINT32*) &buffer[0]); /* ConformanceCount (4 bytes) */
|
||||
/* Padding (variable) */
|
||||
|
||||
return ConformanceCount + 4;
|
||||
}
|
||||
|
||||
|
@ -317,21 +311,18 @@ int rts_ance_command_write(BYTE* buffer)
|
|||
int rts_client_address_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
UINT32 AddressType;
|
||||
|
||||
AddressType = *((UINT32*) &buffer[0]); /* AddressType (4 bytes) */
|
||||
|
||||
if (AddressType == 0)
|
||||
{
|
||||
/* ClientAddress (4 bytes) */
|
||||
/* padding (12 bytes) */
|
||||
|
||||
return 4 + 4 + 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ClientAddress (16 bytes) */
|
||||
/* padding (12 bytes) */
|
||||
|
||||
return 4 + 16 + 12;
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +360,6 @@ int rts_client_address_command_write(BYTE* buffer, UINT32 AddressType, BYTE* Cli
|
|||
int rts_association_group_id_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
/* AssociationGroupId (16 bytes) */
|
||||
|
||||
return 16;
|
||||
}
|
||||
|
||||
|
@ -406,7 +396,6 @@ int rts_destination_command_write(BYTE* buffer, UINT32 Destination)
|
|||
int rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
/* PingTrafficSent (4 bytes) */
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
@ -438,18 +427,14 @@ int rts_send_CONN_A1_pdu(rdpRpc* rpc)
|
|||
BYTE* VirtualConnectionCookie;
|
||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
RpcOutChannel* outChannel = connection->DefaultOutChannel;
|
||||
|
||||
rts_pdu_header_init(&header);
|
||||
header.frag_length = 76;
|
||||
header.Flags = RTS_FLAG_NONE;
|
||||
header.NumberOfCommands = 4;
|
||||
|
||||
WLog_DBG(TAG, "Sending CONN/A1 RTS PDU");
|
||||
|
||||
VirtualConnectionCookie = (BYTE*) &(connection->Cookie);
|
||||
OUTChannelCookie = (BYTE*) &(outChannel->Cookie);
|
||||
VirtualConnectionCookie = (BYTE*) & (connection->Cookie);
|
||||
OUTChannelCookie = (BYTE*) & (outChannel->Cookie);
|
||||
ReceiveWindowSize = outChannel->ReceiveWindow;
|
||||
|
||||
buffer = (BYTE*) malloc(header.frag_length);
|
||||
|
||||
if (!buffer)
|
||||
|
@ -457,27 +442,22 @@ int rts_send_CONN_A1_pdu(rdpRpc* rpc)
|
|||
|
||||
CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
|
||||
rts_version_command_write(&buffer[20]); /* Version (8 bytes) */
|
||||
rts_cookie_command_write(&buffer[28], VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
|
||||
rts_cookie_command_write(&buffer[28],
|
||||
VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
|
||||
rts_cookie_command_write(&buffer[48], OUTChannelCookie); /* OUTChannelCookie (20 bytes) */
|
||||
rts_receive_window_size_command_write(&buffer[68], ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
|
||||
|
||||
rts_receive_window_size_command_write(&buffer[68],
|
||||
ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
|
||||
status = rpc_out_channel_write(outChannel, buffer, header.frag_length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (status > 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
int rts_recv_CONN_A3_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
UINT32 ConnectionTimeout;
|
||||
|
||||
rts_connection_timeout_command_read(rpc, &buffer[24], length - 24, &ConnectionTimeout);
|
||||
|
||||
WLog_DBG(TAG, "Receiving CONN/A3 RTS PDU: ConnectionTimeout: %"PRIu32"", ConnectionTimeout);
|
||||
|
||||
rpc->VirtualConnection->DefaultInChannel->PingOriginator.ConnectionTimeout = ConnectionTimeout;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -494,18 +474,14 @@ int rts_send_CONN_B1_pdu(rdpRpc* rpc)
|
|||
BYTE* VirtualConnectionCookie;
|
||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
RpcInChannel* inChannel = connection->DefaultInChannel;
|
||||
|
||||
rts_pdu_header_init(&header);
|
||||
header.frag_length = 104;
|
||||
header.Flags = RTS_FLAG_NONE;
|
||||
header.NumberOfCommands = 6;
|
||||
|
||||
WLog_DBG(TAG, "Sending CONN/B1 RTS PDU");
|
||||
|
||||
VirtualConnectionCookie = (BYTE*) &(connection->Cookie);
|
||||
INChannelCookie = (BYTE*) &(inChannel->Cookie);
|
||||
AssociationGroupId = (BYTE*) &(connection->AssociationGroupId);
|
||||
|
||||
VirtualConnectionCookie = (BYTE*) & (connection->Cookie);
|
||||
INChannelCookie = (BYTE*) & (inChannel->Cookie);
|
||||
AssociationGroupId = (BYTE*) & (connection->AssociationGroupId);
|
||||
buffer = (BYTE*) malloc(header.frag_length);
|
||||
|
||||
if (!buffer)
|
||||
|
@ -513,18 +489,18 @@ int rts_send_CONN_B1_pdu(rdpRpc* rpc)
|
|||
|
||||
CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
|
||||
rts_version_command_write(&buffer[20]); /* Version (8 bytes) */
|
||||
rts_cookie_command_write(&buffer[28], VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
|
||||
rts_cookie_command_write(&buffer[28],
|
||||
VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
|
||||
rts_cookie_command_write(&buffer[48], INChannelCookie); /* INChannelCookie (20 bytes) */
|
||||
rts_channel_lifetime_command_write(&buffer[68], rpc->ChannelLifetime); /* ChannelLifetime (8 bytes) */
|
||||
rts_client_keepalive_command_write(&buffer[76], rpc->KeepAliveInterval); /* ClientKeepalive (8 bytes) */
|
||||
rts_association_group_id_command_write(&buffer[84], AssociationGroupId); /* AssociationGroupId (20 bytes) */
|
||||
|
||||
rts_channel_lifetime_command_write(&buffer[68],
|
||||
rpc->ChannelLifetime); /* ChannelLifetime (8 bytes) */
|
||||
rts_client_keepalive_command_write(&buffer[76],
|
||||
rpc->KeepAliveInterval); /* ClientKeepalive (8 bytes) */
|
||||
rts_association_group_id_command_write(&buffer[84],
|
||||
AssociationGroupId); /* AssociationGroupId (20 bytes) */
|
||||
length = header.frag_length;
|
||||
|
||||
status = rpc_in_channel_write(inChannel, buffer, length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (status > 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
|
@ -535,18 +511,17 @@ int rts_recv_CONN_C2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
|||
UINT32 offset;
|
||||
UINT32 ReceiveWindowSize;
|
||||
UINT32 ConnectionTimeout;
|
||||
|
||||
offset = 24;
|
||||
offset += rts_version_command_read(rpc, &buffer[offset], length - offset) + 4;
|
||||
offset += rts_receive_window_size_command_read(rpc, &buffer[offset], length - offset, &ReceiveWindowSize) + 4;
|
||||
offset += rts_connection_timeout_command_read(rpc, &buffer[offset], length - offset, &ConnectionTimeout) + 4;
|
||||
|
||||
WLog_DBG(TAG, "Receiving CONN/C2 RTS PDU: ConnectionTimeout: %"PRIu32" ReceiveWindowSize: %"PRIu32"",
|
||||
ConnectionTimeout, ReceiveWindowSize);
|
||||
|
||||
offset += rts_receive_window_size_command_read(rpc, &buffer[offset], length - offset,
|
||||
&ReceiveWindowSize) + 4;
|
||||
offset += rts_connection_timeout_command_read(rpc, &buffer[offset], length - offset,
|
||||
&ConnectionTimeout) + 4;
|
||||
WLog_DBG(TAG,
|
||||
"Receiving CONN/C2 RTS PDU: ConnectionTimeout: %"PRIu32" ReceiveWindowSize: %"PRIu32"",
|
||||
ConnectionTimeout, ReceiveWindowSize);
|
||||
rpc->VirtualConnection->DefaultInChannel->PingOriginator.ConnectionTimeout = ConnectionTimeout;
|
||||
rpc->VirtualConnection->DefaultInChannel->PeerReceiveWindow = ReceiveWindowSize;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -559,28 +534,22 @@ int rts_send_keep_alive_pdu(rdpRpc* rpc)
|
|||
UINT32 length;
|
||||
rpcconn_rts_hdr_t header;
|
||||
RpcInChannel* inChannel = rpc->VirtualConnection->DefaultInChannel;
|
||||
|
||||
rts_pdu_header_init(&header);
|
||||
header.frag_length = 28;
|
||||
header.Flags = RTS_FLAG_OTHER_CMD;
|
||||
header.NumberOfCommands = 1;
|
||||
|
||||
WLog_DBG(TAG, "Sending Keep-Alive RTS PDU");
|
||||
|
||||
buffer = (BYTE*) malloc(header.frag_length);
|
||||
|
||||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
|
||||
rts_client_keepalive_command_write(&buffer[20], rpc->CurrentKeepAliveInterval); /* ClientKeepAlive (8 bytes) */
|
||||
|
||||
rts_client_keepalive_command_write(&buffer[20],
|
||||
rpc->CurrentKeepAliveInterval); /* ClientKeepAlive (8 bytes) */
|
||||
length = header.frag_length;
|
||||
|
||||
status = rpc_in_channel_write(inChannel, buffer, length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (status > 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
|
@ -596,20 +565,15 @@ int rts_send_flow_control_ack_pdu(rdpRpc* rpc)
|
|||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
RpcInChannel* inChannel = connection->DefaultInChannel;
|
||||
RpcOutChannel* outChannel = connection->DefaultOutChannel;
|
||||
|
||||
rts_pdu_header_init(&header);
|
||||
header.frag_length = 56;
|
||||
header.Flags = RTS_FLAG_OTHER_CMD;
|
||||
header.NumberOfCommands = 2;
|
||||
|
||||
WLog_DBG(TAG, "Sending FlowControlAck RTS PDU");
|
||||
|
||||
BytesReceived = outChannel->BytesReceived;
|
||||
AvailableWindow = outChannel->AvailableWindowAdvertised;
|
||||
ChannelCookie = (BYTE*) &(outChannel->Cookie);
|
||||
|
||||
ChannelCookie = (BYTE*) & (outChannel->Cookie);
|
||||
outChannel->ReceiverAvailableWindow = outChannel->AvailableWindowAdvertised;
|
||||
|
||||
buffer = (BYTE*) malloc(header.frag_length);
|
||||
|
||||
if (!buffer)
|
||||
|
@ -617,47 +581,38 @@ int rts_send_flow_control_ack_pdu(rdpRpc* rpc)
|
|||
|
||||
CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
|
||||
rts_destination_command_write(&buffer[20], FDOutProxy); /* Destination Command (8 bytes) */
|
||||
|
||||
/* FlowControlAck Command (28 bytes) */
|
||||
rts_flow_control_ack_command_write(&buffer[28], BytesReceived, AvailableWindow, ChannelCookie);
|
||||
|
||||
length = header.frag_length;
|
||||
|
||||
status = rpc_in_channel_write(inChannel, buffer, length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (status > 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
int rts_recv_flow_control_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
static int rts_recv_flow_control_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
UINT32 offset;
|
||||
UINT32 BytesReceived;
|
||||
UINT32 AvailableWindow;
|
||||
BYTE ChannelCookie[16];
|
||||
|
||||
offset = 24;
|
||||
offset += rts_flow_control_ack_command_read(rpc, &buffer[offset], length - offset,
|
||||
&BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4;
|
||||
|
||||
WLog_ERR(TAG, "Receiving FlowControlAck RTS PDU: BytesReceived: %"PRIu32" AvailableWindow: %"PRIu32"",
|
||||
BytesReceived, AvailableWindow);
|
||||
|
||||
&BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4;
|
||||
WLog_ERR(TAG,
|
||||
"Receiving FlowControlAck RTS PDU: BytesReceived: %"PRIu32" AvailableWindow: %"PRIu32"",
|
||||
BytesReceived, AvailableWindow);
|
||||
rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow =
|
||||
AvailableWindow - (rpc->VirtualConnection->DefaultInChannel->BytesSent - BytesReceived);
|
||||
|
||||
AvailableWindow - (rpc->VirtualConnection->DefaultInChannel->BytesSent - BytesReceived);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rts_recv_flow_control_ack_with_destination_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
static int rts_recv_flow_control_ack_with_destination_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
UINT32 offset;
|
||||
UINT32 Destination;
|
||||
UINT32 BytesReceived;
|
||||
UINT32 AvailableWindow;
|
||||
BYTE ChannelCookie[16];
|
||||
|
||||
/**
|
||||
* When the sender receives a FlowControlAck RTS PDU, it MUST use the following formula to
|
||||
* recalculate its Sender AvailableWindow variable:
|
||||
|
@ -673,18 +628,15 @@ int rts_recv_flow_control_ack_with_destination_pdu(rdpRpc* rpc, BYTE* buffer, UI
|
|||
* in the PDU received.
|
||||
*
|
||||
*/
|
||||
|
||||
offset = 24;
|
||||
offset += rts_destination_command_read(rpc, &buffer[offset], length - offset, &Destination) + 4;
|
||||
offset += rts_flow_control_ack_command_read(rpc, &buffer[offset], length - offset,
|
||||
&BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4;
|
||||
|
||||
WLog_DBG(TAG, "Receiving FlowControlAckWithDestination RTS PDU: BytesReceived: %"PRIu32" AvailableWindow: %"PRIu32"",
|
||||
BytesReceived, AvailableWindow);
|
||||
|
||||
&BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4;
|
||||
WLog_DBG(TAG,
|
||||
"Receiving FlowControlAckWithDestination RTS PDU: BytesReceived: %"PRIu32" AvailableWindow: %"PRIu32"",
|
||||
BytesReceived, AvailableWindow);
|
||||
rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow =
|
||||
AvailableWindow - (rpc->VirtualConnection->DefaultInChannel->BytesSent - BytesReceived);
|
||||
|
||||
AvailableWindow - (rpc->VirtualConnection->DefaultInChannel->BytesSent - BytesReceived);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -695,27 +647,20 @@ int rts_send_ping_pdu(rdpRpc* rpc)
|
|||
UINT32 length;
|
||||
rpcconn_rts_hdr_t header;
|
||||
RpcInChannel* inChannel = rpc->VirtualConnection->DefaultInChannel;
|
||||
|
||||
rts_pdu_header_init(&header);
|
||||
header.frag_length = 20;
|
||||
header.Flags = RTS_FLAG_PING;
|
||||
header.NumberOfCommands = 0;
|
||||
|
||||
WLog_DBG(TAG, "Sending Ping RTS PDU");
|
||||
|
||||
buffer = (BYTE*) malloc(header.frag_length);
|
||||
|
||||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
|
||||
|
||||
length = header.frag_length;
|
||||
|
||||
status = rpc_in_channel_write(inChannel, buffer, length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (status > 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
|
@ -794,7 +739,7 @@ int rts_command_length(rdpRpc* rpc, UINT32 CommandType, BYTE* buffer, UINT32 len
|
|||
return CommandLength;
|
||||
}
|
||||
|
||||
int rts_send_OUT_R2_A7_pdu(rdpRpc* rpc)
|
||||
static int rts_send_OUT_R2_A7_pdu(rdpRpc* rpc)
|
||||
{
|
||||
int status;
|
||||
BYTE* buffer;
|
||||
|
@ -802,16 +747,12 @@ int rts_send_OUT_R2_A7_pdu(rdpRpc* rpc)
|
|||
BYTE* SuccessorChannelCookie;
|
||||
RpcInChannel* inChannel = rpc->VirtualConnection->DefaultInChannel;
|
||||
RpcOutChannel* nextOutChannel = rpc->VirtualConnection->NonDefaultOutChannel;
|
||||
|
||||
rts_pdu_header_init(&header);
|
||||
header.frag_length = 56;
|
||||
header.Flags = RTS_FLAG_OUT_CHANNEL;
|
||||
header.NumberOfCommands = 3;
|
||||
|
||||
WLog_DBG(TAG, "Sending OUT_R2/A7 RTS PDU");
|
||||
|
||||
SuccessorChannelCookie = (BYTE*) &(nextOutChannel->Cookie);
|
||||
|
||||
SuccessorChannelCookie = (BYTE*) & (nextOutChannel->Cookie);
|
||||
buffer = (BYTE*) malloc(header.frag_length);
|
||||
|
||||
if (!buffer)
|
||||
|
@ -819,30 +760,25 @@ int rts_send_OUT_R2_A7_pdu(rdpRpc* rpc)
|
|||
|
||||
CopyMemory(buffer, ((BYTE*)&header), 20); /* RTS Header (20 bytes) */
|
||||
rts_destination_command_write(&buffer[20], FDServer); /* Destination (8 bytes)*/
|
||||
rts_cookie_command_write(&buffer[28], SuccessorChannelCookie); /* SuccessorChannelCookie (20 bytes) */
|
||||
rts_cookie_command_write(&buffer[28],
|
||||
SuccessorChannelCookie); /* SuccessorChannelCookie (20 bytes) */
|
||||
rts_version_command_write(&buffer[48]); /* Version (8 bytes) */
|
||||
|
||||
status = rpc_in_channel_write(inChannel, buffer, header.frag_length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (status > 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
int rts_send_OUT_R2_C1_pdu(rdpRpc* rpc)
|
||||
static int rts_send_OUT_R2_C1_pdu(rdpRpc* rpc)
|
||||
{
|
||||
int status;
|
||||
BYTE* buffer;
|
||||
rpcconn_rts_hdr_t header;
|
||||
RpcOutChannel* nextOutChannel = rpc->VirtualConnection->NonDefaultOutChannel;
|
||||
|
||||
rts_pdu_header_init(&header);
|
||||
header.frag_length = 24;
|
||||
header.Flags = RTS_FLAG_PING;
|
||||
header.NumberOfCommands = 1;
|
||||
|
||||
WLog_DBG(TAG, "Sending OUT_R2/C1 RTS PDU");
|
||||
|
||||
buffer = (BYTE*) malloc(header.frag_length);
|
||||
|
||||
if (!buffer)
|
||||
|
@ -850,11 +786,8 @@ int rts_send_OUT_R2_C1_pdu(rdpRpc* rpc)
|
|||
|
||||
CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
|
||||
rts_empty_command_write(&buffer[20]); /* Empty command (4 bytes) */
|
||||
|
||||
status = rpc_out_channel_write(nextOutChannel, buffer, header.frag_length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (status > 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
|
@ -870,19 +803,15 @@ int rts_send_OUT_R1_A3_pdu(rdpRpc* rpc)
|
|||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
RpcOutChannel* outChannel = connection->DefaultOutChannel;
|
||||
RpcOutChannel* nextOutChannel = connection->NonDefaultOutChannel;
|
||||
|
||||
rts_pdu_header_init(&header);
|
||||
header.frag_length = 96;
|
||||
header.Flags = RTS_FLAG_RECYCLE_CHANNEL;
|
||||
header.NumberOfCommands = 5;
|
||||
|
||||
WLog_DBG(TAG, "Sending OUT_R1/A3 RTS PDU");
|
||||
|
||||
VirtualConnectionCookie = (BYTE*) &(connection->Cookie);
|
||||
PredecessorChannelCookie = (BYTE*) &(outChannel->Cookie);
|
||||
SuccessorChannelCookie = (BYTE*) &(nextOutChannel->Cookie);
|
||||
VirtualConnectionCookie = (BYTE*) & (connection->Cookie);
|
||||
PredecessorChannelCookie = (BYTE*) & (outChannel->Cookie);
|
||||
SuccessorChannelCookie = (BYTE*) & (nextOutChannel->Cookie);
|
||||
ReceiveWindowSize = outChannel->ReceiveWindow;
|
||||
|
||||
buffer = (BYTE*) malloc(header.frag_length);
|
||||
|
||||
if (!buffer)
|
||||
|
@ -890,30 +819,32 @@ int rts_send_OUT_R1_A3_pdu(rdpRpc* rpc)
|
|||
|
||||
CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
|
||||
rts_version_command_write(&buffer[20]); /* Version (8 bytes) */
|
||||
rts_cookie_command_write(&buffer[28], VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
|
||||
rts_cookie_command_write(&buffer[48], PredecessorChannelCookie); /* PredecessorChannelCookie (20 bytes) */
|
||||
rts_cookie_command_write(&buffer[68], SuccessorChannelCookie); /* SuccessorChannelCookie (20 bytes) */
|
||||
rts_receive_window_size_command_write(&buffer[88], ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
|
||||
|
||||
rts_cookie_command_write(&buffer[28],
|
||||
VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
|
||||
rts_cookie_command_write(&buffer[48],
|
||||
PredecessorChannelCookie); /* PredecessorChannelCookie (20 bytes) */
|
||||
rts_cookie_command_write(&buffer[68],
|
||||
SuccessorChannelCookie); /* SuccessorChannelCookie (20 bytes) */
|
||||
rts_receive_window_size_command_write(&buffer[88],
|
||||
ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
|
||||
status = rpc_out_channel_write(nextOutChannel, buffer, header.frag_length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (status > 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
static int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
int status;
|
||||
UINT32 offset;
|
||||
UINT32 Destination = 0;
|
||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
|
||||
WLog_DBG(TAG, "Receiving OUT R1/A2 RTS PDU");
|
||||
|
||||
offset = 24;
|
||||
offset += rts_destination_command_read(rpc, &buffer[offset], length - offset, &Destination) + 4;
|
||||
|
||||
if (length < offset)
|
||||
return -1;
|
||||
|
||||
rts_destination_command_read(rpc, &buffer[offset], length - offset, &Destination);
|
||||
connection->NonDefaultOutChannel = rpc_out_channel_new(rpc);
|
||||
|
||||
if (!connection->NonDefaultOutChannel)
|
||||
|
@ -927,18 +858,16 @@ int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
|||
return -1;
|
||||
}
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED_A6W);
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel,
|
||||
CLIENT_OUT_CHANNEL_STATE_OPENED_A6W);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rts_recv_OUT_R2_A6_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
static int rts_recv_OUT_R2_A6_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
int status;
|
||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
|
||||
WLog_DBG(TAG, "Receiving OUT R2/A6 RTS PDU");
|
||||
|
||||
status = rts_send_OUT_R2_C1_pdu(rpc);
|
||||
|
||||
if (status < 0)
|
||||
|
@ -955,20 +884,19 @@ int rts_recv_OUT_R2_A6_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
|||
return -1;
|
||||
}
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->NonDefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED_B3W);
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED_B3W);
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->NonDefaultOutChannel,
|
||||
CLIENT_OUT_CHANNEL_STATE_OPENED_B3W);
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel,
|
||||
CLIENT_OUT_CHANNEL_STATE_OPENED_B3W);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rts_recv_OUT_R2_B3_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
static int rts_recv_OUT_R2_B3_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
|
||||
WLog_DBG(TAG, "Receiving OUT R2/B3 RTS PDU");
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_RECYCLED);
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel,
|
||||
CLIENT_OUT_CHANNEL_STATE_RECYCLED);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -979,9 +907,7 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
|||
rpcconn_rts_hdr_t* rts;
|
||||
RtsPduSignature signature;
|
||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
|
||||
rts = (rpcconn_rts_hdr_t*) buffer;
|
||||
|
||||
rts_extract_pdu_signature(rpc, &signature, rts);
|
||||
SignatureId = rts_identify_pdu_signature(rpc, &signature, NULL);
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], UINT32 count,
|
|||
* );
|
||||
*/
|
||||
|
||||
BOOL TsProxyCreateTunnelWriteRequest(rdpTsg* tsg, PTSG_PACKET tsgPacket)
|
||||
static BOOL TsProxyCreateTunnelWriteRequest(rdpTsg* tsg, PTSG_PACKET tsgPacket)
|
||||
{
|
||||
int status;
|
||||
UINT32 length;
|
||||
|
@ -291,7 +291,6 @@ BOOL TsProxyCreateTunnelWriteRequest(rdpTsg* tsg, PTSG_PACKET tsgPacket)
|
|||
*((UINT32*) &buffer[offset + 40]) =
|
||||
packetVersionCaps->tsgCaps->capabilityType; /* SwitchValue (4 bytes) */
|
||||
*((UINT32*) &buffer[offset + 44]) = tsgCapNap->capabilities; /* capabilities (4 bytes) */
|
||||
offset += 48;
|
||||
status = rpc_client_write_call(rpc, buffer, length, TsProxyCreateTunnelOpnum);
|
||||
free(buffer);
|
||||
|
||||
|
@ -302,8 +301,9 @@ BOOL TsProxyCreateTunnelWriteRequest(rdpTsg* tsg, PTSG_PACKET tsgPacket)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* tunnelContext,
|
||||
UINT32* tunnelId)
|
||||
static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu,
|
||||
CONTEXT_HANDLE* tunnelContext,
|
||||
UINT32* tunnelId)
|
||||
{
|
||||
BYTE* buffer;
|
||||
UINT32 count;
|
||||
|
@ -629,7 +629,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE*
|
|||
*
|
||||
*/
|
||||
|
||||
BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnelContext)
|
||||
static BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnelContext)
|
||||
{
|
||||
UINT32 pad;
|
||||
int status;
|
||||
|
@ -681,7 +681,7 @@ BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnelConte
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
|
||||
static BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
|
||||
{
|
||||
BYTE* buffer;
|
||||
UINT32 length;
|
||||
|
@ -809,7 +809,8 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
|
|||
* );
|
||||
*/
|
||||
|
||||
BOOL TsProxyMakeTunnelCallWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnelContext, UINT32 procId)
|
||||
static BOOL TsProxyMakeTunnelCallWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnelContext,
|
||||
UINT32 procId)
|
||||
{
|
||||
int status;
|
||||
BYTE* buffer;
|
||||
|
@ -840,7 +841,7 @@ BOOL TsProxyMakeTunnelCallWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnelContex
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
|
||||
static BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
|
||||
{
|
||||
BYTE* buffer;
|
||||
UINT32 length;
|
||||
|
@ -1006,7 +1007,7 @@ out:
|
|||
* );
|
||||
*/
|
||||
|
||||
BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnelContext)
|
||||
static BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnelContext)
|
||||
{
|
||||
int status;
|
||||
UINT32 count;
|
||||
|
@ -1048,8 +1049,9 @@ BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnelContext
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* channelContext,
|
||||
UINT32* channelId)
|
||||
static BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu,
|
||||
CONTEXT_HANDLE* channelContext,
|
||||
UINT32* channelId)
|
||||
{
|
||||
BYTE* buffer;
|
||||
UINT32 offset;
|
||||
|
@ -1079,7 +1081,7 @@ BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE*
|
|||
* );
|
||||
*/
|
||||
|
||||
BOOL TsProxyCloseChannelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* context)
|
||||
static BOOL TsProxyCloseChannelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* context)
|
||||
{
|
||||
int status;
|
||||
BYTE* buffer;
|
||||
|
@ -1108,7 +1110,7 @@ BOOL TsProxyCloseChannelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* context)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TsProxyCloseChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* context)
|
||||
static BOOL TsProxyCloseChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* context)
|
||||
{
|
||||
BYTE* buffer;
|
||||
WLog_DBG(TAG, "TsProxyCloseChannelReadResponse");
|
||||
|
@ -1134,7 +1136,7 @@ BOOL TsProxyCloseChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE*
|
|||
* );
|
||||
*/
|
||||
|
||||
BOOL TsProxyCloseTunnelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* context)
|
||||
static BOOL TsProxyCloseTunnelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* context)
|
||||
{
|
||||
int status;
|
||||
BYTE* buffer;
|
||||
|
@ -1159,7 +1161,7 @@ BOOL TsProxyCloseTunnelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* context)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TsProxyCloseTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* context)
|
||||
static BOOL TsProxyCloseTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* context)
|
||||
{
|
||||
BYTE* buffer;
|
||||
WLog_DBG(TAG, "TsProxyCloseTunnelReadResponse");
|
||||
|
@ -1187,7 +1189,7 @@ BOOL TsProxyCloseTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* c
|
|||
* );
|
||||
*/
|
||||
|
||||
BOOL TsProxySetupReceivePipeWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* channelContext)
|
||||
static BOOL TsProxySetupReceivePipeWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* channelContext)
|
||||
{
|
||||
int status;
|
||||
BYTE* buffer;
|
||||
|
@ -1212,7 +1214,7 @@ BOOL TsProxySetupReceivePipeWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* channelCon
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TsProxySetupReceivePipeReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
|
||||
static BOOL TsProxySetupReceivePipeReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
|
||||
{
|
||||
WLog_DBG(TAG, "TsProxySetupReceivePipeReadResponse");
|
||||
return TRUE;
|
||||
|
@ -1643,7 +1645,7 @@ DWORD tsg_get_event_handles(rdpTsg* tsg, HANDLE* events, DWORD count)
|
|||
return nCount;
|
||||
}
|
||||
|
||||
BOOL tsg_set_hostname(rdpTsg* tsg, const char* hostname)
|
||||
static BOOL tsg_set_hostname(rdpTsg* tsg, const char* hostname)
|
||||
{
|
||||
free(tsg->Hostname);
|
||||
tsg->Hostname = NULL;
|
||||
|
@ -1651,7 +1653,7 @@ BOOL tsg_set_hostname(rdpTsg* tsg, const char* hostname)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL tsg_set_machine_name(rdpTsg* tsg, const char* machineName)
|
||||
static BOOL tsg_set_machine_name(rdpTsg* tsg, const char* machineName)
|
||||
{
|
||||
free(tsg->MachineName);
|
||||
tsg->MachineName = NULL;
|
||||
|
@ -1752,7 +1754,7 @@ BOOL tsg_disconnect(rdpTsg* tsg)
|
|||
* @return < 0 on error; 0 if not enough data is available (non blocking mode); > 0 bytes to read
|
||||
*/
|
||||
|
||||
int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
|
||||
static int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
|
||||
{
|
||||
rdpRpc* rpc;
|
||||
int status = 0;
|
||||
|
@ -1803,7 +1805,7 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
|
|||
return status;
|
||||
}
|
||||
|
||||
int tsg_write(rdpTsg* tsg, BYTE* data, UINT32 length)
|
||||
static int tsg_write(rdpTsg* tsg, BYTE* data, UINT32 length)
|
||||
{
|
||||
int status;
|
||||
|
||||
|
@ -1858,7 +1860,8 @@ void tsg_free(rdpTsg* tsg)
|
|||
}
|
||||
}
|
||||
|
||||
long transport_bio_tsg_callback(BIO* bio, int mode, const char* argp, int argi, long argl, long ret)
|
||||
static long transport_bio_tsg_callback(BIO* bio, int mode, const char* argp, int argi, long argl,
|
||||
long ret)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -321,9 +321,6 @@ FREERDP_LOCAL BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port,
|
|||
int timeout);
|
||||
FREERDP_LOCAL BOOL tsg_disconnect(rdpTsg* tsg);
|
||||
|
||||
FREERDP_LOCAL int tsg_write(rdpTsg* tsg, BYTE* data, UINT32 length);
|
||||
FREERDP_LOCAL int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length);
|
||||
|
||||
FREERDP_LOCAL int tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu);
|
||||
|
||||
FREERDP_LOCAL int tsg_check_event_handles(rdpTsg* tsg);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -190,9 +192,13 @@ static const char* const mcs_result_enumerated[] =
|
|||
};
|
||||
*/
|
||||
|
||||
int mcs_initialize_client_channels(rdpMcs* mcs, rdpSettings* settings)
|
||||
static int mcs_initialize_client_channels(rdpMcs* mcs, rdpSettings* settings)
|
||||
{
|
||||
UINT32 index;
|
||||
|
||||
if (!mcs || !settings)
|
||||
return -1;
|
||||
|
||||
mcs->channelCount = settings->ChannelCount;
|
||||
|
||||
if (mcs->channelCount > mcs->channelMaxCount)
|
||||
|
@ -223,6 +229,9 @@ BOOL mcs_read_domain_mcspdu_header(wStream* s, enum DomainMCSPDU* domainMCSPDU,
|
|||
BYTE choice;
|
||||
enum DomainMCSPDU MCSPDU;
|
||||
|
||||
if (!s || !domainMCSPDU || !length)
|
||||
return FALSE;
|
||||
|
||||
*length = tpkt_read_header(s);
|
||||
|
||||
if (!tpdu_read_data(s, &li))
|
||||
|
@ -248,7 +257,8 @@ BOOL mcs_read_domain_mcspdu_header(wStream* s, enum DomainMCSPDU* domainMCSPDU,
|
|||
* @param length TPKT length
|
||||
*/
|
||||
|
||||
void mcs_write_domain_mcspdu_header(wStream* s, enum DomainMCSPDU domainMCSPDU, UINT16 length, BYTE options)
|
||||
void mcs_write_domain_mcspdu_header(wStream* s, enum DomainMCSPDU domainMCSPDU, UINT16 length,
|
||||
BYTE options)
|
||||
{
|
||||
tpkt_write_header(s, length);
|
||||
tpdu_write_data(s);
|
||||
|
@ -264,18 +274,21 @@ void mcs_write_domain_mcspdu_header(wStream* s, enum DomainMCSPDU domainMCSPDU,
|
|||
* @param maxMCSPDUsize max MCS PDU size
|
||||
*/
|
||||
|
||||
static void mcs_init_domain_parameters(DomainParameters* domainParameters,
|
||||
UINT32 maxChannelIds, UINT32 maxUserIds, UINT32 maxTokenIds, UINT32 maxMCSPDUsize)
|
||||
static BOOL mcs_init_domain_parameters(DomainParameters* domainParameters,
|
||||
UINT32 maxChannelIds, UINT32 maxUserIds, UINT32 maxTokenIds, UINT32 maxMCSPDUsize)
|
||||
{
|
||||
if (!domainParameters)
|
||||
return FALSE;
|
||||
|
||||
domainParameters->maxChannelIds = maxChannelIds;
|
||||
domainParameters->maxUserIds = maxUserIds;
|
||||
domainParameters->maxTokenIds = maxTokenIds;
|
||||
domainParameters->maxMCSPDUsize = maxMCSPDUsize;
|
||||
|
||||
domainParameters->numPriorities = 1;
|
||||
domainParameters->minThroughput = 0;
|
||||
domainParameters->maxHeight = 1;
|
||||
domainParameters->protocolVersion = 2;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -284,20 +297,23 @@ static void mcs_init_domain_parameters(DomainParameters* domainParameters,
|
|||
* @param domainParameters domain parameters
|
||||
*/
|
||||
|
||||
BOOL mcs_read_domain_parameters(wStream* s, DomainParameters* domainParameters)
|
||||
static BOOL mcs_read_domain_parameters(wStream* s, DomainParameters* domainParameters)
|
||||
{
|
||||
int length;
|
||||
|
||||
if (!s || !domainParameters)
|
||||
return FALSE;
|
||||
|
||||
return
|
||||
ber_read_sequence_tag(s, &length) &&
|
||||
ber_read_integer(s, &(domainParameters->maxChannelIds)) &&
|
||||
ber_read_integer(s, &(domainParameters->maxUserIds)) &&
|
||||
ber_read_integer(s, &(domainParameters->maxTokenIds)) &&
|
||||
ber_read_integer(s, &(domainParameters->numPriorities)) &&
|
||||
ber_read_integer(s, &(domainParameters->minThroughput)) &&
|
||||
ber_read_integer(s, &(domainParameters->maxHeight)) &&
|
||||
ber_read_integer(s, &(domainParameters->maxMCSPDUsize)) &&
|
||||
ber_read_integer(s, &(domainParameters->protocolVersion));
|
||||
ber_read_sequence_tag(s, &length) &&
|
||||
ber_read_integer(s, &(domainParameters->maxChannelIds)) &&
|
||||
ber_read_integer(s, &(domainParameters->maxUserIds)) &&
|
||||
ber_read_integer(s, &(domainParameters->maxTokenIds)) &&
|
||||
ber_read_integer(s, &(domainParameters->numPriorities)) &&
|
||||
ber_read_integer(s, &(domainParameters->minThroughput)) &&
|
||||
ber_read_integer(s, &(domainParameters->maxHeight)) &&
|
||||
ber_read_integer(s, &(domainParameters->maxMCSPDUsize)) &&
|
||||
ber_read_integer(s, &(domainParameters->protocolVersion));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -306,17 +322,22 @@ BOOL mcs_read_domain_parameters(wStream* s, DomainParameters* domainParameters)
|
|||
* @param domainParameters domain parameters
|
||||
*/
|
||||
|
||||
BOOL mcs_write_domain_parameters(wStream* s, DomainParameters* domainParameters)
|
||||
static BOOL mcs_write_domain_parameters(wStream* s, DomainParameters* domainParameters)
|
||||
{
|
||||
int length;
|
||||
wStream* tmps;
|
||||
|
||||
if (!s || !domainParameters)
|
||||
return FALSE;
|
||||
|
||||
tmps = Stream_New(NULL, Stream_Capacity(s));
|
||||
|
||||
if (!tmps)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ber_write_integer(tmps, domainParameters->maxChannelIds);
|
||||
ber_write_integer(tmps, domainParameters->maxUserIds);
|
||||
ber_write_integer(tmps, domainParameters->maxTokenIds);
|
||||
|
@ -325,12 +346,10 @@ BOOL mcs_write_domain_parameters(wStream* s, DomainParameters* domainParameters)
|
|||
ber_write_integer(tmps, domainParameters->maxHeight);
|
||||
ber_write_integer(tmps, domainParameters->maxMCSPDUsize);
|
||||
ber_write_integer(tmps, domainParameters->protocolVersion);
|
||||
|
||||
length = Stream_GetPosition(tmps);
|
||||
ber_write_sequence_tag(s, length);
|
||||
Stream_Write(s, Stream_Buffer(tmps), length);
|
||||
Stream_Free(tmps, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -339,17 +358,24 @@ BOOL mcs_write_domain_parameters(wStream* s, DomainParameters* domainParameters)
|
|||
* @param domainParameters domain parameters
|
||||
*/
|
||||
|
||||
void mcs_print_domain_parameters(DomainParameters* domainParameters)
|
||||
static void mcs_print_domain_parameters(DomainParameters* domainParameters)
|
||||
{
|
||||
WLog_INFO(TAG, "DomainParameters {");
|
||||
WLog_INFO(TAG, "\tmaxChannelIds:%"PRIu32"", domainParameters->maxChannelIds);
|
||||
WLog_INFO(TAG, "\tmaxUserIds:%"PRIu32"", domainParameters->maxUserIds);
|
||||
WLog_INFO(TAG, "\tmaxTokenIds:%"PRIu32"", domainParameters->maxTokenIds);
|
||||
WLog_INFO(TAG, "\tnumPriorities:%"PRIu32"", domainParameters->numPriorities);
|
||||
WLog_INFO(TAG, "\tminThroughput:%"PRIu32"", domainParameters->minThroughput);
|
||||
WLog_INFO(TAG, "\tmaxHeight:%"PRIu32"", domainParameters->maxHeight);
|
||||
WLog_INFO(TAG, "\tmaxMCSPDUsize:%"PRIu32"", domainParameters->maxMCSPDUsize);
|
||||
WLog_INFO(TAG, "\tprotocolVersion:%"PRIu32"", domainParameters->protocolVersion);
|
||||
|
||||
if (domainParameters)
|
||||
{
|
||||
WLog_INFO(TAG, "\tmaxChannelIds:%"PRIu32"", domainParameters->maxChannelIds);
|
||||
WLog_INFO(TAG, "\tmaxUserIds:%"PRIu32"", domainParameters->maxUserIds);
|
||||
WLog_INFO(TAG, "\tmaxTokenIds:%"PRIu32"", domainParameters->maxTokenIds);
|
||||
WLog_INFO(TAG, "\tnumPriorities:%"PRIu32"", domainParameters->numPriorities);
|
||||
WLog_INFO(TAG, "\tminThroughput:%"PRIu32"", domainParameters->minThroughput);
|
||||
WLog_INFO(TAG, "\tmaxHeight:%"PRIu32"", domainParameters->maxHeight);
|
||||
WLog_INFO(TAG, "\tmaxMCSPDUsize:%"PRIu32"", domainParameters->maxMCSPDUsize);
|
||||
WLog_INFO(TAG, "\tprotocolVersion:%"PRIu32"", domainParameters->protocolVersion);
|
||||
}
|
||||
else
|
||||
WLog_INFO(TAG, "\tdomainParameters=%p", domainParameters);
|
||||
|
||||
WLog_INFO(TAG, "}");
|
||||
}
|
||||
|
||||
|
@ -361,10 +387,13 @@ void mcs_print_domain_parameters(DomainParameters* domainParameters)
|
|||
* @param domainParameters output parameters
|
||||
*/
|
||||
|
||||
BOOL mcs_merge_domain_parameters(DomainParameters* targetParameters, DomainParameters* minimumParameters,
|
||||
DomainParameters* maximumParameters, DomainParameters* pOutParameters)
|
||||
BOOL mcs_merge_domain_parameters(DomainParameters* targetParameters,
|
||||
DomainParameters* minimumParameters,
|
||||
DomainParameters* maximumParameters, DomainParameters* pOutParameters)
|
||||
{
|
||||
/* maxChannelIds */
|
||||
if (!targetParameters || !minimumParameters || !maximumParameters || !pOutParameters)
|
||||
return FALSE;
|
||||
|
||||
if (targetParameters->maxChannelIds >= 4)
|
||||
{
|
||||
|
@ -395,7 +424,6 @@ BOOL mcs_merge_domain_parameters(DomainParameters* targetParameters, DomainParam
|
|||
}
|
||||
|
||||
/* maxTokenIds */
|
||||
|
||||
pOutParameters->maxTokenIds = targetParameters->maxTokenIds;
|
||||
|
||||
/* numPriorities */
|
||||
|
@ -410,7 +438,6 @@ BOOL mcs_merge_domain_parameters(DomainParameters* targetParameters, DomainParam
|
|||
}
|
||||
|
||||
/* minThroughput */
|
||||
|
||||
pOutParameters->minThroughput = targetParameters->minThroughput;
|
||||
|
||||
/* maxHeight */
|
||||
|
@ -456,7 +483,7 @@ BOOL mcs_merge_domain_parameters(DomainParameters* targetParameters, DomainParam
|
|||
/* protocolVersion */
|
||||
|
||||
if ((targetParameters->protocolVersion == 2) ||
|
||||
((minimumParameters->protocolVersion <= 2) && (maximumParameters->protocolVersion >= 2)))
|
||||
((minimumParameters->protocolVersion <= 2) && (maximumParameters->protocolVersion >= 2)))
|
||||
{
|
||||
pOutParameters->protocolVersion = 2;
|
||||
}
|
||||
|
@ -481,6 +508,9 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s)
|
|||
int length;
|
||||
BOOL upwardFlag;
|
||||
|
||||
if (!mcs || !s)
|
||||
return FALSE;
|
||||
|
||||
tpkt_read_header(s);
|
||||
|
||||
if (!tpdu_read_data(s, &li))
|
||||
|
@ -492,11 +522,13 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s)
|
|||
/* callingDomainSelector (OCTET_STRING) */
|
||||
if (!ber_read_octet_string_tag(s, &length) || ((int) Stream_GetRemainingLength(s)) < length)
|
||||
return FALSE;
|
||||
|
||||
Stream_Seek(s, length);
|
||||
|
||||
/* calledDomainSelector (OCTET_STRING) */
|
||||
if (!ber_read_octet_string_tag(s, &length) || ((int) Stream_GetRemainingLength(s)) < length)
|
||||
return FALSE;
|
||||
|
||||
Stream_Seek(s, length);
|
||||
|
||||
/* upwardFlag (BOOLEAN) */
|
||||
|
@ -522,7 +554,7 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s)
|
|||
return FALSE;
|
||||
|
||||
if (!mcs_merge_domain_parameters(&mcs->targetParameters, &mcs->minimumParameters,
|
||||
&mcs->maximumParameters, &mcs->domainParameters))
|
||||
&mcs->maximumParameters, &mcs->domainParameters))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -542,19 +574,21 @@ BOOL mcs_write_connect_initial(wStream* s, rdpMcs* mcs, wStream* userData)
|
|||
wStream* tmps;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!s || !mcs || !userData)
|
||||
return FALSE;
|
||||
|
||||
tmps = Stream_New(NULL, Stream_Capacity(s));
|
||||
|
||||
if (!tmps) {
|
||||
if (!tmps)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* callingDomainSelector (OCTET_STRING) */
|
||||
ber_write_octet_string(tmps, callingDomainSelector, sizeof(callingDomainSelector));
|
||||
|
||||
/* calledDomainSelector (OCTET_STRING) */
|
||||
ber_write_octet_string(tmps, calledDomainSelector, sizeof(calledDomainSelector));
|
||||
|
||||
/* upwardFlag (BOOLEAN) */
|
||||
ber_write_BOOL(tmps, TRUE);
|
||||
|
||||
|
@ -572,7 +606,6 @@ BOOL mcs_write_connect_initial(wStream* s, rdpMcs* mcs, wStream* userData)
|
|||
|
||||
/* userData (OCTET_STRING) */
|
||||
ber_write_octet_string(tmps, Stream_Buffer(userData), Stream_GetPosition(userData));
|
||||
|
||||
length = Stream_GetPosition(tmps);
|
||||
/* Connect-Initial (APPLICATION 101, IMPLICIT SEQUENCE) */
|
||||
ber_write_application_tag(s, MCS_TYPE_CONNECT_INITIAL, length);
|
||||
|
@ -597,19 +630,25 @@ BOOL mcs_write_connect_response(wStream* s, rdpMcs* mcs, wStream* userData)
|
|||
wStream* tmps;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!s || !mcs || !userData)
|
||||
return FALSE;
|
||||
|
||||
tmps = Stream_New(NULL, Stream_Capacity(s));
|
||||
|
||||
if (!tmps)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ber_write_enumerated(tmps, 0, MCS_Result_enum_length);
|
||||
ber_write_integer(tmps, 0); /* calledConnectId */
|
||||
|
||||
if (!mcs_write_domain_parameters(tmps, &(mcs->domainParameters)))
|
||||
goto out;
|
||||
|
||||
/* userData (OCTET_STRING) */
|
||||
ber_write_octet_string(tmps, Stream_Buffer(userData), Stream_GetPosition(userData));
|
||||
|
||||
length = Stream_GetPosition(tmps);
|
||||
ber_write_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, length);
|
||||
Stream_Write(s, Stream_Buffer(tmps), length);
|
||||
|
@ -634,26 +673,31 @@ BOOL mcs_send_connect_initial(rdpMcs* mcs)
|
|||
wStream* gcc_CCrq = NULL;
|
||||
wStream* client_data = NULL;
|
||||
|
||||
mcs_initialize_client_channels(mcs, mcs->settings);
|
||||
if (!mcs)
|
||||
return FALSE;
|
||||
|
||||
mcs_initialize_client_channels(mcs, mcs->settings);
|
||||
client_data = Stream_New(NULL, 512);
|
||||
|
||||
if (!client_data)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return FALSE;
|
||||
}
|
||||
gcc_write_client_data_blocks(client_data, mcs);
|
||||
|
||||
gcc_write_client_data_blocks(client_data, mcs);
|
||||
gcc_CCrq = Stream_New(NULL, 1024);
|
||||
|
||||
if (!gcc_CCrq)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
goto out;
|
||||
}
|
||||
|
||||
gcc_write_conference_create_request(gcc_CCrq, client_data);
|
||||
length = Stream_GetPosition(gcc_CCrq) + 7;
|
||||
|
||||
s = Stream_New(NULL, 1024 + length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
|
@ -672,19 +716,15 @@ BOOL mcs_send_connect_initial(rdpMcs* mcs)
|
|||
em = Stream_GetPosition(s);
|
||||
length = (em - bm);
|
||||
Stream_SetPosition(s, bm);
|
||||
|
||||
tpkt_write_header(s, length);
|
||||
tpdu_write_data(s);
|
||||
Stream_SetPosition(s, em);
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = transport_write(mcs->transport, s);
|
||||
|
||||
out:
|
||||
Stream_Free(s, TRUE);
|
||||
Stream_Free(gcc_CCrq, TRUE);
|
||||
Stream_Free(client_data, TRUE);
|
||||
|
||||
return (status < 0 ? FALSE : TRUE);
|
||||
}
|
||||
|
||||
|
@ -701,16 +741,19 @@ BOOL mcs_recv_connect_response(rdpMcs* mcs, wStream* s)
|
|||
UINT16 li;
|
||||
UINT32 calledConnectId;
|
||||
|
||||
if (!mcs || !s)
|
||||
return FALSE;
|
||||
|
||||
tpkt_read_header(s);
|
||||
|
||||
if (!tpdu_read_data(s, &li))
|
||||
return FALSE;
|
||||
|
||||
if (!ber_read_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, &length) ||
|
||||
!ber_read_enumerated(s, &result, MCS_Result_enum_length) ||
|
||||
!ber_read_integer(s, &calledConnectId) ||
|
||||
!mcs_read_domain_parameters(s, &(mcs->domainParameters)) ||
|
||||
!ber_read_octet_string_tag(s, &length))
|
||||
!ber_read_enumerated(s, &result, MCS_Result_enum_length) ||
|
||||
!ber_read_integer(s, &calledConnectId) ||
|
||||
!mcs_read_domain_parameters(s, &(mcs->domainParameters)) ||
|
||||
!ber_read_octet_string_tag(s, &length))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -739,7 +782,11 @@ BOOL mcs_send_connect_response(rdpMcs* mcs)
|
|||
wStream* gcc_CCrsp;
|
||||
wStream* server_data;
|
||||
|
||||
if (!mcs)
|
||||
return FALSE;
|
||||
|
||||
server_data = Stream_New(NULL, 512);
|
||||
|
||||
if (!server_data)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
|
@ -750,6 +797,7 @@ BOOL mcs_send_connect_response(rdpMcs* mcs)
|
|||
goto error_data_blocks;
|
||||
|
||||
gcc_CCrsp = Stream_New(NULL, 512 + Stream_Capacity(server_data));
|
||||
|
||||
if (!gcc_CCrsp)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
|
@ -758,8 +806,8 @@ BOOL mcs_send_connect_response(rdpMcs* mcs)
|
|||
|
||||
gcc_write_conference_create_response(gcc_CCrsp, server_data);
|
||||
length = Stream_GetPosition(gcc_CCrsp) + 7;
|
||||
|
||||
s = Stream_New(NULL, length + 1024);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
|
@ -771,23 +819,19 @@ BOOL mcs_send_connect_response(rdpMcs* mcs)
|
|||
|
||||
if (!mcs_write_connect_response(s, mcs, gcc_CCrsp))
|
||||
goto error_write_connect_response;
|
||||
|
||||
em = Stream_GetPosition(s);
|
||||
length = (em - bm);
|
||||
Stream_SetPosition(s, bm);
|
||||
|
||||
tpkt_write_header(s, length);
|
||||
tpdu_write_data(s);
|
||||
Stream_SetPosition(s, em);
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = transport_write(mcs->transport, s);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
Stream_Free(gcc_CCrsp, TRUE);
|
||||
Stream_Free(server_data, TRUE);
|
||||
|
||||
return (status < 0) ? FALSE : TRUE;
|
||||
|
||||
error_write_connect_response:
|
||||
Stream_Free(s, TRUE);
|
||||
error_stream_s:
|
||||
|
@ -811,6 +855,9 @@ BOOL mcs_recv_erect_domain_request(rdpMcs* mcs, wStream* s)
|
|||
UINT32 subInterval;
|
||||
enum DomainMCSPDU MCSPDU;
|
||||
|
||||
if (!mcs || !s)
|
||||
return FALSE;
|
||||
|
||||
MCSPDU = DomainMCSPDU_ErectDomainRequest;
|
||||
|
||||
if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length))
|
||||
|
@ -837,7 +884,11 @@ BOOL mcs_send_erect_domain_request(rdpMcs* mcs)
|
|||
int status;
|
||||
UINT16 length = 12;
|
||||
|
||||
if (!mcs)
|
||||
return FALSE;
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
|
@ -845,16 +896,11 @@ BOOL mcs_send_erect_domain_request(rdpMcs* mcs)
|
|||
}
|
||||
|
||||
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ErectDomainRequest, length, 0);
|
||||
|
||||
per_write_integer(s, 0); /* subHeight (INTEGER) */
|
||||
per_write_integer(s, 0); /* subInterval (INTEGER) */
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = transport_write(mcs->transport, s);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return (status < 0) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
@ -870,8 +916,10 @@ BOOL mcs_recv_attach_user_request(rdpMcs* mcs, wStream* s)
|
|||
UINT16 length;
|
||||
enum DomainMCSPDU MCSPDU;
|
||||
|
||||
MCSPDU = DomainMCSPDU_AttachUserRequest;
|
||||
if (!mcs || !s)
|
||||
return FALSE;
|
||||
|
||||
MCSPDU = DomainMCSPDU_AttachUserRequest;
|
||||
return mcs_read_domain_mcspdu_header(s, &MCSPDU, &length);
|
||||
}
|
||||
|
||||
|
@ -887,7 +935,11 @@ BOOL mcs_send_attach_user_request(rdpMcs* mcs)
|
|||
int status;
|
||||
UINT16 length = 8;
|
||||
|
||||
if (!mcs)
|
||||
return FALSE;
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
|
@ -895,13 +947,9 @@ BOOL mcs_send_attach_user_request(rdpMcs* mcs)
|
|||
}
|
||||
|
||||
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserRequest, length, 0);
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = transport_write(mcs->transport, s);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return (status < 0) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
@ -918,12 +966,13 @@ BOOL mcs_recv_attach_user_confirm(rdpMcs* mcs, wStream* s)
|
|||
UINT16 length;
|
||||
enum DomainMCSPDU MCSPDU;
|
||||
|
||||
if (!mcs || !s)
|
||||
return FALSE;
|
||||
|
||||
MCSPDU = DomainMCSPDU_AttachUserConfirm;
|
||||
|
||||
status = mcs_read_domain_mcspdu_header(s, &MCSPDU, &length) &&
|
||||
per_read_enumerated(s, &result, MCS_Result_enum_length) && /* result */
|
||||
per_read_integer16(s, &(mcs->userId), MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
|
||||
|
||||
per_read_enumerated(s, &result, MCS_Result_enum_length) && /* result */
|
||||
per_read_integer16(s, &(mcs->userId), MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -938,30 +987,25 @@ BOOL mcs_send_attach_user_confirm(rdpMcs* mcs)
|
|||
wStream* s;
|
||||
int status;
|
||||
UINT16 length = 11;
|
||||
rdpSettings* settings;
|
||||
|
||||
|
||||
if (!mcs)
|
||||
return FALSE;
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
settings = mcs->transport->settings;
|
||||
|
||||
mcs->userId = mcs->baseChannelId++;
|
||||
|
||||
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserConfirm, length, 2);
|
||||
|
||||
per_write_enumerated(s, 0, MCS_Result_enum_length); /* result */
|
||||
per_write_integer16(s, mcs->userId, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = transport_write(mcs->transport, s);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return (status < 0) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
@ -978,13 +1022,15 @@ BOOL mcs_recv_channel_join_request(rdpMcs* mcs, wStream* s, UINT16* channelId)
|
|||
UINT16 userId;
|
||||
enum DomainMCSPDU MCSPDU;
|
||||
|
||||
MCSPDU = DomainMCSPDU_ChannelJoinRequest;
|
||||
if (!mcs || !s || !channelId)
|
||||
return FALSE;
|
||||
|
||||
MCSPDU = DomainMCSPDU_ChannelJoinRequest;
|
||||
return
|
||||
mcs_read_domain_mcspdu_header(s, &MCSPDU, &length) &&
|
||||
per_read_integer16(s, &userId, MCS_BASE_CHANNEL_ID) &&
|
||||
(userId == mcs->userId) &&
|
||||
per_read_integer16(s, channelId, 0);
|
||||
mcs_read_domain_mcspdu_header(s, &MCSPDU, &length) &&
|
||||
per_read_integer16(s, &userId, MCS_BASE_CHANNEL_ID) &&
|
||||
(userId == mcs->userId) &&
|
||||
per_read_integer16(s, channelId, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1000,7 +1046,11 @@ BOOL mcs_send_channel_join_request(rdpMcs* mcs, UINT16 channelId)
|
|||
int status;
|
||||
UINT16 length = 12;
|
||||
|
||||
if (!mcs)
|
||||
return FALSE;
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
|
@ -1008,16 +1058,11 @@ BOOL mcs_send_channel_join_request(rdpMcs* mcs, UINT16 channelId)
|
|||
}
|
||||
|
||||
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinRequest, length, 0);
|
||||
|
||||
per_write_integer16(s, mcs->userId, MCS_BASE_CHANNEL_ID);
|
||||
per_write_integer16(s, channelId, 0);
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = transport_write(mcs->transport, s);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return (status < 0) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
@ -1036,15 +1081,16 @@ BOOL mcs_recv_channel_join_confirm(rdpMcs* mcs, wStream* s, UINT16* channelId)
|
|||
UINT16 requested;
|
||||
enum DomainMCSPDU MCSPDU;
|
||||
|
||||
if (!mcs || !s || !channelId)
|
||||
return FALSE;
|
||||
|
||||
status = TRUE;
|
||||
MCSPDU = DomainMCSPDU_ChannelJoinConfirm;
|
||||
|
||||
status &= mcs_read_domain_mcspdu_header(s, &MCSPDU, &length);
|
||||
status &= per_read_enumerated(s, &result, MCS_Result_enum_length); /* result */
|
||||
status &= per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
|
||||
status &= per_read_integer16(s, &requested, 0); /* requested (ChannelId) */
|
||||
status &= per_read_integer16(s, channelId, 0); /* channelId */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1060,7 +1106,11 @@ BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channelId)
|
|||
int status;
|
||||
UINT16 length = 15;
|
||||
|
||||
if (!mcs)
|
||||
return FALSE;
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
|
@ -1068,18 +1118,13 @@ BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channelId)
|
|||
}
|
||||
|
||||
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinConfirm, length, 2);
|
||||
|
||||
per_write_enumerated(s, 0, MCS_Result_enum_length); /* result */
|
||||
per_write_integer16(s, mcs->userId, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
|
||||
per_write_integer16(s, channelId, 0); /* requested (ChannelId) */
|
||||
per_write_integer16(s, channelId, 0); /* channelId */
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = transport_write(mcs->transport, s);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return (status < 0) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
@ -1092,6 +1137,9 @@ BOOL mcs_recv_disconnect_provider_ultimatum(rdpMcs* mcs, wStream* s, int* reason
|
|||
{
|
||||
BYTE b1, b2;
|
||||
|
||||
if (!mcs || !s || !reason)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* http://msdn.microsoft.com/en-us/library/cc240872.aspx:
|
||||
*
|
||||
|
@ -1125,9 +1173,7 @@ BOOL mcs_recv_disconnect_provider_ultimatum(rdpMcs* mcs, wStream* s, int* reason
|
|||
Stream_Rewind_UINT8(s);
|
||||
Stream_Read_UINT8(s, b1);
|
||||
Stream_Read_UINT8(s, b2);
|
||||
|
||||
*reason = ((b1 & 0x01) << 1) | (b2 >> 7);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1142,7 +1188,11 @@ BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs)
|
|||
int status;
|
||||
UINT16 length = 9;
|
||||
|
||||
if (!mcs)
|
||||
return FALSE;
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
|
@ -1150,19 +1200,23 @@ BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs)
|
|||
}
|
||||
|
||||
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_DisconnectProviderUltimatum, length, 1);
|
||||
|
||||
per_write_enumerated(s, 0x80, 0);
|
||||
|
||||
status = transport_write(mcs->transport, s);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return (status < 0) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
BOOL mcs_client_begin(rdpMcs* mcs)
|
||||
{
|
||||
rdpContext* context = mcs->transport->context;
|
||||
rdpContext* context;
|
||||
|
||||
if (!mcs || !mcs->transport)
|
||||
return FALSE;
|
||||
|
||||
context = mcs->transport->context;
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
if (!mcs_send_connect_initial(mcs))
|
||||
{
|
||||
|
@ -1187,6 +1241,9 @@ rdpMcs* mcs_new(rdpTransport* transport)
|
|||
{
|
||||
rdpMcs* mcs;
|
||||
|
||||
if (!transport)
|
||||
return NULL;
|
||||
|
||||
mcs = (rdpMcs*) calloc(1, sizeof(rdpMcs));
|
||||
|
||||
if (!mcs)
|
||||
|
@ -1194,24 +1251,19 @@ rdpMcs* mcs_new(rdpTransport* transport)
|
|||
|
||||
mcs->transport = transport;
|
||||
mcs->settings = transport->settings;
|
||||
|
||||
mcs_init_domain_parameters(&mcs->targetParameters, 34, 2, 0, 0xFFFF);
|
||||
mcs_init_domain_parameters(&mcs->minimumParameters, 1, 1, 1, 0x420);
|
||||
mcs_init_domain_parameters(&mcs->maximumParameters, 0xFFFF, 0xFC17, 0xFFFF, 0xFFFF);
|
||||
mcs_init_domain_parameters(&mcs->domainParameters, 0, 0, 0, 0xFFFF);
|
||||
|
||||
mcs->channelCount = 0;
|
||||
mcs->channelMaxCount = CHANNEL_MAX_COUNT;
|
||||
|
||||
mcs->baseChannelId = MCS_GLOBAL_CHANNEL_ID + 1;
|
||||
|
||||
mcs->channels = (rdpMcsChannel*) calloc(mcs->channelMaxCount, sizeof(rdpMcsChannel));
|
||||
|
||||
if (!mcs->channels)
|
||||
goto out_free;
|
||||
|
||||
return mcs;
|
||||
|
||||
out_free:
|
||||
free(mcs);
|
||||
return NULL;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -30,15 +30,12 @@
|
|||
#include <winpr/stream.h>
|
||||
|
||||
/* Protocol Security Negotiation Protocols */
|
||||
enum RDP_NEG_PROTOCOLS
|
||||
{
|
||||
PROTOCOL_RDP = 0x00000000,
|
||||
PROTOCOL_TLS = 0x00000001,
|
||||
PROTOCOL_NLA = 0x00000002,
|
||||
PROTOCOL_EXT = 0x00000008,
|
||||
#define PROTOCOL_RDP 0x00000000
|
||||
#define PROTOCOL_TLS 0x00000001
|
||||
#define PROTOCOL_NLA 0x00000002
|
||||
#define PROTOCOL_EXT 0x00000008
|
||||
|
||||
PROTOCOL_FAILED_NEGO = 0x80000000 /* only used internally, not on the wire */
|
||||
};
|
||||
#define PROTOCOL_FAILED_NEGO 0x80000000 /* only used internally, not on the wire */
|
||||
|
||||
/* Protocol Security Negotiation Failure Codes */
|
||||
enum RDP_NEG_FAILURE_FAILURECODES
|
||||
|
@ -147,26 +144,26 @@ FREERDP_LOCAL void nego_free(rdpNego* nego);
|
|||
FREERDP_LOCAL void nego_init(rdpNego* nego);
|
||||
FREERDP_LOCAL void nego_set_target(rdpNego* nego, char* hostname, int port);
|
||||
FREERDP_LOCAL void nego_set_negotiation_enabled(rdpNego* nego,
|
||||
BOOL NegotiateSecurityLayer);
|
||||
BOOL NegotiateSecurityLayer);
|
||||
FREERDP_LOCAL void nego_set_restricted_admin_mode_required(rdpNego* nego,
|
||||
BOOL RestrictedAdminModeRequired);
|
||||
BOOL RestrictedAdminModeRequired);
|
||||
FREERDP_LOCAL void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled);
|
||||
FREERDP_LOCAL void nego_set_gateway_bypass_local(rdpNego* nego,
|
||||
BOOL GatewayBypassLocal);
|
||||
BOOL GatewayBypassLocal);
|
||||
FREERDP_LOCAL void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp);
|
||||
FREERDP_LOCAL void nego_enable_tls(rdpNego* nego, BOOL enable_tls);
|
||||
FREERDP_LOCAL void nego_enable_nla(rdpNego* nego, BOOL enable_nla);
|
||||
FREERDP_LOCAL void nego_enable_ext(rdpNego* nego, BOOL enable_ext);
|
||||
FREERDP_LOCAL BOOL nego_set_routing_token(rdpNego* nego, BYTE* RoutingToken,
|
||||
DWORD RoutingTokenLength);
|
||||
DWORD RoutingTokenLength);
|
||||
FREERDP_LOCAL BOOL nego_set_cookie(rdpNego* nego, char* cookie);
|
||||
FREERDP_LOCAL void nego_set_cookie_max_length(rdpNego* nego,
|
||||
UINT32 CookieMaxLength);
|
||||
UINT32 CookieMaxLength);
|
||||
FREERDP_LOCAL void nego_set_send_preconnection_pdu(rdpNego* nego,
|
||||
BOOL SendPreconnectionPdu);
|
||||
BOOL SendPreconnectionPdu);
|
||||
FREERDP_LOCAL void nego_set_preconnection_id(rdpNego* nego,
|
||||
UINT32 PreconnectionId);
|
||||
UINT32 PreconnectionId);
|
||||
FREERDP_LOCAL void nego_set_preconnection_blob(rdpNego* nego,
|
||||
char* PreconnectionBlob);
|
||||
char* PreconnectionBlob);
|
||||
|
||||
#endif /* __NEGO_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2294,7 +2294,6 @@ static BOOL update_read_cache_brush_order(wStream* s,
|
|||
UINT16 flags)
|
||||
{
|
||||
int i;
|
||||
int size;
|
||||
BYTE iBitmapFormat;
|
||||
BOOL compressed = FALSE;
|
||||
|
||||
|
@ -2311,8 +2310,6 @@ static BOOL update_read_cache_brush_order(wStream* s,
|
|||
|
||||
if ((cache_brush->cx == 8) && (cache_brush->cy == 8))
|
||||
{
|
||||
size = (cache_brush->bpp == 1) ? 8 : 8 * 8 * cache_brush->bpp;
|
||||
|
||||
if (cache_brush->bpp == 1)
|
||||
{
|
||||
if (cache_brush->length != 8)
|
||||
|
@ -2373,7 +2370,6 @@ BOOL update_write_cache_brush_order(wStream* s,
|
|||
UINT16* flags)
|
||||
{
|
||||
int i;
|
||||
int size;
|
||||
BYTE iBitmapFormat;
|
||||
BOOL compressed = FALSE;
|
||||
|
||||
|
@ -2391,8 +2387,6 @@ BOOL update_write_cache_brush_order(wStream* s,
|
|||
|
||||
if ((cache_brush->cx == 8) && (cache_brush->cy == 8))
|
||||
{
|
||||
size = (cache_brush->bpp == 1) ? 8 : 8 * 8 * cache_brush->bpp;
|
||||
|
||||
if (cache_brush->bpp == 1)
|
||||
{
|
||||
if (cache_brush->length != 8)
|
||||
|
|
|
@ -68,8 +68,9 @@ void proxy_read_environment(rdpSettings* settings, char* envname)
|
|||
return;
|
||||
}
|
||||
|
||||
envlen = GetEnvironmentVariableA(envname, env, envlen);
|
||||
proxy_parse_uri(settings, env);
|
||||
if (GetEnvironmentVariableA(envname, env, envlen) == envlen)
|
||||
proxy_parse_uri(settings, env);
|
||||
|
||||
free(env);
|
||||
}
|
||||
|
||||
|
@ -169,9 +170,7 @@ BOOL http_proxy_connect(BIO* bufferedBio, const char* hostname, UINT16 port)
|
|||
wStream* s;
|
||||
char port_str[10], recv_buf[256], *eol;
|
||||
int resultsize;
|
||||
|
||||
_itoa_s(port, port_str, sizeof(port_str), 10);
|
||||
|
||||
s = Stream_New(NULL, 200);
|
||||
Stream_Write(s, "CONNECT ", 8);
|
||||
Stream_Write(s, hostname, strlen(hostname));
|
||||
|
@ -182,7 +181,6 @@ BOOL http_proxy_connect(BIO* bufferedBio, const char* hostname, UINT16 port)
|
|||
Stream_Write_UINT8(s, ':');
|
||||
Stream_Write(s, port_str, strlen(port_str));
|
||||
Stream_Write(s, CRLF CRLF, 4);
|
||||
|
||||
status = BIO_write(bufferedBio, Stream_Buffer(s), Stream_GetPosition(s));
|
||||
|
||||
if (status != Stream_GetPosition(s))
|
||||
|
@ -193,10 +191,8 @@ BOOL http_proxy_connect(BIO* bufferedBio, const char* hostname, UINT16 port)
|
|||
|
||||
Stream_Free(s, TRUE);
|
||||
s = NULL;
|
||||
|
||||
/* Read result until CR-LF-CR-LF.
|
||||
* Keep recv_buf a null-terminated string. */
|
||||
|
||||
memset(recv_buf, '\0', sizeof(recv_buf));
|
||||
resultsize = 0;
|
||||
|
||||
|
@ -242,7 +238,6 @@ BOOL http_proxy_connect(BIO* bufferedBio, const char* hostname, UINT16 port)
|
|||
}
|
||||
|
||||
*eol = '\0';
|
||||
|
||||
WLog_INFO(TAG, "HTTP Proxy: %s", recv_buf);
|
||||
|
||||
if (strlen(recv_buf) < 12)
|
||||
|
|
|
@ -66,9 +66,9 @@ void rdp_write_system_time(wStream* s, SYSTEMTIME* system_time)
|
|||
Stream_Write_UINT16(s, system_time->wSecond); /* wSecond */
|
||||
Stream_Write_UINT16(s, system_time->wMilliseconds); /* wMilliseconds */
|
||||
DEBUG_TIMEZONE("Time: y=%"PRIu16",m=%"PRIu16",dow=%"PRIu16",d=%"PRIu16", %02"PRIu16":%02"PRIu16":%02"PRIu16".%03"PRIu16"",
|
||||
system_time->wYear, system_time->wMonth, system_time->wDayOfWeek,
|
||||
system_time->wDay, system_time->wHour, system_time->wMinute,
|
||||
system_time->wSecond, system_time->wMilliseconds);
|
||||
system_time->wYear, system_time->wMonth, system_time->wDayOfWeek,
|
||||
system_time->wDay, system_time->wHour, system_time->wMinute,
|
||||
system_time->wSecond, system_time->wMilliseconds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,23 +89,19 @@ BOOL rdp_read_client_time_zone(wStream* s, rdpSettings* settings)
|
|||
return FALSE;
|
||||
|
||||
tz = settings->ClientTimeZone;
|
||||
|
||||
if (!tz)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, tz->Bias); /* Bias */
|
||||
|
||||
/* standardName (64 bytes) */
|
||||
Stream_Read(s, tz->StandardName, sizeof(tz->StandardName));
|
||||
|
||||
rdp_read_system_time(s, &tz->StandardDate); /* StandardDate */
|
||||
Stream_Read_UINT32(s, tz->StandardBias); /* StandardBias */
|
||||
|
||||
/* daylightName (64 bytes) */
|
||||
Stream_Read(s, tz->DaylightName, sizeof(tz->DaylightName));
|
||||
|
||||
rdp_read_system_time(s, &tz->DaylightDate); /* DaylightDate */
|
||||
Stream_Read_UINT32(s, tz->DaylightBias); /* DaylightBias */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -119,23 +115,18 @@ BOOL rdp_read_client_time_zone(wStream* s, rdpSettings* settings)
|
|||
BOOL rdp_write_client_time_zone(wStream* s, rdpSettings* settings)
|
||||
{
|
||||
LPTIME_ZONE_INFORMATION tz;
|
||||
DWORD rc;
|
||||
|
||||
tz = settings->ClientTimeZone;
|
||||
|
||||
if (!tz)
|
||||
return FALSE;
|
||||
|
||||
rc = GetTimeZoneInformation(tz);
|
||||
|
||||
GetTimeZoneInformation(tz);
|
||||
/* Bias */
|
||||
Stream_Write_UINT32(s, tz->Bias);
|
||||
|
||||
/* standardName (64 bytes) */
|
||||
Stream_Write(s, tz->StandardName, sizeof(tz->StandardName));
|
||||
|
||||
/* StandardDate */
|
||||
rdp_write_system_time(s, &tz->StandardDate);
|
||||
|
||||
#ifdef WITH_DEBUG_TIMEZONE
|
||||
WLog_DBG(TIMEZONE_TAG, "bias=%"PRId32"", tz->Bias);
|
||||
WLog_DBG(TIMEZONE_TAG, "StandardName:");
|
||||
|
@ -147,18 +138,14 @@ BOOL rdp_write_client_time_zone(wStream* s, rdpSettings* settings)
|
|||
/* StandardBias */
|
||||
Stream_Write_UINT32(s, tz->StandardBias);
|
||||
DEBUG_TIMEZONE("StandardBias=%"PRId32"", tz->StandardBias);
|
||||
|
||||
/* daylightName (64 bytes) */
|
||||
Stream_Write(s, tz->DaylightName, sizeof(tz->DaylightName));
|
||||
|
||||
/* DaylightDate */
|
||||
rdp_write_system_time(s, &tz->DaylightDate);
|
||||
|
||||
/* Note that DaylightBias is ignored if no valid daylightDate is provided. */
|
||||
/* DaylightBias */
|
||||
Stream_Write_UINT32(s, tz->DaylightBias);
|
||||
DEBUG_TIMEZONE("DaylightBias=%"PRId32"", tz->DaylightBias);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
|
||||
#include "rdtk_font.h"
|
||||
|
||||
int rdtk_font_draw_glyph(rdtkSurface* surface, int nXDst, int nYDst, rdtkFont* font, rdtkGlyph* glyph)
|
||||
static int rdtk_font_draw_glyph(rdtkSurface* surface, int nXDst, int nYDst, rdtkFont* font,
|
||||
rdtkGlyph* glyph)
|
||||
{
|
||||
int x, y;
|
||||
int nXSrc;
|
||||
|
@ -39,35 +40,22 @@ int rdtk_font_draw_glyph(rdtkSurface* surface, int nXDst, int nYDst, rdtkFont* f
|
|||
int nHeight;
|
||||
int nSrcStep;
|
||||
int nDstStep;
|
||||
int nSrcPad;
|
||||
int nDstPad;
|
||||
BYTE* pSrcData;
|
||||
BYTE* pSrcPixel;
|
||||
BYTE* pDstData;
|
||||
BYTE* pDstPixel;
|
||||
BYTE A, R, G, B;
|
||||
|
||||
nXDst += glyph->offsetX;
|
||||
nYDst += glyph->offsetY;
|
||||
|
||||
nXSrc = glyph->rectX;
|
||||
nYSrc = glyph->rectY;
|
||||
|
||||
nWidth = glyph->rectWidth;
|
||||
nHeight = glyph->rectHeight;
|
||||
|
||||
nSrcStep = font->image->scanline;
|
||||
pSrcData = font->image->data;
|
||||
|
||||
pDstData = surface->data;
|
||||
nDstStep = surface->scanline;
|
||||
|
||||
nSrcPad = (nSrcStep - (nWidth * 4));
|
||||
nDstPad = (nDstStep - (nWidth * 4));
|
||||
|
||||
pSrcPixel = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
pSrcPixel = &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
|
||||
|
@ -100,7 +88,6 @@ int rdtk_font_draw_glyph(rdtkSurface* surface, int nXDst, int nYDst, rdtkFont* f
|
|||
R = (R * A) / 255;
|
||||
G = (G * A) / 255;
|
||||
B = (B * A) / 255;
|
||||
|
||||
pDstPixel[0] = B + (pDstPixel[0] * (255 - A) + (255 / 2)) / 255;
|
||||
pDstPixel[1] = G + (pDstPixel[1] * (255 - A) + (255 / 2)) / 255;
|
||||
pDstPixel[2] = R + (pDstPixel[2] * (255 - A) + (255 / 2)) / 255;
|
||||
|
@ -109,22 +96,18 @@ int rdtk_font_draw_glyph(rdtkSurface* surface, int nXDst, int nYDst, rdtkFont* f
|
|||
pDstPixel[3] = 0xFF;
|
||||
pDstPixel += 4;
|
||||
}
|
||||
|
||||
pSrcPixel += nSrcPad;
|
||||
pDstPixel += nDstPad;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_font_draw_text(rdtkSurface* surface, int nXDst, int nYDst, rdtkFont* font, const char* text)
|
||||
int rdtk_font_draw_text(rdtkSurface* surface, int nXDst, int nYDst, rdtkFont* font,
|
||||
const char* text)
|
||||
{
|
||||
int index;
|
||||
int length;
|
||||
rdtkGlyph* glyph;
|
||||
|
||||
font = surface->engine->font;
|
||||
|
||||
length = strlen(text);
|
||||
|
||||
for (index = 0; index < length; index++)
|
||||
|
@ -143,10 +126,8 @@ int rdtk_font_text_draw_size(rdtkFont* font, int* width, int* height, const char
|
|||
int length;
|
||||
int glyphIndex;
|
||||
rdtkGlyph* glyph;
|
||||
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
|
||||
length = strlen(text);
|
||||
|
||||
for (index = 0; index < length; index++)
|
||||
|
@ -161,17 +142,15 @@ int rdtk_font_text_draw_size(rdtkFont* font, int* width, int* height, const char
|
|||
}
|
||||
|
||||
*height = font->height + 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* rdtk_font_load_descriptor_file(const char* filename, int* pSize)
|
||||
static char* rdtk_font_load_descriptor_file(const char* filename, int* pSize)
|
||||
{
|
||||
BYTE* buffer;
|
||||
FILE* fp = NULL;
|
||||
size_t readSize;
|
||||
size_t fileSize;
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
|
||||
if (!fp)
|
||||
|
@ -213,15 +192,13 @@ char* rdtk_font_load_descriptor_file(const char* filename, int* pSize)
|
|||
|
||||
buffer[fileSize] = '\0';
|
||||
buffer[fileSize + 1] = '\0';
|
||||
|
||||
*pSize = (int) fileSize;
|
||||
return (char*) buffer;
|
||||
}
|
||||
|
||||
int rdtk_font_convert_descriptor_code_to_utf8(const char* str, BYTE* utf8)
|
||||
static int rdtk_font_convert_descriptor_code_to_utf8(const char* str, BYTE* utf8)
|
||||
{
|
||||
int len = strlen(str);
|
||||
|
||||
*((UINT32*) utf8) = 0;
|
||||
|
||||
if (len < 1)
|
||||
|
@ -254,7 +231,7 @@ int rdtk_font_convert_descriptor_code_to_utf8(const char* str, BYTE* utf8)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
||||
static int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
||||
{
|
||||
char* p;
|
||||
char* q;
|
||||
|
@ -265,30 +242,25 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
int index;
|
||||
int count;
|
||||
rdtkGlyph* glyph;
|
||||
|
||||
p = strstr((char*) buffer, "<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
|
||||
if (!p)
|
||||
return -1;
|
||||
|
||||
p += sizeof("<?xml version=\"1.0\" encoding=\"utf-8\"?>") - 1;
|
||||
|
||||
p = strstr(p, "<Font ");
|
||||
|
||||
if (!p)
|
||||
return -1;
|
||||
|
||||
p += sizeof("<Font ") - 1;
|
||||
|
||||
/* find closing font tag */
|
||||
|
||||
end = strstr(p, "</Font>");
|
||||
|
||||
if (!end)
|
||||
return -1;
|
||||
|
||||
/* parse font size */
|
||||
|
||||
p = strstr(p, "size=\"");
|
||||
|
||||
if (!p)
|
||||
|
@ -308,9 +280,7 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
return -1;
|
||||
|
||||
p = q + 1;
|
||||
|
||||
/* parse font family */
|
||||
|
||||
p = strstr(p, "family=\"");
|
||||
|
||||
if (!p)
|
||||
|
@ -330,9 +300,7 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
return -1;
|
||||
|
||||
p = q + 1;
|
||||
|
||||
/* parse font height */
|
||||
|
||||
p = strstr(p, "height=\"");
|
||||
|
||||
if (!p)
|
||||
|
@ -352,9 +320,7 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
return -1;
|
||||
|
||||
p = q + 1;
|
||||
|
||||
/* parse font style */
|
||||
|
||||
p = strstr(p, "style=\"");
|
||||
|
||||
if (!p)
|
||||
|
@ -374,10 +340,8 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
return -1;
|
||||
|
||||
p = q + 1;
|
||||
|
||||
//printf("size: %d family: %s height: %d style: %s\n",
|
||||
// font->size, font->family, font->height, font->style);
|
||||
|
||||
beg = p;
|
||||
count = 0;
|
||||
|
||||
|
@ -389,22 +353,20 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
return -1;
|
||||
|
||||
p += sizeof("<Char ") - 1;
|
||||
|
||||
r = strstr(p, "/>");
|
||||
|
||||
if (!r)
|
||||
return -1;
|
||||
|
||||
*r = '\0';
|
||||
|
||||
p = r + sizeof("/>");
|
||||
*r = '/';
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
font->glyphCount = count;
|
||||
font->glyphs = NULL;
|
||||
|
||||
if (count > 0)
|
||||
font->glyphs = (rdtkGlyph*) calloc(font->glyphCount, sizeof(rdtkGlyph));
|
||||
|
||||
|
@ -422,20 +384,15 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
return -1;
|
||||
|
||||
p += sizeof("<Char ") - 1;
|
||||
|
||||
r = strstr(p, "/>");
|
||||
|
||||
if (!r)
|
||||
return -1;
|
||||
|
||||
*r = '\0';
|
||||
|
||||
/* start parsing glyph */
|
||||
|
||||
glyph = &font->glyphs[index];
|
||||
|
||||
/* parse glyph width */
|
||||
|
||||
p = strstr(p, "width=\"");
|
||||
|
||||
if (!p)
|
||||
|
@ -455,9 +412,7 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
return -1;
|
||||
|
||||
p = q + 1;
|
||||
|
||||
/* parse glyph offset x,y */
|
||||
|
||||
p = strstr(p, "offset=\"");
|
||||
|
||||
if (!p)
|
||||
|
@ -470,9 +425,7 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
return -1;
|
||||
|
||||
*q = '\0';
|
||||
|
||||
tok[0] = p;
|
||||
|
||||
p = strchr(tok[0] + 1, ' ');
|
||||
|
||||
if (!p)
|
||||
|
@ -480,16 +433,11 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
|
||||
*p = 0;
|
||||
tok[1] = p + 1;
|
||||
|
||||
glyph->offsetX = atoi(tok[0]);
|
||||
glyph->offsetY = atoi(tok[1]);
|
||||
|
||||
*q = '"';
|
||||
|
||||
p = q + 1;
|
||||
|
||||
/* parse glyph rect x,y,w,h */
|
||||
|
||||
p = strstr(p, "rect=\"");
|
||||
|
||||
if (!p)
|
||||
|
@ -502,9 +450,7 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
return -1;
|
||||
|
||||
*q = '\0';
|
||||
|
||||
tok[0] = p;
|
||||
|
||||
p = strchr(tok[0] + 1, ' ');
|
||||
|
||||
if (!p)
|
||||
|
@ -512,7 +458,6 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
|
||||
*p = 0;
|
||||
tok[1] = p + 1;
|
||||
|
||||
p = strchr(tok[1] + 1, ' ');
|
||||
|
||||
if (!p)
|
||||
|
@ -520,7 +465,6 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
|
||||
*p = 0;
|
||||
tok[2] = p + 1;
|
||||
|
||||
p = strchr(tok[2] + 1, ' ');
|
||||
|
||||
if (!p)
|
||||
|
@ -528,18 +472,13 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
|
||||
*p = 0;
|
||||
tok[3] = p + 1;
|
||||
|
||||
glyph->rectX = atoi(tok[0]);
|
||||
glyph->rectY = atoi(tok[1]);
|
||||
glyph->rectWidth = atoi(tok[2]);
|
||||
glyph->rectHeight = atoi(tok[3]);
|
||||
|
||||
*q = '"';
|
||||
|
||||
p = q + 1;
|
||||
|
||||
/* parse code */
|
||||
|
||||
p = strstr(p, "code=\"");
|
||||
|
||||
if (!p)
|
||||
|
@ -554,25 +493,19 @@ int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
|
|||
*q = '\0';
|
||||
rdtk_font_convert_descriptor_code_to_utf8(p, glyph->code);
|
||||
*q = '"';
|
||||
|
||||
p = q + 1;
|
||||
|
||||
/* finish parsing glyph */
|
||||
|
||||
p = r + sizeof("/>");
|
||||
*r = '/';
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_font_load_descriptor(rdtkFont* font, const char* filename)
|
||||
static int rdtk_font_load_descriptor(rdtkFont* font, const char* filename)
|
||||
{
|
||||
int size;
|
||||
char* buffer;
|
||||
|
||||
buffer = rdtk_font_load_descriptor_file(filename, &size);
|
||||
|
||||
if (!buffer)
|
||||
|
@ -589,14 +522,12 @@ rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file)
|
|||
char* fontBaseFile = NULL;
|
||||
char* fontImageFile = NULL;
|
||||
char* fontDescriptorFile = NULL;
|
||||
|
||||
fontBaseFile = GetCombinedPath(path, file);
|
||||
|
||||
if (!fontBaseFile)
|
||||
goto cleanup;
|
||||
|
||||
length = strlen(fontBaseFile);
|
||||
|
||||
fontImageFile = (char*) malloc(length + 8);
|
||||
|
||||
if (!fontImageFile)
|
||||
|
@ -604,7 +535,6 @@ rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file)
|
|||
|
||||
strcpy(fontImageFile, fontBaseFile);
|
||||
strcpy(&fontImageFile[length], ".png");
|
||||
|
||||
fontDescriptorFile = (char*) malloc(length + 8);
|
||||
|
||||
if (!fontDescriptorFile)
|
||||
|
@ -612,7 +542,6 @@ rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file)
|
|||
|
||||
strcpy(fontDescriptorFile, fontBaseFile);
|
||||
strcpy(&fontDescriptorFile[length], ".xml");
|
||||
|
||||
free(fontBaseFile);
|
||||
|
||||
if (!PathFileExistsA(fontImageFile))
|
||||
|
@ -627,7 +556,6 @@ rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file)
|
|||
goto cleanup;
|
||||
|
||||
font->engine = engine;
|
||||
|
||||
font->image = winpr_image_new();
|
||||
|
||||
if (!font->image)
|
||||
|
@ -640,38 +568,40 @@ rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file)
|
|||
|
||||
status = rdtk_font_load_descriptor(font, fontDescriptorFile);
|
||||
|
||||
if (status < 0)
|
||||
goto cleanup;
|
||||
|
||||
free(fontImageFile);
|
||||
free(fontDescriptorFile);
|
||||
|
||||
return font;
|
||||
|
||||
cleanup:
|
||||
free(fontImageFile);
|
||||
free(fontDescriptorFile);
|
||||
|
||||
if (font)
|
||||
{
|
||||
if (font->image)
|
||||
winpr_image_free(font->image, TRUE);
|
||||
free (font);
|
||||
|
||||
free(font);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rdtkFont* rdtk_embedded_font_new(rdtkEngine* engine, BYTE* imageData, int imageSize, BYTE* descriptorData, int descriptorSize)
|
||||
static rdtkFont* rdtk_embedded_font_new(rdtkEngine* engine, BYTE* imageData, int imageSize,
|
||||
BYTE* descriptorData, int descriptorSize)
|
||||
{
|
||||
int size;
|
||||
int status;
|
||||
BYTE* buffer;
|
||||
rdtkFont* font;
|
||||
|
||||
font = (rdtkFont*) calloc(1, sizeof(rdtkFont));
|
||||
|
||||
if (!font)
|
||||
return NULL;
|
||||
|
||||
font->engine = engine;
|
||||
|
||||
font->image = winpr_image_new();
|
||||
|
||||
if (!font->image)
|
||||
|
@ -700,11 +630,16 @@ rdtkFont* rdtk_embedded_font_new(rdtkEngine* engine, BYTE* imageData, int imageS
|
|||
}
|
||||
|
||||
CopyMemory(buffer, descriptorData, size);
|
||||
|
||||
status = rdtk_font_parse_descriptor_buffer(font, buffer, size);
|
||||
|
||||
free(buffer);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
winpr_image_free(font->image, TRUE);
|
||||
free(font);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
|
@ -728,9 +663,9 @@ int rdtk_font_engine_init(rdtkEngine* engine)
|
|||
int descriptorSize;
|
||||
BYTE* imageData = NULL;
|
||||
BYTE* descriptorData = NULL;
|
||||
|
||||
imageSize = rdtk_get_embedded_resource_file("source_serif_pro_regular_12.png", &imageData);
|
||||
descriptorSize = rdtk_get_embedded_resource_file("source_serif_pro_regular_12.xml", &descriptorData);
|
||||
descriptorSize = rdtk_get_embedded_resource_file("source_serif_pro_regular_12.xml",
|
||||
&descriptorData);
|
||||
|
||||
if ((imageSize < 0) || (descriptorSize < 0))
|
||||
return -1;
|
||||
|
|
|
@ -27,25 +27,19 @@
|
|||
#include "rdtk_nine_patch.h"
|
||||
|
||||
int rdtk_image_copy_alpha_blend(BYTE* pDstData, int nDstStep, int nXDst, int nYDst,
|
||||
int nWidth, int nHeight, BYTE* pSrcData, int nSrcStep, int nXSrc, int nYSrc)
|
||||
int nWidth, int nHeight, BYTE* pSrcData, int nSrcStep, int nXSrc, int nYSrc)
|
||||
{
|
||||
int x, y;
|
||||
int nSrcPad;
|
||||
int nDstPad;
|
||||
BYTE* pSrcPixel;
|
||||
BYTE* pDstPixel;
|
||||
BYTE A, R, G, B;
|
||||
|
||||
nSrcPad = (nSrcStep - (nWidth * 4));
|
||||
nDstPad = (nDstStep - (nWidth * 4));
|
||||
|
||||
pSrcPixel = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
pSrcPixel = &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
|
||||
const BYTE* pSrcPixel = &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
|
||||
BYTE* pDstPixel = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
|
||||
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
|
@ -66,7 +60,6 @@ int rdtk_image_copy_alpha_blend(BYTE* pDstData, int nDstStep, int nXDst, int nYD
|
|||
R = (R * A) / 255;
|
||||
G = (G * A) / 255;
|
||||
B = (B * A) / 255;
|
||||
|
||||
pDstPixel[0] = B + (pDstPixel[0] * (255 - A) + (255 / 2)) / 255;
|
||||
pDstPixel[1] = G + (pDstPixel[1] * (255 - A) + (255 / 2)) / 255;
|
||||
pDstPixel[2] = R + (pDstPixel[2] * (255 - A) + (255 / 2)) / 255;
|
||||
|
@ -75,15 +68,13 @@ int rdtk_image_copy_alpha_blend(BYTE* pDstData, int nDstStep, int nXDst, int nYD
|
|||
pDstPixel[3] = 0xFF;
|
||||
pDstPixel += 4;
|
||||
}
|
||||
|
||||
pSrcPixel += nSrcPad;
|
||||
pDstPixel += nDstPad;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight, rdtkNinePatch* ninePatch)
|
||||
int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight,
|
||||
rdtkNinePatch* ninePatch)
|
||||
{
|
||||
int x, y;
|
||||
int width;
|
||||
|
@ -95,7 +86,6 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth,
|
|||
BYTE* pSrcData;
|
||||
BYTE* pDstData;
|
||||
int scaleWidth;
|
||||
int scaleHeight;
|
||||
|
||||
if (nWidth < ninePatch->width)
|
||||
nWidth = ninePatch->width;
|
||||
|
@ -104,36 +94,24 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth,
|
|||
nHeight = ninePatch->height;
|
||||
|
||||
scaleWidth = nWidth - (ninePatch->width - ninePatch->scaleWidth);
|
||||
scaleHeight = nHeight - (ninePatch->height - ninePatch->scaleHeight);
|
||||
|
||||
nSrcStep = ninePatch->scanline;
|
||||
pSrcData = ninePatch->data;
|
||||
|
||||
pDstData = surface->data;
|
||||
nDstStep = surface->scanline;
|
||||
|
||||
/* top */
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
|
||||
/* top left */
|
||||
|
||||
nXSrc = 0;
|
||||
nYSrc = 0;
|
||||
width = ninePatch->scaleLeft;
|
||||
height = ninePatch->scaleTop;
|
||||
|
||||
rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y,
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
x += width;
|
||||
|
||||
/* top middle (scalable) */
|
||||
|
||||
nXSrc = ninePatch->scaleLeft;
|
||||
nYSrc = 0;
|
||||
width = ninePatch->scaleWidth;
|
||||
height = ninePatch->scaleTop;
|
||||
|
||||
while (x < (nXSrc + scaleWidth))
|
||||
|
@ -144,43 +122,31 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth,
|
|||
width = ninePatch->scaleWidth;
|
||||
|
||||
rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y,
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
x += width;
|
||||
}
|
||||
|
||||
/* top right */
|
||||
|
||||
nXSrc = ninePatch->scaleRight;
|
||||
nYSrc = 0;
|
||||
width = ninePatch->width - ninePatch->scaleRight;
|
||||
height = ninePatch->scaleTop;
|
||||
|
||||
rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y,
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
/* middle */
|
||||
|
||||
x = 0;
|
||||
y = ninePatch->scaleTop;
|
||||
|
||||
/* middle left */
|
||||
|
||||
nXSrc = 0;
|
||||
nYSrc = ninePatch->scaleTop;
|
||||
width = ninePatch->scaleLeft;
|
||||
height = ninePatch->scaleHeight;
|
||||
|
||||
rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y,
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
x += width;
|
||||
|
||||
/* middle (scalable) */
|
||||
|
||||
nXSrc = ninePatch->scaleLeft;
|
||||
nYSrc = ninePatch->scaleTop;
|
||||
width = ninePatch->scaleWidth;
|
||||
height = ninePatch->scaleHeight;
|
||||
|
||||
while (x < (nXSrc + scaleWidth))
|
||||
|
@ -191,43 +157,31 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth,
|
|||
width = ninePatch->scaleWidth;
|
||||
|
||||
rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y,
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
x += width;
|
||||
}
|
||||
|
||||
/* middle right */
|
||||
|
||||
nXSrc = ninePatch->scaleRight;
|
||||
nYSrc = ninePatch->scaleTop;
|
||||
width = ninePatch->width - ninePatch->scaleRight;
|
||||
height = ninePatch->scaleHeight;
|
||||
|
||||
rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y,
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
/* bottom */
|
||||
|
||||
x = 0;
|
||||
y = ninePatch->scaleBottom;
|
||||
|
||||
/* bottom left */
|
||||
|
||||
nXSrc = 0;
|
||||
nYSrc = ninePatch->scaleBottom;
|
||||
width = ninePatch->scaleLeft;
|
||||
height = ninePatch->height - ninePatch->scaleBottom;
|
||||
|
||||
rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y,
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
x += width;
|
||||
|
||||
/* bottom middle (scalable) */
|
||||
|
||||
nXSrc = ninePatch->scaleLeft;
|
||||
nYSrc = ninePatch->scaleBottom;
|
||||
width = ninePatch->scaleWidth;
|
||||
height = ninePatch->height - ninePatch->scaleBottom;
|
||||
|
||||
while (x < (nXSrc + scaleWidth))
|
||||
|
@ -238,21 +192,17 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth,
|
|||
width = ninePatch->scaleWidth;
|
||||
|
||||
rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y,
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
x += width;
|
||||
}
|
||||
|
||||
/* bottom right */
|
||||
|
||||
nXSrc = ninePatch->scaleRight;
|
||||
nYSrc = ninePatch->scaleBottom;
|
||||
width = ninePatch->width - ninePatch->scaleRight;
|
||||
height = ninePatch->height - ninePatch->scaleBottom;
|
||||
|
||||
rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y,
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
|
||||
width, height, pSrcData, nSrcStep, nXSrc, nYSrc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -264,16 +214,12 @@ int rdtk_nine_patch_set_image(rdtkNinePatch* ninePatch, wImage* image)
|
|||
int scanline;
|
||||
UINT32* pixel;
|
||||
int width, height;
|
||||
|
||||
ninePatch->image = image;
|
||||
|
||||
width = image->width;
|
||||
height = image->height;
|
||||
scanline = image->scanline;
|
||||
data = image->data;
|
||||
|
||||
/* parse scalable area */
|
||||
|
||||
beg = end = -1;
|
||||
pixel = (UINT32*) &data[4]; /* (1, 0) */
|
||||
|
||||
|
@ -301,7 +247,6 @@ int rdtk_nine_patch_set_image(rdtkNinePatch* ninePatch, wImage* image)
|
|||
ninePatch->scaleLeft = beg - 1;
|
||||
ninePatch->scaleRight = end - 1;
|
||||
ninePatch->scaleWidth = ninePatch->scaleRight - ninePatch->scaleLeft;
|
||||
|
||||
beg = end = -1;
|
||||
pixel = (UINT32*) &data[scanline]; /* (0, 1) */
|
||||
|
||||
|
@ -323,15 +268,13 @@ int rdtk_nine_patch_set_image(rdtkNinePatch* ninePatch, wImage* image)
|
|||
}
|
||||
}
|
||||
|
||||
pixel = (UINT32*) &((BYTE*) pixel)[scanline];
|
||||
pixel = (UINT32*) & ((BYTE*) pixel)[scanline];
|
||||
}
|
||||
|
||||
ninePatch->scaleTop = beg - 1;
|
||||
ninePatch->scaleBottom = end - 1;
|
||||
ninePatch->scaleHeight = ninePatch->scaleBottom - ninePatch->scaleTop;
|
||||
|
||||
/* parse fillable area */
|
||||
|
||||
beg = end = -1;
|
||||
pixel = (UINT32*) &data[((height - 1) * scanline) + 4]; /* (1, height - 1) */
|
||||
|
||||
|
@ -359,7 +302,6 @@ int rdtk_nine_patch_set_image(rdtkNinePatch* ninePatch, wImage* image)
|
|||
ninePatch->fillLeft = beg - 1;
|
||||
ninePatch->fillRight = end - 1;
|
||||
ninePatch->fillWidth = ninePatch->fillRight - ninePatch->fillLeft;
|
||||
|
||||
beg = end = -1;
|
||||
pixel = (UINT32*) &data[((width - 1) * 4) + scanline]; /* (width - 1, 1) */
|
||||
|
||||
|
@ -381,46 +323,38 @@ int rdtk_nine_patch_set_image(rdtkNinePatch* ninePatch, wImage* image)
|
|||
}
|
||||
}
|
||||
|
||||
pixel = (UINT32*) &((BYTE*) pixel)[scanline];
|
||||
pixel = (UINT32*) & ((BYTE*) pixel)[scanline];
|
||||
}
|
||||
|
||||
ninePatch->fillTop = beg - 1;
|
||||
ninePatch->fillBottom = end - 1;
|
||||
ninePatch->fillHeight = ninePatch->fillBottom - ninePatch->fillTop;
|
||||
|
||||
/* cut out borders from image */
|
||||
|
||||
ninePatch->width = width - 2;
|
||||
ninePatch->height = height - 2;
|
||||
ninePatch->data = &data[scanline + 4]; /* (1, 1) */
|
||||
ninePatch->scanline = scanline;
|
||||
|
||||
#if 0
|
||||
printf("width: %d height: %d\n", ninePatch->width, ninePatch->height);
|
||||
|
||||
printf("scale: left: %d right: %d top: %d bottom: %d\n",
|
||||
ninePatch->scaleLeft, ninePatch->scaleRight,
|
||||
ninePatch->scaleTop, ninePatch->scaleBottom);
|
||||
|
||||
ninePatch->scaleLeft, ninePatch->scaleRight,
|
||||
ninePatch->scaleTop, ninePatch->scaleBottom);
|
||||
printf("fill: left: %d right: %d top: %d bottom: %d\n",
|
||||
ninePatch->fillLeft, ninePatch->fillRight,
|
||||
ninePatch->fillTop, ninePatch->fillBottom);
|
||||
ninePatch->fillLeft, ninePatch->fillRight,
|
||||
ninePatch->fillTop, ninePatch->fillBottom);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rdtkNinePatch* rdtk_nine_patch_new(rdtkEngine* engine)
|
||||
{
|
||||
rdtkNinePatch* ninePatch;
|
||||
|
||||
ninePatch = (rdtkNinePatch*) calloc(1, sizeof(rdtkNinePatch));
|
||||
|
||||
if (!ninePatch)
|
||||
return NULL;
|
||||
|
||||
ninePatch->engine = engine;
|
||||
|
||||
return ninePatch;
|
||||
}
|
||||
|
||||
|
@ -430,7 +364,6 @@ void rdtk_nine_patch_free(rdtkNinePatch* ninePatch)
|
|||
return;
|
||||
|
||||
winpr_image_free(ninePatch->image, TRUE);
|
||||
|
||||
free(ninePatch);
|
||||
}
|
||||
|
||||
|
@ -444,9 +377,7 @@ int rdtk_nine_patch_engine_init(rdtkEngine* engine)
|
|||
{
|
||||
int size;
|
||||
BYTE* data;
|
||||
|
||||
status = -1;
|
||||
|
||||
size = rdtk_get_embedded_resource_file("btn_default_normal.9.png", &data);
|
||||
|
||||
if (size > 0)
|
||||
|
@ -470,9 +401,7 @@ int rdtk_nine_patch_engine_init(rdtkEngine* engine)
|
|||
{
|
||||
int size;
|
||||
BYTE* data;
|
||||
|
||||
status = -1;
|
||||
|
||||
size = rdtk_get_embedded_resource_file("textfield_default.9.png", &data);
|
||||
|
||||
if (size > 0)
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
*
|
||||
* Copyright 2011-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -71,7 +73,7 @@ static int x11_shadow_pam_conv(int num_msg, const struct pam_message** msg,
|
|||
struct pam_response** resp, void* appdata_ptr)
|
||||
{
|
||||
int index;
|
||||
int pam_status = PAM_BUF_ERR;
|
||||
int pam_status = PAM_CONV_ERR;
|
||||
SHADOW_PAM_AUTH_DATA* appdata;
|
||||
struct pam_response* response;
|
||||
appdata = (SHADOW_PAM_AUTH_DATA*) appdata_ptr;
|
||||
|
@ -124,7 +126,7 @@ out_fail:
|
|||
memset(response, 0, sizeof(struct pam_response) * num_msg);
|
||||
free(response);
|
||||
*resp = NULL;
|
||||
return PAM_CONV_ERR;
|
||||
return pam_status;
|
||||
}
|
||||
|
||||
static int x11_shadow_pam_get_service_name(SHADOW_PAM_AUTH_INFO* info)
|
||||
|
@ -376,32 +378,40 @@ static void x11_shadow_message_free(UINT32 id, SHADOW_MSG_OUT* msg)
|
|||
|
||||
static int x11_shadow_pointer_position_update(x11ShadowSubsystem* subsystem)
|
||||
{
|
||||
SHADOW_MSG_OUT_POINTER_POSITION_UPDATE* msg;
|
||||
UINT32 msgId = SHADOW_MSG_OUT_POINTER_POSITION_UPDATE_ID;
|
||||
rdpShadowClient* client;
|
||||
rdpShadowServer* server;
|
||||
SHADOW_MSG_OUT_POINTER_POSITION_UPDATE templateMsg;
|
||||
int count = 0;
|
||||
int index = 0;
|
||||
msg = (SHADOW_MSG_OUT_POINTER_POSITION_UPDATE*) calloc(1,
|
||||
sizeof(SHADOW_MSG_OUT_POINTER_POSITION_UPDATE));
|
||||
templateMsg.xPos = subsystem->pointerX;
|
||||
templateMsg.yPos = subsystem->pointerY;
|
||||
templateMsg.Free = x11_shadow_message_free;
|
||||
|
||||
if (!msg)
|
||||
if (!subsystem || !subsystem->server || !subsystem->server->clients)
|
||||
return -1;
|
||||
|
||||
msg->xPos = subsystem->pointerX;
|
||||
msg->yPos = subsystem->pointerY;
|
||||
msg->Free = x11_shadow_message_free;
|
||||
server = subsystem->server;
|
||||
ArrayList_Lock(server->clients);
|
||||
|
||||
for (index = 0; index < ArrayList_Count(server->clients); index++)
|
||||
{
|
||||
client = (rdpShadowClient*)ArrayList_GetItem(server->clients, index);
|
||||
SHADOW_MSG_OUT_POINTER_POSITION_UPDATE* msg;
|
||||
rdpShadowClient* client = (rdpShadowClient*)ArrayList_GetItem(server->clients, index);
|
||||
|
||||
/* Skip the client which send us the latest mouse event */
|
||||
if (client == subsystem->lastMouseClient)
|
||||
continue;
|
||||
|
||||
msg = malloc(sizeof(templateMsg));
|
||||
|
||||
if (!msg)
|
||||
{
|
||||
count = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(msg, &templateMsg, sizeof(templateMsg));
|
||||
|
||||
if (shadow_client_post_msg(client, NULL, msgId, (SHADOW_MSG_OUT*) msg, NULL))
|
||||
count++;
|
||||
}
|
||||
|
@ -576,12 +586,8 @@ static int x11_shadow_blend_cursor(x11ShadowSubsystem* subsystem)
|
|||
int nHeight;
|
||||
int nSrcStep;
|
||||
int nDstStep;
|
||||
int nSrcPad;
|
||||
int nDstPad;
|
||||
BYTE* pSrcData;
|
||||
BYTE* pDstData;
|
||||
BYTE* pSrcPixel;
|
||||
BYTE* pDstPixel;
|
||||
BYTE A, R, G, B;
|
||||
rdpShadowSurface* surface;
|
||||
surface = subsystem->server->surface;
|
||||
|
@ -632,15 +638,11 @@ static int x11_shadow_blend_cursor(x11ShadowSubsystem* subsystem)
|
|||
nSrcStep = subsystem->cursorWidth * 4;
|
||||
pDstData = surface->data;
|
||||
nDstStep = surface->scanline;
|
||||
nSrcPad = (nSrcStep - (nWidth * 4));
|
||||
nDstPad = (nDstStep - (nWidth * 4));
|
||||
pSrcPixel = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
pSrcPixel = &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
|
||||
const BYTE* pSrcPixel = &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
|
||||
BYTE* pDstPixel = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
|
||||
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
|
@ -665,9 +667,6 @@ static int x11_shadow_blend_cursor(x11ShadowSubsystem* subsystem)
|
|||
pDstPixel[3] = 0xFF;
|
||||
pDstPixel += 4;
|
||||
}
|
||||
|
||||
pSrcPixel += nSrcPad;
|
||||
pDstPixel += nDstPad;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -724,7 +723,6 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
|||
int x, y;
|
||||
int width, height;
|
||||
XImage* image;
|
||||
rdpShadowScreen* screen;
|
||||
rdpShadowServer* server;
|
||||
rdpShadowSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
|
@ -732,7 +730,6 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
|||
const RECTANGLE_16* extents;
|
||||
server = subsystem->server;
|
||||
surface = server->surface;
|
||||
screen = server->screen;
|
||||
count = ArrayList_Count(server->clients);
|
||||
|
||||
if (count < 1)
|
||||
|
@ -782,38 +779,43 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
|||
XSetErrorHandler(NULL);
|
||||
XSync(subsystem->display, False);
|
||||
XUnlockDisplay(subsystem->display);
|
||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion),
|
||||
&invalidRect);
|
||||
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion),
|
||||
&surfaceRect);
|
||||
|
||||
if (!region16_is_empty(&(surface->invalidRegion)))
|
||||
if (status)
|
||||
{
|
||||
extents = region16_extents(&(surface->invalidRegion));
|
||||
x = extents->left;
|
||||
y = extents->top;
|
||||
width = extents->right - extents->left;
|
||||
height = extents->bottom - extents->top;
|
||||
freerdp_image_copy(surface->data, surface->format,
|
||||
surface->scanline, x, y, width, height,
|
||||
(BYTE*) image->data, PIXEL_FORMAT_BGRX32,
|
||||
image->bytes_per_line, x, y, NULL, FREERDP_FLIP_NONE);
|
||||
//x11_shadow_blend_cursor(subsystem);
|
||||
count = ArrayList_Count(server->clients);
|
||||
shadow_subsystem_frame_update((rdpShadowSubsystem*)subsystem);
|
||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion),
|
||||
&invalidRect);
|
||||
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion),
|
||||
&surfaceRect);
|
||||
|
||||
if (count == 1)
|
||||
if (!region16_is_empty(&(surface->invalidRegion)))
|
||||
{
|
||||
rdpShadowClient* client;
|
||||
client = (rdpShadowClient*) ArrayList_GetItem(server->clients, 0);
|
||||
extents = region16_extents(&(surface->invalidRegion));
|
||||
x = extents->left;
|
||||
y = extents->top;
|
||||
width = extents->right - extents->left;
|
||||
height = extents->bottom - extents->top;
|
||||
|
||||
if (client)
|
||||
if (!freerdp_image_copy(surface->data, surface->format,
|
||||
surface->scanline, x, y, width, height,
|
||||
(BYTE*) image->data, PIXEL_FORMAT_BGRX32,
|
||||
image->bytes_per_line, x, y, NULL, FREERDP_FLIP_NONE))
|
||||
goto fail_capture;
|
||||
|
||||
//x11_shadow_blend_cursor(subsystem);
|
||||
count = ArrayList_Count(server->clients);
|
||||
shadow_subsystem_frame_update((rdpShadowSubsystem*)subsystem);
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder);
|
||||
}
|
||||
}
|
||||
rdpShadowClient* client;
|
||||
client = (rdpShadowClient*) ArrayList_GetItem(server->clients, 0);
|
||||
|
||||
region16_clear(&(surface->invalidRegion));
|
||||
if (client)
|
||||
subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder);
|
||||
}
|
||||
|
||||
region16_clear(&(surface->invalidRegion));
|
||||
}
|
||||
}
|
||||
|
||||
if (!subsystem->use_xshm)
|
||||
|
@ -821,6 +823,10 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
|||
|
||||
return 1;
|
||||
fail_capture:
|
||||
|
||||
if (!subsystem->use_xshm && image)
|
||||
XDestroyImage(image);
|
||||
|
||||
XSetErrorHandler(NULL);
|
||||
XSync(subsystem->display, False);
|
||||
XUnlockDisplay(subsystem->display);
|
||||
|
@ -1297,7 +1303,8 @@ static int x11_shadow_subsystem_init(x11ShadowSubsystem* subsystem)
|
|||
virtualScreen->right = subsystem->width;
|
||||
virtualScreen->bottom = subsystem->height;
|
||||
virtualScreen->flags = 1;
|
||||
WLog_INFO(TAG, "X11 Extensions: XFixes: %"PRId32" Xinerama: %"PRId32" XDamage: %"PRId32" XShm: %"PRId32"",
|
||||
WLog_INFO(TAG,
|
||||
"X11 Extensions: XFixes: %"PRId32" Xinerama: %"PRId32" XDamage: %"PRId32" XShm: %"PRId32"",
|
||||
subsystem->use_xfixes, subsystem->use_xinerama, subsystem->use_xdamage,
|
||||
subsystem->use_xshm);
|
||||
return 1;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -700,32 +702,31 @@ static UINT shadow_client_rdpgfx_caps_advertise(RdpgfxServerContext* context,
|
|||
* @return TRUE on success
|
||||
*/
|
||||
static BOOL shadow_client_send_surface_gfx(rdpShadowClient* client,
|
||||
BYTE* pSrcData, int nSrcStep, int nXSrc, int nYSrc, int nWidth, int nHeight)
|
||||
const BYTE* pSrcData, int nSrcStep, int nXSrc, int nYSrc, int nWidth, int nHeight)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
rdpUpdate* update;
|
||||
rdpContext* context;
|
||||
rdpContext* context = (rdpContext*) client;
|
||||
rdpSettings* settings;
|
||||
rdpShadowServer* server;
|
||||
rdpShadowEncoder* encoder;
|
||||
RDPGFX_SURFACE_COMMAND cmd;
|
||||
RDPGFX_START_FRAME_PDU cmdstart;
|
||||
RDPGFX_END_FRAME_PDU cmdend;
|
||||
SYSTEMTIME sTime;
|
||||
|
||||
context = (rdpContext*) client;
|
||||
update = context->update;
|
||||
if (!context || !pSrcData)
|
||||
return FALSE;
|
||||
|
||||
settings = context->settings;
|
||||
server = client->server;
|
||||
encoder = client->encoder;
|
||||
|
||||
if (!settings || !encoder)
|
||||
return FALSE;
|
||||
|
||||
cmdstart.frameId = shadow_encoder_create_frame_id(encoder);
|
||||
GetSystemTime(&sTime);
|
||||
cmdstart.timestamp = sTime.wHour << 22 | sTime.wMinute << 16 |
|
||||
sTime.wSecond << 10 | sTime.wMilliseconds;
|
||||
|
||||
cmdend.frameId = cmdstart.frameId;
|
||||
|
||||
cmd.surfaceId = 0;
|
||||
cmd.codecId = 0;
|
||||
cmd.contextId = 0;
|
||||
|
@ -796,17 +797,21 @@ static BOOL shadow_client_send_surface_bits(rdpShadowClient* client,
|
|||
int numMessages;
|
||||
UINT32 frameId = 0;
|
||||
rdpUpdate* update;
|
||||
rdpContext* context;
|
||||
rdpContext* context = (rdpContext*) client;
|
||||
rdpSettings* settings;
|
||||
rdpShadowServer* server;
|
||||
rdpShadowEncoder* encoder;
|
||||
SURFACE_BITS_COMMAND cmd;
|
||||
context = (rdpContext*) client;
|
||||
|
||||
if (!context || !pSrcData)
|
||||
return FALSE;
|
||||
|
||||
update = context->update;
|
||||
settings = context->settings;
|
||||
server = client->server;
|
||||
encoder = client->encoder;
|
||||
|
||||
if (!update || !settings || !encoder)
|
||||
return FALSE;
|
||||
|
||||
if (encoder->frameAck)
|
||||
frameId = shadow_encoder_create_frame_id(encoder);
|
||||
|
||||
|
@ -944,20 +949,25 @@ static BOOL shadow_client_send_bitmap_update(rdpShadowClient* client,
|
|||
UINT32 SrcFormat;
|
||||
BITMAP_DATA* bitmap;
|
||||
rdpUpdate* update;
|
||||
rdpContext* context;
|
||||
rdpContext* context = (rdpContext*) client;
|
||||
rdpSettings* settings;
|
||||
UINT32 maxUpdateSize;
|
||||
UINT32 totalBitmapSize;
|
||||
UINT32 updateSizeEstimate;
|
||||
BITMAP_DATA* bitmapData;
|
||||
BITMAP_UPDATE bitmapUpdate;
|
||||
rdpShadowServer* server;
|
||||
rdpShadowEncoder* encoder;
|
||||
context = (rdpContext*) client;
|
||||
|
||||
if (!context || !pSrcData)
|
||||
return FALSE;
|
||||
|
||||
update = context->update;
|
||||
settings = context->settings;
|
||||
server = client->server;
|
||||
encoder = client->encoder;
|
||||
|
||||
if (!update || !settings || !encoder)
|
||||
return FALSE;
|
||||
|
||||
maxUpdateSize = settings->MultifragMaxRequestSize;
|
||||
|
||||
if (settings->ColorDepth < 32)
|
||||
|
@ -1156,11 +1166,10 @@ static BOOL shadow_client_send_surface_update(rdpShadowClient* client,
|
|||
BOOL ret = TRUE;
|
||||
int nXSrc, nYSrc;
|
||||
int nWidth, nHeight;
|
||||
rdpContext* context;
|
||||
rdpContext* context = (rdpContext*) client;
|
||||
rdpSettings* settings;
|
||||
rdpShadowServer* server;
|
||||
rdpShadowSurface* surface;
|
||||
rdpShadowEncoder* encoder;
|
||||
REGION16 invalidRegion;
|
||||
RECTANGLE_16 surfaceRect;
|
||||
const RECTANGLE_16* extents;
|
||||
|
@ -1169,11 +1178,21 @@ static BOOL shadow_client_send_surface_update(rdpShadowClient* client,
|
|||
int index;
|
||||
UINT32 numRects = 0;
|
||||
const RECTANGLE_16* rects;
|
||||
context = (rdpContext*) client;
|
||||
|
||||
if (!context || !pStatus)
|
||||
return FALSE;
|
||||
|
||||
settings = context->settings;
|
||||
server = client->server;
|
||||
encoder = client->encoder;
|
||||
|
||||
if (!settings || !server)
|
||||
return FALSE;
|
||||
|
||||
surface = client->inLobby ? server->lobby : server->surface;
|
||||
|
||||
if (!surface)
|
||||
return FALSE;
|
||||
|
||||
EnterCriticalSection(&(client->lock));
|
||||
region16_init(&invalidRegion);
|
||||
region16_copy(&invalidRegion, &(client->invalidRegion));
|
||||
|
@ -1275,14 +1294,19 @@ out:
|
|||
static BOOL shadow_client_send_resize(rdpShadowClient* client,
|
||||
SHADOW_GFX_STATUS* pStatus)
|
||||
{
|
||||
rdpContext* context;
|
||||
rdpContext* context = (rdpContext*) client;
|
||||
rdpSettings* settings;
|
||||
rdpShadowServer* server;
|
||||
freerdp_peer* peer;
|
||||
server = client->server;
|
||||
context = (rdpContext*) client;
|
||||
|
||||
if (!context || !pStatus)
|
||||
return FALSE;
|
||||
|
||||
peer = context->peer;
|
||||
settings = context->settings;
|
||||
|
||||
if (!peer || !settings)
|
||||
return FALSE;
|
||||
|
||||
/**
|
||||
* Unset client activated flag to avoid sending update message during
|
||||
* resize. DesktopResize will reactive the client and
|
||||
|
@ -1467,8 +1491,6 @@ static void* shadow_client_thread(rdpShadowClient* client)
|
|||
rdpContext* context;
|
||||
rdpSettings* settings;
|
||||
rdpShadowServer* server;
|
||||
rdpShadowScreen* screen;
|
||||
rdpShadowEncoder* encoder;
|
||||
rdpShadowSubsystem* subsystem;
|
||||
wMessageQueue* MsgQueue = client->MsgQueue;
|
||||
/* This should only be visited in client thread */
|
||||
|
@ -1476,8 +1498,6 @@ static void* shadow_client_thread(rdpShadowClient* client)
|
|||
gfxstatus.gfxOpened = FALSE;
|
||||
gfxstatus.gfxSurfaceCreated = FALSE;
|
||||
server = client->server;
|
||||
screen = server->screen;
|
||||
encoder = client->encoder;
|
||||
subsystem = server->subsystem;
|
||||
context = (rdpContext*) client;
|
||||
peer = context->peer;
|
||||
|
@ -1523,6 +1543,9 @@ static void* shadow_client_thread(rdpShadowClient* client)
|
|||
events[nCount++] = MessageQueue_Event(MsgQueue);
|
||||
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
|
||||
|
||||
if (status == WAIT_FAILED)
|
||||
break;
|
||||
|
||||
if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
/* The UpdateEvent means to start sending current frame. It is
|
||||
|
@ -1733,6 +1756,10 @@ BOOL shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer)
|
|||
{
|
||||
rdpShadowClient* client;
|
||||
rdpShadowServer* server;
|
||||
|
||||
if (!listener || !peer)
|
||||
return FALSE;
|
||||
|
||||
server = (rdpShadowServer*) listener->info;
|
||||
peer->ContextExtra = (void*) server;
|
||||
peer->ContextSize = sizeof(rdpShadowClient);
|
||||
|
@ -1775,13 +1802,14 @@ static void shadow_msg_out_release(wMessage* message)
|
|||
static BOOL shadow_client_dispatch_msg(rdpShadowClient* client,
|
||||
wMessage* message)
|
||||
{
|
||||
if (!client || !message)
|
||||
return FALSE;
|
||||
|
||||
/* Add reference when it is posted */
|
||||
shadow_msg_out_addref(message);
|
||||
|
||||
if (MessageQueue_Dispatch(client->MsgQueue, message))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Release the reference since post failed */
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -61,21 +63,18 @@ static COMMAND_LINE_ARGUMENT_A shadow_args[] =
|
|||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
int shadow_server_print_command_line_help(int argc, char** argv)
|
||||
static int shadow_server_print_command_line_help(int argc, char** argv)
|
||||
{
|
||||
char* str;
|
||||
int length;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
|
||||
WLog_INFO(TAG, "Usage: %s [options]", argv[0]);
|
||||
WLog_INFO(TAG, "");
|
||||
|
||||
WLog_INFO(TAG, "Syntax:");
|
||||
WLog_INFO(TAG, " /flag (enables flag)");
|
||||
WLog_INFO(TAG, " /option:<value> (specifies option with value)");
|
||||
WLog_INFO(TAG, " +toggle -toggle (enables or disables toggle, where '/' is a synonym of '+')");
|
||||
WLog_INFO(TAG, "");
|
||||
|
||||
arg = shadow_args;
|
||||
|
||||
do
|
||||
|
@ -92,10 +91,12 @@ int shadow_server_print_command_line_help(int argc, char** argv)
|
|||
|
||||
if (arg->Format)
|
||||
{
|
||||
length = (int) (strlen(arg->Name) + strlen(arg->Format) + 2);
|
||||
length = (int)(strlen(arg->Name) + strlen(arg->Format) + 2);
|
||||
str = (char*) malloc(length + 1);
|
||||
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
sprintf_s(str, length + 1, "%s:%s", arg->Name, arg->Format);
|
||||
WLog_INFO(TAG, "%-20s", str);
|
||||
free(str);
|
||||
|
@ -111,16 +112,15 @@ int shadow_server_print_command_line_help(int argc, char** argv)
|
|||
{
|
||||
length = (int) strlen(arg->Name) + 32;
|
||||
str = (char*) malloc(length + 1);
|
||||
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
sprintf_s(str, length + 1, "%s (default:%s)", arg->Name,
|
||||
arg->Default ? "on" : "off");
|
||||
|
||||
arg->Default ? "on" : "off");
|
||||
WLog_INFO(TAG, " %s", arg->Default ? "-" : "+");
|
||||
|
||||
WLog_INFO(TAG, "%-20s", str);
|
||||
free(str);
|
||||
|
||||
WLog_INFO(TAG, "\t%s", arg->Text);
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,8 @@ int shadow_server_print_command_line_help(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int shadow_server_command_line_status_print(rdpShadowServer* server, int argc, char** argv, int status)
|
||||
int shadow_server_command_line_status_print(rdpShadowServer* server, int argc, char** argv,
|
||||
int status)
|
||||
{
|
||||
if (status == COMMAND_LINE_STATUS_PRINT_VERSION)
|
||||
{
|
||||
|
@ -144,6 +145,7 @@ int shadow_server_command_line_status_print(rdpShadowServer* server, int argc, c
|
|||
{
|
||||
if (shadow_server_print_command_line_help(argc, argv) < 0)
|
||||
return -1;
|
||||
|
||||
return COMMAND_LINE_STATUS_PRINT_HELP;
|
||||
}
|
||||
|
||||
|
@ -161,11 +163,10 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
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);
|
||||
status = CommandLineParseArgumentsA(argc, (const char**) argv, shadow_args, flags, server, NULL,
|
||||
NULL);
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
@ -178,7 +179,6 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
continue;
|
||||
|
||||
CommandLineSwitchStart(arg)
|
||||
|
||||
CommandLineSwitchCase(arg, "port")
|
||||
{
|
||||
server->port = (DWORD) atoi(arg->Value);
|
||||
|
@ -186,6 +186,7 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
CommandLineSwitchCase(arg, "ipc-socket")
|
||||
{
|
||||
server->ipcSocket = _strdup(arg->Value);
|
||||
|
||||
if (!server->ipcSocket)
|
||||
return -1;
|
||||
}
|
||||
|
@ -203,11 +204,11 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
char* tok[4];
|
||||
int x, y, w, h;
|
||||
char* str = _strdup(arg->Value);
|
||||
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
tok[0] = p = str;
|
||||
|
||||
p = strchr(p + 1, ',');
|
||||
|
||||
if (!p)
|
||||
|
@ -218,7 +219,6 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
|
||||
*p++ = '\0';
|
||||
tok[1] = p;
|
||||
|
||||
p = strchr(p + 1, ',');
|
||||
|
||||
if (!p)
|
||||
|
@ -229,7 +229,6 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
|
||||
*p++ = '\0';
|
||||
tok[2] = p;
|
||||
|
||||
p = strchr(p + 1, ',');
|
||||
|
||||
if (!p)
|
||||
|
@ -240,7 +239,6 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
|
||||
*p++ = '\0';
|
||||
tok[3] = p;
|
||||
|
||||
x = atoi(tok[0]);
|
||||
y = atoi(tok[1]);
|
||||
w = atoi(tok[2]);
|
||||
|
@ -318,9 +316,7 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CommandLineSwitchEnd(arg)
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
@ -332,13 +328,11 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
int index;
|
||||
int numMonitors;
|
||||
MONITOR_DEF monitors[16];
|
||||
|
||||
numMonitors = shadow_enum_monitors(monitors, 16);
|
||||
|
||||
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
|
||||
{
|
||||
/* Select monitors */
|
||||
|
||||
index = atoi(arg->Value);
|
||||
|
||||
if (index < 0)
|
||||
|
@ -359,13 +353,11 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
for (index = 0; index < numMonitors; index++)
|
||||
{
|
||||
monitor = &monitors[index];
|
||||
|
||||
width = monitor->right - monitor->left;
|
||||
height = monitor->bottom - monitor->top;
|
||||
|
||||
WLog_INFO(TAG, " %s [%d] %dx%d\t+%"PRId32"+%"PRId32"",
|
||||
(monitor->flags == 1) ? "*" : " ", index,
|
||||
width, height, monitor->left, monitor->top);
|
||||
(monitor->flags == 1) ? "*" : " ", index,
|
||||
width, height, monitor->left, monitor->top);
|
||||
}
|
||||
|
||||
status = COMMAND_LINE_STATUS_PRINT;
|
||||
|
@ -375,66 +367,67 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||
return status;
|
||||
}
|
||||
|
||||
void* shadow_server_thread(rdpShadowServer* server)
|
||||
static void* shadow_server_thread(rdpShadowServer* server)
|
||||
{
|
||||
BOOL running = TRUE;
|
||||
DWORD status;
|
||||
DWORD nCount;
|
||||
HANDLE events[32];
|
||||
HANDLE StopEvent;
|
||||
freerdp_listener* listener;
|
||||
rdpShadowSubsystem* subsystem;
|
||||
|
||||
listener = server->listener;
|
||||
StopEvent = server->StopEvent;
|
||||
subsystem = server->subsystem;
|
||||
|
||||
freerdp_listener* listener = server->listener;
|
||||
shadow_subsystem_start(server->subsystem);
|
||||
|
||||
while (1)
|
||||
while (running)
|
||||
{
|
||||
nCount = listener->GetEventHandles(listener, events, 32);
|
||||
if (0 == nCount)
|
||||
HANDLE events[32];
|
||||
DWORD nCount = 0;
|
||||
events[nCount++] = server->StopEvent;
|
||||
nCount += listener->GetEventHandles(listener, &events[nCount], 32 - nCount);
|
||||
|
||||
if (nCount <= 1)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to get FreeRDP file descriptor");
|
||||
break;
|
||||
}
|
||||
|
||||
events[nCount++] = server->StopEvent;
|
||||
|
||||
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(server->StopEvent, 0) == WAIT_OBJECT_0)
|
||||
switch (status)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!listener->CheckFileDescriptor(listener))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
|
||||
break;
|
||||
}
|
||||
case WAIT_FAILED:
|
||||
case WAIT_OBJECT_0:
|
||||
running = FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if (!listener->CheckFileDescriptor(listener))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
|
||||
running = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Sleep(100); /* FIXME: listener event handles */
|
||||
Sleep(100); /* FIXME: listener event handles */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
listener->Close(listener);
|
||||
|
||||
shadow_subsystem_stop(server->subsystem);
|
||||
|
||||
/* Signal to the clients that server is being stopped and wait for them
|
||||
* to disconnect. */
|
||||
if (shadow_client_boardcast_quit(server, 0))
|
||||
{
|
||||
while(ArrayList_Count(server->clients) > 0)
|
||||
while (ArrayList_Count(server->clients) > 0)
|
||||
{
|
||||
Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -443,13 +436,15 @@ int shadow_server_start(rdpShadowServer* server)
|
|||
BOOL status;
|
||||
WSADATA wsaData;
|
||||
|
||||
if (!server)
|
||||
return -1;
|
||||
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
|
||||
return -1;
|
||||
|
||||
#ifndef _WIN32
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
server->screen = shadow_screen_new(server);
|
||||
|
||||
if (!server->screen)
|
||||
|
@ -478,7 +473,7 @@ int shadow_server_start(rdpShadowServer* server)
|
|||
}
|
||||
|
||||
if (!(server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
|
||||
shadow_server_thread, (void*) server, 0, NULL)))
|
||||
shadow_server_thread, (void*) server, 0, NULL)))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -488,13 +483,15 @@ int shadow_server_start(rdpShadowServer* server)
|
|||
|
||||
int shadow_server_stop(rdpShadowServer* server)
|
||||
{
|
||||
if (!server)
|
||||
return -1;
|
||||
|
||||
if (server->thread)
|
||||
{
|
||||
SetEvent(server->StopEvent);
|
||||
WaitForSingleObject(server->thread, INFINITE);
|
||||
CloseHandle(server->thread);
|
||||
server->thread = NULL;
|
||||
|
||||
server->listener->Close(server->listener);
|
||||
}
|
||||
|
||||
|
@ -513,27 +510,28 @@ int shadow_server_stop(rdpShadowServer* server)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int shadow_server_init_config_path(rdpShadowServer* server)
|
||||
static int shadow_server_init_config_path(rdpShadowServer* server)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
if (!server->ConfigPath)
|
||||
{
|
||||
server->ConfigPath = GetEnvironmentSubPath("LOCALAPPDATA", "freerdp");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
|
||||
if (!server->ConfigPath)
|
||||
{
|
||||
char* userLibraryPath;
|
||||
char* userApplicationSupportPath;
|
||||
|
||||
userLibraryPath = GetKnownSubPath(KNOWN_PATH_HOME, "Library");
|
||||
|
||||
if (userLibraryPath)
|
||||
{
|
||||
if (!PathFileExistsA(userLibraryPath) &&
|
||||
!PathMakePathA(userLibraryPath, 0))
|
||||
!PathMakePathA(userLibraryPath, 0))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create directory '%s'", userLibraryPath);
|
||||
free(userLibraryPath);
|
||||
|
@ -545,13 +543,14 @@ int shadow_server_init_config_path(rdpShadowServer* server)
|
|||
if (userApplicationSupportPath)
|
||||
{
|
||||
if (!PathFileExistsA(userApplicationSupportPath) &&
|
||||
!PathMakePathA(userApplicationSupportPath, 0))
|
||||
!PathMakePathA(userApplicationSupportPath, 0))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create directory '%s'", userApplicationSupportPath);
|
||||
free(userLibraryPath);
|
||||
free(userApplicationSupportPath);
|
||||
return -1;
|
||||
}
|
||||
|
||||
server->ConfigPath = GetCombinedPath(userApplicationSupportPath, "freerdp");
|
||||
}
|
||||
|
||||
|
@ -559,23 +558,24 @@ int shadow_server_init_config_path(rdpShadowServer* server)
|
|||
free(userApplicationSupportPath);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (!server->ConfigPath)
|
||||
{
|
||||
char* configHome;
|
||||
|
||||
configHome = GetKnownPath(KNOWN_PATH_XDG_CONFIG_HOME);
|
||||
|
||||
if (configHome)
|
||||
{
|
||||
if (!PathFileExistsA(configHome) &&
|
||||
!PathMakePathA(configHome, 0))
|
||||
!PathMakePathA(configHome, 0))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create directory '%s'", configHome);
|
||||
free(configHome);
|
||||
return -1;
|
||||
}
|
||||
|
||||
server->ConfigPath = GetKnownSubPath(KNOWN_PATH_XDG_CONFIG_HOME, "freerdp");
|
||||
free(configHome);
|
||||
}
|
||||
|
@ -592,7 +592,6 @@ static BOOL shadow_server_init_certificate(rdpShadowServer* server)
|
|||
char* filepath;
|
||||
MAKECERT_CONTEXT* makecert = NULL;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
const char* makecert_argv[6] =
|
||||
{
|
||||
"makecert",
|
||||
|
@ -601,11 +600,10 @@ static BOOL shadow_server_init_certificate(rdpShadowServer* server)
|
|||
"-silent",
|
||||
"-y", "5"
|
||||
};
|
||||
|
||||
int makecert_argc = (sizeof(makecert_argv) / sizeof(char*));
|
||||
|
||||
if (!PathFileExistsA(server->ConfigPath) &&
|
||||
!PathMakePathA(server->ConfigPath, 0))
|
||||
!PathMakePathA(server->ConfigPath, 0))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create directory '%s'", server->ConfigPath);
|
||||
return FALSE;
|
||||
|
@ -615,7 +613,7 @@ static BOOL shadow_server_init_certificate(rdpShadowServer* server)
|
|||
return FALSE;
|
||||
|
||||
if (!PathFileExistsA(filepath) &&
|
||||
!PathMakePathA(filepath, 0))
|
||||
!PathMakePathA(filepath, 0))
|
||||
{
|
||||
if (!CreateDirectoryA(filepath, 0))
|
||||
{
|
||||
|
@ -626,13 +624,15 @@ static BOOL shadow_server_init_certificate(rdpShadowServer* server)
|
|||
|
||||
server->CertificateFile = GetCombinedPath(filepath, "shadow.crt");
|
||||
server->PrivateKeyFile = GetCombinedPath(filepath, "shadow.key");
|
||||
|
||||
if (!server->CertificateFile || !server->PrivateKeyFile)
|
||||
goto out_fail;
|
||||
|
||||
if ((!PathFileExistsA(server->CertificateFile)) ||
|
||||
(!PathFileExistsA(server->PrivateKeyFile)))
|
||||
(!PathFileExistsA(server->PrivateKeyFile)))
|
||||
{
|
||||
makecert = makecert_context_new();
|
||||
|
||||
if (!makecert)
|
||||
goto out_fail;
|
||||
|
||||
|
@ -654,20 +654,18 @@ static BOOL shadow_server_init_certificate(rdpShadowServer* server)
|
|||
goto out_fail;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out_fail:
|
||||
makecert_context_free(makecert);
|
||||
free(filepath);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int shadow_server_init(rdpShadowServer* server)
|
||||
{
|
||||
int status;
|
||||
|
||||
winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
|
||||
|
||||
WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi());
|
||||
|
||||
if (!(server->clients = ArrayList_New(TRUE)))
|
||||
|
@ -696,7 +694,6 @@ int shadow_server_init(rdpShadowServer* server)
|
|||
|
||||
server->listener->info = (void*) server;
|
||||
server->listener->PeerAccepted = shadow_client_accepted;
|
||||
|
||||
server->subsystem = shadow_subsystem_new();
|
||||
|
||||
if (!server->subsystem)
|
||||
|
@ -738,37 +735,27 @@ int shadow_server_uninit(rdpShadowServer* server)
|
|||
return -1;
|
||||
|
||||
shadow_server_stop(server);
|
||||
|
||||
shadow_subsystem_uninit(server->subsystem);
|
||||
|
||||
shadow_subsystem_free(server->subsystem);
|
||||
|
||||
freerdp_listener_free(server->listener);
|
||||
server->listener = NULL;
|
||||
|
||||
free(server->CertificateFile);
|
||||
server->CertificateFile = NULL;
|
||||
free(server->PrivateKeyFile);
|
||||
server->PrivateKeyFile = NULL;
|
||||
|
||||
free(server->ConfigPath);
|
||||
server->ConfigPath = NULL;
|
||||
|
||||
DeleteCriticalSection(&(server->lock));
|
||||
|
||||
CloseHandle(server->StopEvent);
|
||||
server->StopEvent = NULL;
|
||||
|
||||
ArrayList_Free(server->clients);
|
||||
server->clients = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rdpShadowServer* shadow_server_new()
|
||||
rdpShadowServer* shadow_server_new(void)
|
||||
{
|
||||
rdpShadowServer* server;
|
||||
|
||||
server = (rdpShadowServer*) calloc(1, sizeof(rdpShadowServer));
|
||||
|
||||
if (!server)
|
||||
|
@ -777,17 +764,13 @@ rdpShadowServer* shadow_server_new()
|
|||
server->port = 3389;
|
||||
server->mayView = TRUE;
|
||||
server->mayInteract = TRUE;
|
||||
|
||||
server->rfxMode = RLGR3;
|
||||
server->h264RateControlMode = H264_RATECONTROL_VBR;
|
||||
server->h264BitRate = 1000000;
|
||||
server->h264FrameRate = 30;
|
||||
server->h264QP = 0;
|
||||
|
||||
server->authentication = FALSE;
|
||||
|
||||
server->settings = freerdp_settings_new(FREERDP_SETTINGS_SERVER_MODE);
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
|
@ -798,10 +781,8 @@ void shadow_server_free(rdpShadowServer* server)
|
|||
|
||||
free(server->ipcSocket);
|
||||
server->ipcSocket = NULL;
|
||||
|
||||
freerdp_settings_free(server->settings);
|
||||
server->settings = NULL;
|
||||
|
||||
free(server);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ static pfnShadowSubsystemEntry shadow_subsystem_load_static_entry(const char* na
|
|||
if (g_Subsystems[index].name)
|
||||
return g_Subsystems[index].entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (index = 0; index < g_SubsystemCount; index++)
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
*
|
||||
* Copyright 2011 Vic Lee
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -61,61 +63,61 @@ static INLINE void Stream_Rewind(wStream* s, size_t _offset)
|
|||
}
|
||||
|
||||
#define _stream_read_n8(_t, _s, _v, _p) do { \
|
||||
_v = \
|
||||
(_t)(*_s->pointer); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
_v = \
|
||||
(_t)(*_s->pointer); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
|
||||
#define _stream_read_n16_le(_t, _s, _v, _p) do { \
|
||||
_v = \
|
||||
(_t)(*_s->pointer) + \
|
||||
(((_t)(*(_s->pointer + 1))) << 8); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
_v = \
|
||||
(_t)(*_s->pointer) + \
|
||||
(((_t)(*(_s->pointer + 1))) << 8); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
|
||||
#define _stream_read_n16_be(_t, _s, _v, _p) do { \
|
||||
_v = \
|
||||
(((_t)(*_s->pointer)) << 8) + \
|
||||
(_t)(*(_s->pointer + 1)); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
_v = \
|
||||
(((_t)(*_s->pointer)) << 8) + \
|
||||
(_t)(*(_s->pointer + 1)); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
|
||||
#define _stream_read_n32_le(_t, _s, _v, _p) do { \
|
||||
_v = \
|
||||
(_t)(*_s->pointer) + \
|
||||
(((_t)(*(_s->pointer + 1))) << 8) + \
|
||||
(((_t)(*(_s->pointer + 2))) << 16) + \
|
||||
(((_t)(*(_s->pointer + 3))) << 24); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
_v = \
|
||||
(_t)(*_s->pointer) + \
|
||||
(((_t)(*(_s->pointer + 1))) << 8) + \
|
||||
(((_t)(*(_s->pointer + 2))) << 16) + \
|
||||
(((_t)(*(_s->pointer + 3))) << 24); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
|
||||
#define _stream_read_n32_be(_t, _s, _v, _p) do { \
|
||||
_v = \
|
||||
(((_t)(*(_s->pointer))) << 24) + \
|
||||
(((_t)(*(_s->pointer + 1))) << 16) + \
|
||||
(((_t)(*(_s->pointer + 2))) << 8) + \
|
||||
(((_t)(*(_s->pointer + 3)))); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
_v = \
|
||||
(((_t)(*(_s->pointer))) << 24) + \
|
||||
(((_t)(*(_s->pointer + 1))) << 16) + \
|
||||
(((_t)(*(_s->pointer + 2))) << 8) + \
|
||||
(((_t)(*(_s->pointer + 3)))); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
|
||||
#define _stream_read_n64_le(_t, _s, _v, _p) do { \
|
||||
_v = \
|
||||
(_t)(*_s->pointer) + \
|
||||
(((_t)(*(_s->pointer + 1))) << 8) + \
|
||||
(((_t)(*(_s->pointer + 2))) << 16) + \
|
||||
(((_t)(*(_s->pointer + 3))) << 24) + \
|
||||
(((_t)(*(_s->pointer + 4))) << 32) + \
|
||||
(((_t)(*(_s->pointer + 5))) << 40) + \
|
||||
(((_t)(*(_s->pointer + 6))) << 48) + \
|
||||
(((_t)(*(_s->pointer + 7))) << 56); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
_v = \
|
||||
(_t)(*_s->pointer) + \
|
||||
(((_t)(*(_s->pointer + 1))) << 8) + \
|
||||
(((_t)(*(_s->pointer + 2))) << 16) + \
|
||||
(((_t)(*(_s->pointer + 3))) << 24) + \
|
||||
(((_t)(*(_s->pointer + 4))) << 32) + \
|
||||
(((_t)(*(_s->pointer + 5))) << 40) + \
|
||||
(((_t)(*(_s->pointer + 6))) << 48) + \
|
||||
(((_t)(*(_s->pointer + 7))) << 56); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
|
||||
#define _stream_read_n64_be(_t, _s, _v, _p) do { \
|
||||
_v = \
|
||||
(((_t)(*(_s->pointer))) << 56) + \
|
||||
(((_t)(*(_s->pointer + 1))) << 48) + \
|
||||
(((_t)(*(_s->pointer + 2))) << 40) + \
|
||||
(((_t)(*(_s->pointer + 3))) << 32) + \
|
||||
(((_t)(*(_s->pointer + 4))) << 24) + \
|
||||
(((_t)(*(_s->pointer + 5))) << 16) + \
|
||||
(((_t)(*(_s->pointer + 6))) << 8) + \
|
||||
(((_t)(*(_s->pointer + 7)))); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
_v = \
|
||||
(((_t)(*(_s->pointer))) << 56) + \
|
||||
(((_t)(*(_s->pointer + 1))) << 48) + \
|
||||
(((_t)(*(_s->pointer + 2))) << 40) + \
|
||||
(((_t)(*(_s->pointer + 3))) << 32) + \
|
||||
(((_t)(*(_s->pointer + 4))) << 24) + \
|
||||
(((_t)(*(_s->pointer + 5))) << 16) + \
|
||||
(((_t)(*(_s->pointer + 6))) << 8) + \
|
||||
(((_t)(*(_s->pointer + 7)))); \
|
||||
if (_p) Stream_Seek(_s, sizeof(_t)); } while (0)
|
||||
|
||||
#define Stream_Read_UINT8(_s, _v) _stream_read_n8(UINT8, _s, _v, TRUE)
|
||||
#define Stream_Read_INT8(_s, _v) _stream_read_n8(INT8, _s, _v, TRUE)
|
||||
|
@ -306,6 +308,11 @@ static INLINE void Stream_SealLength(wStream* _s)
|
|||
_s->length = (_s->pointer - _s->buffer);
|
||||
}
|
||||
|
||||
static INLINE size_t Stream_GetRemainingCapacity(wStream* _s)
|
||||
{
|
||||
return (_s->capacity - (_s->pointer - _s->buffer));
|
||||
}
|
||||
|
||||
static INLINE size_t Stream_GetRemainingLength(wStream* _s)
|
||||
{
|
||||
return (_s->length - (_s->pointer - _s->buffer));
|
||||
|
@ -316,9 +323,11 @@ static INLINE void Stream_Clear(wStream* _s)
|
|||
memset(_s->buffer, 0, _s->capacity);
|
||||
}
|
||||
|
||||
static INLINE BOOL Stream_SafeSeek(wStream* s, size_t size) {
|
||||
static INLINE BOOL Stream_SafeSeek(wStream* s, size_t size)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < size)
|
||||
return FALSE;
|
||||
|
||||
Stream_Seek(s, size);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -54,8 +54,8 @@ static const DWORD halfMask = 0x3FFUL;
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
ConversionResult ConvertUTF32toUTF16(
|
||||
const DWORD** sourceStart, const DWORD* sourceEnd,
|
||||
WCHAR** targetStart, WCHAR* targetEnd, ConversionFlags flags)
|
||||
const DWORD** sourceStart, const DWORD* sourceEnd,
|
||||
WCHAR** targetStart, WCHAR* targetEnd, ConversionFlags flags)
|
||||
{
|
||||
ConversionResult result = conversionOK;
|
||||
const DWORD* source = *sourceStart;
|
||||
|
@ -129,8 +129,8 @@ ConversionResult ConvertUTF32toUTF16(
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
ConversionResult ConvertUTF16toUTF32(
|
||||
const WCHAR** sourceStart, const WCHAR* sourceEnd,
|
||||
DWORD** targetStart, DWORD* targetEnd, ConversionFlags flags)
|
||||
const WCHAR** sourceStart, const WCHAR* sourceEnd,
|
||||
DWORD** targetStart, DWORD* targetEnd, ConversionFlags flags)
|
||||
{
|
||||
ConversionResult result = conversionOK;
|
||||
const WCHAR* source = *sourceStart;
|
||||
|
@ -154,7 +154,7 @@ ConversionResult ConvertUTF16toUTF32(
|
|||
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) /* it's an unpaired high surrogate */
|
||||
|
@ -216,14 +216,14 @@ ConversionResult ConvertUTF16toUTF32(
|
|||
*/
|
||||
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
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 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
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -232,8 +232,8 @@ static const char trailingBytesForUTF8[256] =
|
|||
* in a UTF-8 sequence.
|
||||
*/
|
||||
static const DWORD offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
||||
0x03C82080UL, 0xFA082080UL, 0x82082080UL
|
||||
};
|
||||
0x03C82080UL, 0xFA082080UL, 0x82082080UL
|
||||
};
|
||||
|
||||
/*
|
||||
* Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
|
||||
|
@ -257,8 +257,8 @@ static const BYTE firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
ConversionResult ConvertUTF16toUTF8(
|
||||
const WCHAR** sourceStart, const WCHAR* sourceEnd,
|
||||
BYTE** targetStart, BYTE* targetEnd, ConversionFlags flags)
|
||||
const WCHAR** sourceStart, const WCHAR* sourceEnd,
|
||||
BYTE** targetStart, BYTE* targetEnd, ConversionFlags flags)
|
||||
{
|
||||
BYTE* target;
|
||||
const WCHAR* source;
|
||||
|
@ -276,7 +276,7 @@ ConversionResult ConvertUTF16toUTF8(
|
|||
const DWORD byteMask = 0xBF;
|
||||
const DWORD byteMark = 0x80;
|
||||
const WCHAR* oldSource = source; /* In case we have to back up because of target overflow. */
|
||||
Data_Read_UINT16 (source, ch);
|
||||
Data_Read_UINT16(source, ch);
|
||||
source++;
|
||||
|
||||
/* If we have a surrogate pair, convert to UTF32 first. */
|
||||
|
@ -286,13 +286,13 @@ ConversionResult ConvertUTF16toUTF8(
|
|||
if (source < sourceEnd)
|
||||
{
|
||||
DWORD ch2;
|
||||
Data_Read_UINT16 (source, ch2);
|
||||
Data_Read_UINT16(source, ch2);
|
||||
|
||||
/* 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)
|
||||
|
@ -359,7 +359,7 @@ ConversionResult ConvertUTF16toUTF8(
|
|||
{
|
||||
switch (bytesToWrite)
|
||||
{
|
||||
/* note: everything falls through. */
|
||||
/* note: everything falls through. */
|
||||
case 4:
|
||||
*--target = (BYTE)((ch | byteMark) & byteMask);
|
||||
ch >>= 6;
|
||||
|
@ -380,18 +380,15 @@ ConversionResult ConvertUTF16toUTF8(
|
|||
{
|
||||
switch (bytesToWrite)
|
||||
{
|
||||
/* note: everything falls through. */
|
||||
/* note: everything falls through. */
|
||||
case 4:
|
||||
--target;
|
||||
ch >>= 6;
|
||||
|
||||
case 3:
|
||||
--target;
|
||||
ch >>= 6;
|
||||
|
||||
case 2:
|
||||
--target;
|
||||
ch >>= 6;
|
||||
|
||||
case 1:
|
||||
--target;
|
||||
|
@ -429,7 +426,7 @@ static BOOL isLegalUTF8(const BYTE* source, int length)
|
|||
default:
|
||||
return FALSE;
|
||||
|
||||
/* Everything else falls through when "TRUE"... */
|
||||
/* Everything else falls through when "TRUE"... */
|
||||
case 4:
|
||||
if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return FALSE;
|
||||
|
||||
|
@ -441,7 +438,7 @@ static BOOL isLegalUTF8(const BYTE* source, int length)
|
|||
|
||||
switch (*source)
|
||||
{
|
||||
/* no fall-through in this inner switch */
|
||||
/* no fall-through in this inner switch */
|
||||
case 0xE0:
|
||||
if (a < 0xA0) return FALSE;
|
||||
|
||||
|
@ -495,8 +492,8 @@ BOOL isLegalUTF8Sequence(const BYTE* source, const BYTE* sourceEnd)
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
ConversionResult ConvertUTF8toUTF16(
|
||||
const BYTE** sourceStart, const BYTE* sourceEnd,
|
||||
WCHAR** targetStart, WCHAR* targetEnd, ConversionFlags flags)
|
||||
const BYTE** sourceStart, const BYTE* sourceEnd,
|
||||
WCHAR** targetStart, WCHAR* targetEnd, ConversionFlags flags)
|
||||
{
|
||||
WCHAR* target;
|
||||
const BYTE* source;
|
||||
|
@ -577,7 +574,8 @@ ConversionResult ConvertUTF8toUTF16(
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!computeLength) {
|
||||
if (!computeLength)
|
||||
{
|
||||
Data_Write_UINT16(target, UNI_REPLACEMENT_CHAR);
|
||||
target++;
|
||||
}
|
||||
|
@ -587,7 +585,8 @@ ConversionResult ConvertUTF8toUTF16(
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!computeLength) {
|
||||
if (!computeLength)
|
||||
{
|
||||
Data_Write_UINT16(target, ch); /* normal case */
|
||||
target++;
|
||||
}
|
||||
|
@ -605,7 +604,8 @@ ConversionResult ConvertUTF8toUTF16(
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!computeLength) {
|
||||
if (!computeLength)
|
||||
{
|
||||
Data_Write_UINT16(target, UNI_REPLACEMENT_CHAR);
|
||||
target++;
|
||||
}
|
||||
|
@ -625,9 +625,9 @@ ConversionResult ConvertUTF8toUTF16(
|
|||
|
||||
ch -= halfBase;
|
||||
|
||||
if (!computeLength) {
|
||||
if (!computeLength)
|
||||
{
|
||||
WCHAR wchar;
|
||||
|
||||
wchar = (ch >> halfShift) + UNI_SUR_HIGH_START;
|
||||
Data_Write_UINT16(target, wchar);
|
||||
target++;
|
||||
|
@ -651,8 +651,8 @@ ConversionResult ConvertUTF8toUTF16(
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
ConversionResult ConvertUTF32toUTF8(
|
||||
const DWORD** sourceStart, const DWORD* sourceEnd,
|
||||
BYTE** targetStart, BYTE* targetEnd, ConversionFlags flags)
|
||||
const DWORD** sourceStart, const DWORD* sourceEnd,
|
||||
BYTE** targetStart, BYTE* targetEnd, ConversionFlags flags)
|
||||
{
|
||||
ConversionResult result = conversionOK;
|
||||
const DWORD* source = *sourceStart;
|
||||
|
@ -743,8 +743,8 @@ ConversionResult ConvertUTF32toUTF8(
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
ConversionResult ConvertUTF8toUTF32(
|
||||
const BYTE** sourceStart, const BYTE* sourceEnd,
|
||||
DWORD** targetStart, DWORD* targetEnd, ConversionFlags flags)
|
||||
const BYTE** sourceStart, const BYTE* sourceEnd,
|
||||
DWORD** targetStart, DWORD* targetEnd, ConversionFlags flags)
|
||||
{
|
||||
ConversionResult result = conversionOK;
|
||||
const BYTE* source = *sourceStart;
|
||||
|
@ -762,7 +762,7 @@ ConversionResult ConvertUTF8toUTF32(
|
|||
}
|
||||
|
||||
/* Do this check whether lenient or strict */
|
||||
if (! isLegalUTF8(source, extraBytesToRead+1))
|
||||
if (! isLegalUTF8(source, extraBytesToRead + 1))
|
||||
{
|
||||
result = sourceIllegal;
|
||||
break;
|
||||
|
@ -801,7 +801,7 @@ ConversionResult ConvertUTF8toUTF32(
|
|||
|
||||
if (target >= targetEnd)
|
||||
{
|
||||
source -= (extraBytesToRead+1); /* Back up the source pointer! */
|
||||
source -= (extraBytesToRead + 1); /* Back up the source pointer! */
|
||||
result = targetExhausted;
|
||||
break;
|
||||
}
|
||||
|
@ -816,7 +816,7 @@ ConversionResult ConvertUTF8toUTF32(
|
|||
{
|
||||
if (flags == strictConversion)
|
||||
{
|
||||
source -= (extraBytesToRead+1); /* return to the illegal value itself */
|
||||
source -= (extraBytesToRead + 1); /* return to the illegal value itself */
|
||||
result = sourceIllegal;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* Pipe Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -94,7 +96,7 @@ static BOOL PipeIsHandled(HANDLE handle)
|
|||
|
||||
static int PipeGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_PIPE *pipe = (WINPR_PIPE *)handle;
|
||||
WINPR_PIPE* pipe = (WINPR_PIPE*)handle;
|
||||
|
||||
if (!PipeIsHandled(handle))
|
||||
return -1;
|
||||
|
@ -102,8 +104,9 @@ static int PipeGetFd(HANDLE handle)
|
|||
return pipe->fd;
|
||||
}
|
||||
|
||||
static BOOL PipeCloseHandle(HANDLE handle) {
|
||||
WINPR_PIPE* pipe = (WINPR_PIPE *)handle;
|
||||
static BOOL PipeCloseHandle(HANDLE handle)
|
||||
{
|
||||
WINPR_PIPE* pipe = (WINPR_PIPE*)handle;
|
||||
|
||||
if (!PipeIsHandled(handle))
|
||||
return FALSE;
|
||||
|
@ -119,7 +122,7 @@ static BOOL PipeCloseHandle(HANDLE handle) {
|
|||
}
|
||||
|
||||
static BOOL PipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
|
||||
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
int io_status;
|
||||
WINPR_PIPE* pipe;
|
||||
|
@ -132,7 +135,8 @@ static BOOL PipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
pipe = (WINPR_PIPE *)Object;
|
||||
pipe = (WINPR_PIPE*)Object;
|
||||
|
||||
do
|
||||
{
|
||||
io_status = read(pipe->fd, lpBuffer, nNumberOfBytesToRead);
|
||||
|
@ -158,7 +162,7 @@ static BOOL PipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
|||
}
|
||||
|
||||
static BOOL PipeWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
|
||||
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
int io_status;
|
||||
WINPR_PIPE* pipe;
|
||||
|
@ -170,7 +174,7 @@ static BOOL PipeWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrit
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
pipe = (WINPR_PIPE *)Object;
|
||||
pipe = (WINPR_PIPE*)Object;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -186,27 +190,28 @@ static BOOL PipeWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrit
|
|||
}
|
||||
|
||||
|
||||
static HANDLE_OPS ops = {
|
||||
PipeIsHandled,
|
||||
PipeCloseHandle,
|
||||
PipeGetFd,
|
||||
NULL, /* CleanupHandle */
|
||||
PipeRead,
|
||||
NULL, /* FileReadEx */
|
||||
NULL, /* FileReadScatter */
|
||||
PipeWrite,
|
||||
NULL, /* FileWriteEx */
|
||||
NULL, /* FileWriteGather */
|
||||
NULL, /* FileGetFileSize */
|
||||
NULL, /* FlushFileBuffers */
|
||||
NULL, /* FileSetEndOfFile */
|
||||
NULL, /* FileSetFilePointer */
|
||||
NULL, /* SetFilePointerEx */
|
||||
NULL, /* FileLockFile */
|
||||
NULL, /* FileLockFileEx */
|
||||
NULL, /* FileUnlockFile */
|
||||
NULL, /* FileUnlockFileEx */
|
||||
NULL /* SetFileTime */
|
||||
static HANDLE_OPS ops =
|
||||
{
|
||||
PipeIsHandled,
|
||||
PipeCloseHandle,
|
||||
PipeGetFd,
|
||||
NULL, /* CleanupHandle */
|
||||
PipeRead,
|
||||
NULL, /* FileReadEx */
|
||||
NULL, /* FileReadScatter */
|
||||
PipeWrite,
|
||||
NULL, /* FileWriteEx */
|
||||
NULL, /* FileWriteGather */
|
||||
NULL, /* FileGetFileSize */
|
||||
NULL, /* FlushFileBuffers */
|
||||
NULL, /* FileSetEndOfFile */
|
||||
NULL, /* FileSetFilePointer */
|
||||
NULL, /* SetFilePointerEx */
|
||||
NULL, /* FileLockFile */
|
||||
NULL, /* FileLockFileEx */
|
||||
NULL, /* FileUnlockFile */
|
||||
NULL, /* FileUnlockFileEx */
|
||||
NULL /* SetFileTime */
|
||||
};
|
||||
|
||||
|
||||
|
@ -226,18 +231,20 @@ static BOOL NamedPipeIsHandled(HANDLE handle)
|
|||
|
||||
static int NamedPipeGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_NAMED_PIPE *pipe = (WINPR_NAMED_PIPE *)handle;
|
||||
WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*)handle;
|
||||
|
||||
if (!NamedPipeIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
if (pipe->ServerMode)
|
||||
return pipe->serverfd;
|
||||
|
||||
return pipe->clientfd;
|
||||
}
|
||||
|
||||
BOOL NamedPipeCloseHandle(HANDLE handle) {
|
||||
WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE *)handle;
|
||||
static BOOL NamedPipeCloseHandle(HANDLE handle)
|
||||
{
|
||||
WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*)handle;
|
||||
|
||||
if (!NamedPipeIsHandled(handle))
|
||||
return FALSE;
|
||||
|
@ -251,17 +258,16 @@ BOOL NamedPipeCloseHandle(HANDLE handle) {
|
|||
|
||||
if (pNamedPipe->serverfd != -1)
|
||||
close(pNamedPipe->serverfd);
|
||||
|
||||
|
||||
if (pNamedPipe->clientfd != -1)
|
||||
close(pNamedPipe->clientfd);
|
||||
|
||||
free(handle);
|
||||
|
||||
free(pNamedPipe);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL NamedPipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
|
||||
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
int io_status;
|
||||
WINPR_NAMED_PIPE* pipe;
|
||||
|
@ -274,7 +280,7 @@ BOOL NamedPipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
pipe = (WINPR_NAMED_PIPE *)Object;
|
||||
pipe = (WINPR_NAMED_PIPE*)Object;
|
||||
|
||||
if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
|
||||
{
|
||||
|
@ -355,7 +361,7 @@ BOOL NamedPipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
|||
}
|
||||
|
||||
BOOL NamedPipeWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
|
||||
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
int io_status;
|
||||
WINPR_NAMED_PIPE* pipe;
|
||||
|
@ -442,21 +448,20 @@ BOOL NamedPipeWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
|||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
static HANDLE_OPS namedOps = {
|
||||
NamedPipeIsHandled,
|
||||
NamedPipeCloseHandle,
|
||||
NamedPipeGetFd,
|
||||
NULL, /* CleanupHandle */
|
||||
NamedPipeRead,
|
||||
NULL,
|
||||
NULL,
|
||||
NamedPipeWrite
|
||||
static HANDLE_OPS namedOps =
|
||||
{
|
||||
NamedPipeIsHandled,
|
||||
NamedPipeCloseHandle,
|
||||
NamedPipeGetFd,
|
||||
NULL, /* CleanupHandle */
|
||||
NamedPipeRead,
|
||||
NULL,
|
||||
NULL,
|
||||
NamedPipeWrite
|
||||
};
|
||||
|
||||
|
||||
static BOOL InitWinPRPipeModule()
|
||||
{
|
||||
if (g_NamedPipeServerSockets)
|
||||
|
@ -466,13 +471,12 @@ static BOOL InitWinPRPipeModule()
|
|||
return g_NamedPipeServerSockets != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Unnamed pipe
|
||||
*/
|
||||
|
||||
BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
|
||||
BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes,
|
||||
DWORD nSize)
|
||||
{
|
||||
int pipe_fd[2];
|
||||
WINPR_PIPE* pReadPipe;
|
||||
|
@ -500,7 +504,6 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP
|
|||
pWritePipe->fd = pipe_fd[1];
|
||||
WINPR_HANDLE_SET_TYPE_AND_MODE(pReadPipe, HANDLE_TYPE_ANONYMOUS_PIPE, WINPR_FD_READ);
|
||||
pReadPipe->ops = &ops;
|
||||
|
||||
*((ULONG_PTR*) hReadPipe) = (ULONG_PTR) pReadPipe;
|
||||
WINPR_HANDLE_SET_TYPE_AND_MODE(pWritePipe, HANDLE_TYPE_ANONYMOUS_PIPE, WINPR_FD_READ);
|
||||
pWritePipe->ops = &ops;
|
||||
|
@ -528,7 +531,7 @@ static void winpr_unref_named_pipe(WINPR_NAMED_PIPE* pNamedPipe)
|
|||
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))
|
||||
|
@ -555,10 +558,10 @@ static void winpr_unref_named_pipe(WINPR_NAMED_PIPE* pNamedPipe)
|
|||
|
||||
|
||||
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;
|
||||
char* lpPipePath;
|
||||
struct sockaddr_un s;
|
||||
WINPR_NAMED_PIPE* pNamedPipe = NULL;
|
||||
|
@ -579,13 +582,15 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
|
|||
return INVALID_HANDLE_VALUE;
|
||||
|
||||
pNamedPipe = (WINPR_NAMED_PIPE*) calloc(1, sizeof(WINPR_NAMED_PIPE));
|
||||
|
||||
if (!pNamedPipe)
|
||||
return INVALID_HANDLE_VALUE;
|
||||
|
||||
ArrayList_Lock(g_NamedPipeServerSockets);
|
||||
WINPR_HANDLE_SET_TYPE_AND_MODE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE, WINPR_FD_READ);
|
||||
|
||||
pNamedPipe->serverfd = -1;
|
||||
pNamedPipe->clientfd = -1;
|
||||
|
||||
if (!(pNamedPipe->name = _strdup(lpName)))
|
||||
goto out;
|
||||
|
||||
|
@ -605,12 +610,11 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
|
|||
pNamedPipe->clientfd = -1;
|
||||
pNamedPipe->ServerMode = TRUE;
|
||||
pNamedPipe->ops = &namedOps;
|
||||
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))
|
||||
{
|
||||
|
@ -634,15 +638,14 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
|
|||
free(lpPipePath);
|
||||
goto out;
|
||||
}
|
||||
|
||||
UnixChangeFileMode(lpPipePath, 0xFFFF);
|
||||
}
|
||||
|
||||
free(lpPipePath);
|
||||
|
||||
if (PathFileExistsA(pNamedPipe->lpFilePath))
|
||||
{
|
||||
DeleteFileA(pNamedPipe->lpFilePath);
|
||||
}
|
||||
|
||||
if ((serverfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
|
@ -685,6 +688,7 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
|
|||
free(baseSocket->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
//WLog_DBG(TAG, "created shared socked resource for pipe %p (%s). base serverfd = %d", (void*) pNamedPipe, lpName, serverfd);
|
||||
}
|
||||
|
||||
|
@ -704,24 +708,21 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
|
|||
#endif
|
||||
}
|
||||
|
||||
hNamedPipe = (HANDLE) pNamedPipe;
|
||||
ArrayList_Unlock(g_NamedPipeServerSockets);
|
||||
return pNamedPipe;
|
||||
out:
|
||||
NamedPipeCloseHandle(pNamedPipe);
|
||||
|
||||
if (hNamedPipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (pNamedPipe)
|
||||
NamedPipeCloseHandle(pNamedPipe);
|
||||
|
||||
if (serverfd != -1)
|
||||
close(serverfd);
|
||||
}
|
||||
if (serverfd != -1)
|
||||
close(serverfd);
|
||||
|
||||
ArrayList_Unlock(g_NamedPipeServerSockets);
|
||||
return hNamedPipe;
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
WLog_ERR(TAG, "%s is not implemented", __FUNCTION__);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
|
@ -796,15 +797,16 @@ BOOL DisconnectNamedPipe(HANDLE hNamedPipe)
|
|||
}
|
||||
|
||||
BOOL PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize,
|
||||
LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
|
||||
LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL TransactNamedPipe(HANDLE hNamedPipe, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
|
||||
DWORD nOutBufferSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
|
||||
BOOL TransactNamedPipe(HANDLE hNamedPipe, LPVOID lpInBuffer, DWORD nInBufferSize,
|
||||
LPVOID lpOutBuffer,
|
||||
DWORD nOutBufferSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
|
@ -822,6 +824,7 @@ BOOL WaitNamedPipeA(LPCSTR lpNamedPipeName, DWORD nTimeOut)
|
|||
return FALSE;
|
||||
|
||||
lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpNamedPipeName);
|
||||
|
||||
if (!lpFilePath)
|
||||
return FALSE;
|
||||
|
||||
|
@ -855,7 +858,8 @@ BOOL WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout)
|
||||
BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount,
|
||||
LPDWORD lpCollectDataTimeout)
|
||||
{
|
||||
int fd;
|
||||
int flags;
|
||||
|
@ -871,6 +875,7 @@ BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCol
|
|||
return FALSE;
|
||||
|
||||
flags = fcntl(fd, F_GETFL);
|
||||
|
||||
if (flags < 0)
|
||||
return FALSE;
|
||||
|
||||
|
@ -901,14 +906,16 @@ BOOL ImpersonateNamedPipeClient(HANDLE hNamedPipe)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL GetNamedPipeClientComputerNameA(HANDLE Pipe, LPCSTR ClientComputerName, ULONG ClientComputerNameLength)
|
||||
BOOL GetNamedPipeClientComputerNameA(HANDLE Pipe, LPCSTR ClientComputerName,
|
||||
ULONG ClientComputerNameLength)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL GetNamedPipeClientComputerNameW(HANDLE Pipe, LPCWSTR ClientComputerName, ULONG ClientComputerNameLength)
|
||||
BOOL GetNamedPipeClientComputerNameW(HANDLE Pipe, LPCWSTR ClientComputerName,
|
||||
ULONG ClientComputerNameLength)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
|
|
|
@ -183,7 +183,7 @@ void ntlm_free_message_fields_buffer(NTLM_MESSAGE_FIELDS* fields)
|
|||
void ntlm_print_message_fields(NTLM_MESSAGE_FIELDS* fields, const char* name)
|
||||
{
|
||||
WLog_DBG(TAG, "%s (Len: %"PRIu16" MaxLen: %"PRIu16" BufferOffset: %"PRIu32")",
|
||||
name, fields->Len, fields->MaxLen, fields->BufferOffset);
|
||||
name, fields->Len, fields->MaxLen, fields->BufferOffset);
|
||||
|
||||
if (fields->Len > 0)
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, fields->Buffer, fields->Len);
|
||||
|
@ -210,8 +210,8 @@ SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||
Stream_Read_UINT32(s, message->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||
|
||||
if (!((message->NegotiateFlags & NTLMSSP_REQUEST_TARGET) &&
|
||||
(message->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLM) &&
|
||||
(message->NegotiateFlags & NTLMSSP_NEGOTIATE_UNICODE)))
|
||||
(message->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLM) &&
|
||||
(message->NegotiateFlags & NTLMSSP_NEGOTIATE_UNICODE)))
|
||||
{
|
||||
Stream_Free(s, FALSE);
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
@ -245,7 +245,8 @@ SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||
context->NegotiateMessage.BufferType = buffer->BufferType;
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
WLog_DBG(TAG, "NEGOTIATE_MESSAGE (length = %"PRIu32")", context->NegotiateMessage.cbBuffer);
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, context->NegotiateMessage.pvBuffer, 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)
|
||||
|
@ -420,7 +421,8 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||
CopyMemory(context->ChallengeMessage.pvBuffer, StartOffset, length);
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
WLog_DBG(TAG, "CHALLENGE_MESSAGE (length = %d)", length);
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, context->ChallengeMessage.pvBuffer,
|
||||
context->ChallengeMessage.cbBuffer);
|
||||
ntlm_print_negotiate_flags(context->NegotiateFlags);
|
||||
|
||||
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
|
@ -573,7 +575,8 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||
CopyMemory(context->ChallengeMessage.pvBuffer, Stream_Buffer(s), length);
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
WLog_DBG(TAG, "CHALLENGE_MESSAGE (length = %d)", length);
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, context->ChallengeMessage.pvBuffer,
|
||||
context->ChallengeMessage.cbBuffer);
|
||||
ntlm_print_negotiate_flags(message->NegotiateFlags);
|
||||
|
||||
if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
|
@ -611,10 +614,12 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||
if (message->MessageType != MESSAGE_TYPE_AUTHENTICATE)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
if (ntlm_read_message_fields(s, &(message->LmChallengeResponse)) < 0) /* LmChallengeResponseFields (8 bytes) */
|
||||
if (ntlm_read_message_fields(s,
|
||||
&(message->LmChallengeResponse)) < 0) /* LmChallengeResponseFields (8 bytes) */
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
if (ntlm_read_message_fields(s, &(message->NtChallengeResponse)) < 0) /* NtChallengeResponseFields (8 bytes) */
|
||||
if (ntlm_read_message_fields(s,
|
||||
&(message->NtChallengeResponse)) < 0) /* NtChallengeResponseFields (8 bytes) */
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
if (ntlm_read_message_fields(s, &(message->DomainName)) < 0) /* DomainNameFields (8 bytes) */
|
||||
|
@ -626,14 +631,16 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||
if (ntlm_read_message_fields(s, &(message->Workstation)) < 0) /* WorkstationFields (8 bytes) */
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
if (ntlm_read_message_fields(s, &(message->EncryptedRandomSessionKey)) < 0) /* EncryptedRandomSessionKeyFields (8 bytes) */
|
||||
if (ntlm_read_message_fields(s,
|
||||
&(message->EncryptedRandomSessionKey)) < 0) /* EncryptedRandomSessionKeyFields (8 bytes) */
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
Stream_Read_UINT32(s, message->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||
context->NegotiateKeyExchange = (message->NegotiateFlags & NTLMSSP_NEGOTIATE_KEY_EXCH) ? TRUE : FALSE;
|
||||
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)
|
||||
|
@ -653,10 +660,12 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||
if (ntlm_read_message_fields_buffer(s, &(message->Workstation)) < 0) /* Workstation */
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
if (ntlm_read_message_fields_buffer(s, &(message->LmChallengeResponse)) < 0) /* LmChallengeResponse */
|
||||
if (ntlm_read_message_fields_buffer(s,
|
||||
&(message->LmChallengeResponse)) < 0) /* LmChallengeResponse */
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
if (ntlm_read_message_fields_buffer(s, &(message->NtChallengeResponse)) < 0) /* NtChallengeResponse */
|
||||
if (ntlm_read_message_fields_buffer(s,
|
||||
&(message->NtChallengeResponse)) < 0) /* NtChallengeResponse */
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
if (message->NtChallengeResponse.Len > 0)
|
||||
|
@ -682,7 +691,8 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||
Data_Read_UINT32(ntlm_av_pair_get_value_pointer(AvFlags), flags);
|
||||
}
|
||||
|
||||
if (ntlm_read_message_fields_buffer(s, &(message->EncryptedRandomSessionKey)) < 0) /* EncryptedRandomSessionKey */
|
||||
if (ntlm_read_message_fields_buffer(s,
|
||||
&(message->EncryptedRandomSessionKey)) < 0) /* EncryptedRandomSessionKey */
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
if (message->EncryptedRandomSessionKey.Len > 0)
|
||||
|
@ -710,12 +720,12 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
Stream_Read(s, message->MessageIntegrityCheck, 16);
|
||||
PayloadBufferOffset += 16;
|
||||
}
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
WLog_DBG(TAG, "AUTHENTICATE_MESSAGE (length = %"PRIu32")", context->AuthenticateMessage.cbBuffer);
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, context->AuthenticateMessage.pvBuffer, 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));
|
||||
|
@ -853,17 +863,23 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||
message->DomainName.BufferOffset = PayloadBufferOffset;
|
||||
message->UserName.BufferOffset = message->DomainName.BufferOffset + message->DomainName.Len;
|
||||
message->Workstation.BufferOffset = message->UserName.BufferOffset + message->UserName.Len;
|
||||
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;
|
||||
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_fields(s, &(message->LmChallengeResponse)); /* LmChallengeResponseFields (8 bytes) */
|
||||
ntlm_write_message_fields(s, &(message->NtChallengeResponse)); /* NtChallengeResponseFields (8 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) */
|
||||
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)
|
||||
|
@ -887,7 +903,8 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||
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 */
|
||||
ntlm_write_message_fields_buffer(s,
|
||||
&(message->EncryptedRandomSessionKey)); /* EncryptedRandomSessionKey */
|
||||
|
||||
length = Stream_GetPosition(s);
|
||||
|
||||
|
@ -969,10 +986,11 @@ SECURITY_STATUS ntlm_server_AuthenticateComplete(NTLM_CONTEXT* context)
|
|||
|
||||
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
|
||||
{
|
||||
ZeroMemory(&((PBYTE) context->AuthenticateMessage.pvBuffer)[context->MessageIntegrityCheckOffset], 16);
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -129,6 +129,7 @@ int schannel_openssl_client_init(SCHANNEL_OPENSSL* context)
|
|||
}
|
||||
|
||||
status = BIO_set_write_buf_size(context->bioRead, SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
if (status != 1)
|
||||
{
|
||||
WLog_ERR(TAG, "BIO_set_write_buf_size on bioRead failed");
|
||||
|
@ -144,32 +145,39 @@ int schannel_openssl_client_init(SCHANNEL_OPENSSL* context)
|
|||
}
|
||||
|
||||
status = BIO_set_write_buf_size(context->bioWrite, SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
if (status != 1)
|
||||
{
|
||||
WLog_ERR(TAG, "BIO_set_write_buf_size on bioWrite failed");
|
||||
goto out_set_write_buf_write;
|
||||
}
|
||||
|
||||
status = BIO_make_bio_pair(context->bioRead, context->bioWrite);
|
||||
|
||||
if (status != 1)
|
||||
{
|
||||
WLog_ERR(TAG, "BIO_make_bio_pair failed");
|
||||
goto out_bio_pair;
|
||||
}
|
||||
|
||||
SSL_set_bio(context->ssl, context->bioRead, context->bioWrite);
|
||||
context->ReadBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
if (!context->ReadBuffer)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to allocate ReadBuffer");
|
||||
goto out_read_alloc;
|
||||
}
|
||||
|
||||
context->WriteBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
if (!context->WriteBuffer)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to allocate ReadBuffer");
|
||||
goto out_write_alloc;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
out_write_alloc:
|
||||
free(context->ReadBuffer);
|
||||
out_read_alloc:
|
||||
|
@ -190,7 +198,6 @@ int schannel_openssl_server_init(SCHANNEL_OPENSSL* context)
|
|||
{
|
||||
int status;
|
||||
long options = 0;
|
||||
|
||||
context->ctx = SSL_CTX_new(TLSv1_server_method());
|
||||
|
||||
if (!context->ctx)
|
||||
|
@ -263,11 +270,13 @@ int schannel_openssl_server_init(SCHANNEL_OPENSSL* context)
|
|||
}
|
||||
|
||||
status = BIO_set_write_buf_size(context->bioRead, SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
if (status != 1)
|
||||
{
|
||||
WLog_ERR(TAG, "BIO_set_write_buf_size failed for bioRead");
|
||||
goto out_set_write_buf_read;
|
||||
}
|
||||
|
||||
context->bioWrite = BIO_new(BIO_s_mem());
|
||||
|
||||
if (!context->bioWrite)
|
||||
|
@ -277,32 +286,39 @@ int schannel_openssl_server_init(SCHANNEL_OPENSSL* context)
|
|||
}
|
||||
|
||||
status = BIO_set_write_buf_size(context->bioWrite, SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
if (status != 1)
|
||||
{
|
||||
WLog_ERR(TAG, "BIO_set_write_buf_size failed for bioWrite");
|
||||
goto out_set_write_buf_write;
|
||||
}
|
||||
|
||||
status = BIO_make_bio_pair(context->bioRead, context->bioWrite);
|
||||
|
||||
if (status != 1)
|
||||
{
|
||||
WLog_ERR(TAG, "BIO_make_bio_pair failed");
|
||||
goto out_bio_pair;
|
||||
}
|
||||
|
||||
SSL_set_bio(context->ssl, context->bioRead, context->bioWrite);
|
||||
context->ReadBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
if (!context->ReadBuffer)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to allocate memory for ReadBuffer");
|
||||
goto out_read_buffer;
|
||||
}
|
||||
|
||||
context->WriteBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
if (!context->WriteBuffer)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to allocate memory for WriteBuffer");
|
||||
goto out_write_buffer;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
out_write_buffer:
|
||||
free(context->ReadBuffer);
|
||||
out_read_buffer:
|
||||
|
@ -321,7 +337,8 @@ out_rsa_key:
|
|||
return -1;
|
||||
}
|
||||
|
||||
SECURITY_STATUS schannel_openssl_client_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput)
|
||||
SECURITY_STATUS schannel_openssl_client_process_tokens(SCHANNEL_OPENSSL* context,
|
||||
PSecBufferDesc pInput, PSecBufferDesc pOutput)
|
||||
{
|
||||
int status;
|
||||
int ssl_error;
|
||||
|
@ -382,7 +399,8 @@ SECURITY_STATUS schannel_openssl_client_process_tokens(SCHANNEL_OPENSSL* context
|
|||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS schannel_openssl_server_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput)
|
||||
SECURITY_STATUS schannel_openssl_server_process_tokens(SCHANNEL_OPENSSL* context,
|
||||
PSecBufferDesc pInput, PSecBufferDesc pOutput)
|
||||
{
|
||||
int status;
|
||||
int ssl_error;
|
||||
|
@ -468,17 +486,19 @@ SECURITY_STATUS schannel_openssl_encrypt_message(SCHANNEL_OPENSSL* context, PSec
|
|||
if (status > 0)
|
||||
{
|
||||
offset = 0;
|
||||
length = (pStreamHeaderBuffer->cbBuffer > (unsigned long) status) ? status : pStreamHeaderBuffer->cbBuffer;
|
||||
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;
|
||||
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;
|
||||
length = (pStreamTrailerBuffer->cbBuffer > (unsigned long) status) ? status :
|
||||
pStreamTrailerBuffer->cbBuffer;
|
||||
CopyMemory(pStreamTrailerBuffer->pvBuffer, &context->ReadBuffer[offset], length);
|
||||
status -= length;
|
||||
}
|
||||
|
||||
return SEC_E_OK;
|
||||
|
@ -555,12 +575,14 @@ int schannel_openssl_server_init(SCHANNEL_OPENSSL* context)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SECURITY_STATUS schannel_openssl_client_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput)
|
||||
SECURITY_STATUS schannel_openssl_client_process_tokens(SCHANNEL_OPENSSL* context,
|
||||
PSecBufferDesc pInput, PSecBufferDesc pOutput)
|
||||
{
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS schannel_openssl_server_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput)
|
||||
SECURITY_STATUS schannel_openssl_server_process_tokens(SCHANNEL_OPENSSL* context,
|
||||
PSecBufferDesc pInput, PSecBufferDesc pOutput)
|
||||
{
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
@ -582,7 +604,6 @@ SCHANNEL_OPENSSL* schannel_openssl_new(void)
|
|||
|
||||
void schannel_openssl_free(SCHANNEL_OPENSSL* context)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* Synchronization Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2017 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2017 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.
|
||||
|
@ -62,15 +64,18 @@ static BOOL EventIsHandled(HANDLE handle)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static int EventGetFd(HANDLE handle) {
|
||||
WINPR_EVENT *event = (WINPR_EVENT *)handle;
|
||||
static int EventGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_EVENT* event = (WINPR_EVENT*)handle;
|
||||
|
||||
if (!EventIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
return event->pipe_fd[0];
|
||||
}
|
||||
|
||||
BOOL EventCloseHandle(HANDLE handle) {
|
||||
static BOOL EventCloseHandle(HANDLE handle)
|
||||
{
|
||||
WINPR_EVENT* event = (WINPR_EVENT*) handle;
|
||||
|
||||
if (!EventIsHandled(handle))
|
||||
|
@ -83,6 +88,7 @@ BOOL EventCloseHandle(HANDLE handle) {
|
|||
close(event->pipe_fd[0]);
|
||||
event->pipe_fd[0] = -1;
|
||||
}
|
||||
|
||||
if (event->pipe_fd[1] != -1)
|
||||
{
|
||||
close(event->pipe_fd[1]);
|
||||
|
@ -94,29 +100,29 @@ BOOL EventCloseHandle(HANDLE handle) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static HANDLE_OPS ops = {
|
||||
EventIsHandled,
|
||||
EventCloseHandle,
|
||||
EventGetFd,
|
||||
NULL /* CleanupHandle */
|
||||
static HANDLE_OPS ops =
|
||||
{
|
||||
EventIsHandled,
|
||||
EventCloseHandle,
|
||||
EventGetFd,
|
||||
NULL /* CleanupHandle */
|
||||
};
|
||||
|
||||
HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName)
|
||||
HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState,
|
||||
LPCWSTR lpName)
|
||||
{
|
||||
WINPR_EVENT* event;
|
||||
WINPR_EVENT* event = (WINPR_EVENT*) calloc(1, sizeof(WINPR_EVENT));
|
||||
|
||||
event = (WINPR_EVENT*) calloc(1, sizeof(WINPR_EVENT));
|
||||
if (!event)
|
||||
return NULL;
|
||||
|
||||
event->bAttached = FALSE;
|
||||
event->bManualReset = bManualReset;
|
||||
event->ops = &ops;
|
||||
WINPR_HANDLE_SET_TYPE_AND_MODE(event, HANDLE_TYPE_EVENT, FD_READ);
|
||||
|
||||
if (!event->bManualReset)
|
||||
{
|
||||
WLog_ERR(TAG, "auto-reset events not yet implemented");
|
||||
}
|
||||
|
||||
event->pipe_fd[0] = -1;
|
||||
event->pipe_fd[1] = -1;
|
||||
|
@ -124,38 +130,38 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset,
|
|||
event->pipe_fd[0] = eventfd(0, EFD_NONBLOCK);
|
||||
|
||||
if (event->pipe_fd[0] < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "failed to create event");
|
||||
free(event);
|
||||
return NULL;
|
||||
}
|
||||
goto fail;
|
||||
|
||||
#else
|
||||
|
||||
if (pipe(event->pipe_fd) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "failed to create event");
|
||||
free(event);
|
||||
return NULL;
|
||||
}
|
||||
goto fail;
|
||||
|
||||
#endif
|
||||
|
||||
if (bInitialState)
|
||||
SetEvent(event);
|
||||
|
||||
return (HANDLE)event;
|
||||
fail:
|
||||
free(event);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName)
|
||||
HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState,
|
||||
LPCSTR lpName)
|
||||
{
|
||||
return CreateEventW(lpEventAttributes, bManualReset, bInitialState, NULL);
|
||||
}
|
||||
|
||||
HANDLE CreateEventExW(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCWSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess)
|
||||
HANDLE CreateEventExW(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCWSTR lpName, DWORD dwFlags,
|
||||
DWORD dwDesiredAccess)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HANDLE CreateEventExA(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess)
|
||||
HANDLE CreateEventExA(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName, DWORD dwFlags,
|
||||
DWORD dwDesiredAccess)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -207,6 +213,7 @@ BOOL SetEvent(HANDLE hEvent)
|
|||
|
||||
status = (length == 0) ? TRUE : FALSE;
|
||||
#else
|
||||
|
||||
if (WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0)
|
||||
{
|
||||
length = write(event->pipe_fd[1], "-", 1);
|
||||
|
@ -262,8 +269,8 @@ BOOL ResetEvent(HANDLE hEvent)
|
|||
|
||||
|
||||
HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes,
|
||||
BOOL bManualReset, BOOL bInitialState,
|
||||
int FileDescriptor, ULONG mode)
|
||||
BOOL bManualReset, BOOL bInitialState,
|
||||
int FileDescriptor, ULONG mode)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
WINPR_EVENT* event;
|
||||
|
@ -288,25 +295,26 @@ HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes,
|
|||
}
|
||||
|
||||
HANDLE CreateFileDescriptorEventA(LPSECURITY_ATTRIBUTES lpEventAttributes,
|
||||
BOOL bManualReset, BOOL bInitialState,
|
||||
int FileDescriptor, ULONG mode)
|
||||
BOOL bManualReset, BOOL bInitialState,
|
||||
int FileDescriptor, ULONG mode)
|
||||
{
|
||||
return CreateFileDescriptorEventW(lpEventAttributes, bManualReset,
|
||||
bInitialState, FileDescriptor, mode);
|
||||
bInitialState, FileDescriptor, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, WINPR_FD_READ);
|
||||
bInitialState, (int)(ULONG_PTR) pObject, WINPR_FD_READ);
|
||||
#else
|
||||
HANDLE hEvent = NULL;
|
||||
DuplicateHandle(GetCurrentProcess(), pObject, GetCurrentProcess(), &hEvent, 0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
DuplicateHandle(GetCurrentProcess(), pObject, GetCurrentProcess(), &hEvent, 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
return hEvent;
|
||||
#endif
|
||||
}
|
||||
|
@ -364,8 +372,10 @@ int SetEventFileDescriptor(HANDLE hEvent, int FileDescriptor, ULONG mode)
|
|||
return -1;
|
||||
|
||||
event = (WINPR_EVENT*) Object;
|
||||
|
||||
if (!event->bAttached && event->pipe_fd[0] >= 0)
|
||||
close(event->pipe_fd[0]);
|
||||
|
||||
event->bAttached = TRUE;
|
||||
event->Mode = mode;
|
||||
event->pipe_fd[0] = FileDescriptor;
|
||||
|
|
|
@ -115,6 +115,7 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||
lpEscapedCmdLine = NULL;
|
||||
cmdLineLength = (int) strlen(lpCmdLine);
|
||||
lpEscapedChars = (BOOL*) calloc(1, (cmdLineLength + 1) * sizeof(BOOL));
|
||||
|
||||
if (!lpEscapedChars)
|
||||
return NULL;
|
||||
|
||||
|
@ -123,11 +124,13 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||
int i, n;
|
||||
char* pLastEnd = NULL;
|
||||
lpEscapedCmdLine = (char*) malloc((cmdLineLength + 1) * sizeof(char));
|
||||
|
||||
if (!lpEscapedCmdLine)
|
||||
{
|
||||
free(lpEscapedChars);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = (char*) lpCmdLine;
|
||||
pLastEnd = (char*) lpCmdLine;
|
||||
pOutput = (char*) lpEscapedCmdLine;
|
||||
|
@ -141,7 +144,6 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||
length = (int) strlen(p);
|
||||
CopyMemory(pOutput, p, length);
|
||||
pOutput += length;
|
||||
p += length;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -158,8 +160,8 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||
pBeg--;
|
||||
}
|
||||
|
||||
n = (int) ((pEnd - pBeg) - 1);
|
||||
length = (int) (pBeg - pLastEnd);
|
||||
n = (int)((pEnd - pBeg) - 1);
|
||||
length = (int)(pBeg - pLastEnd);
|
||||
CopyMemory(pOutput, p, length);
|
||||
pOutput += length;
|
||||
p += length;
|
||||
|
@ -212,15 +214,17 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||
while (1)
|
||||
{
|
||||
p += strcspn(p, " \t\"\0");
|
||||
|
||||
if ((*p != '"') || !lpEscapedChars[p - lpCmdLine])
|
||||
break;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p != '"')
|
||||
{
|
||||
/* no whitespace escaped with double quotes */
|
||||
length = (int) (p - pBeg);
|
||||
length = (int)(p - pBeg);
|
||||
CopyMemory(pOutput, pBeg, length);
|
||||
pOutput[length] = '\0';
|
||||
pArgs[numArgs++] = pOutput;
|
||||
|
@ -233,8 +237,10 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||
while (1)
|
||||
{
|
||||
p += strcspn(p, "\"\0");
|
||||
|
||||
if ((*p != '"') || !lpEscapedChars[p - lpCmdLine])
|
||||
break;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
|
@ -250,6 +256,7 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||
{
|
||||
if (*pBeg != '"')
|
||||
*pOutput++ = *pBeg;
|
||||
|
||||
pBeg++;
|
||||
}
|
||||
|
||||
|
@ -261,7 +268,6 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||
|
||||
free(lpEscapedCmdLine);
|
||||
free(lpEscapedChars);
|
||||
|
||||
*pNumArgs = numArgs;
|
||||
return pArgs;
|
||||
}
|
||||
|
|
|
@ -285,10 +285,7 @@ int winpr_image_bitmap_read_buffer(wImage* image, BYTE* buffer, int size)
|
|||
return -1;
|
||||
|
||||
if (!vFlip)
|
||||
{
|
||||
CopyMemory(image->data, pSrcData, bi.biSizeImage);
|
||||
pSrcData += bi.biSizeImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDstData = &(image->data[(image->height - 1) * image->scanline]);
|
||||
|
|
|
@ -713,7 +713,6 @@ char* IniFile_WriteBuffer(wIniFile* ini)
|
|||
}
|
||||
|
||||
buffer[offset] = '\0';
|
||||
size += 1;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ BOOL WLog_Layout_GetMessagePrefix(wLog* log, wLogLayout* layout, wLogMessage* me
|
|||
{
|
||||
#if defined __linux__ && !defined ANDROID
|
||||
/* On Linux we prefer to see the LWP id */
|
||||
args[argc++] = (void*)(size_t) syscall(SYS_gettid);;
|
||||
args[argc++] = (void*)(size_t) syscall(SYS_gettid);
|
||||
format[index++] = '%';
|
||||
format[index++] = 'l';
|
||||
format[index++] = 'd';
|
||||
|
|
Loading…
Reference in New Issue