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:
Armin Novak 2017-02-20 18:31:58 +01:00
parent 5bb7a05026
commit b2c29158be
59 changed files with 3079 additions and 2592 deletions

View File

@ -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

View File

@ -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!");

View File

@ -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;
}
}

View File

@ -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);
}
/**

View File

@ -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 */

View File

@ -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)
{

View File

@ -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!");

View File

@ -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);

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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)
{

View File

@ -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;

View File

@ -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))
{

View File

@ -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);
}

View File

@ -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)

View File

@ -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 &region->extents;
}
static RECTANGLE_16 *region16_extents_noconst(REGION16 *region)
static RECTANGLE_16* region16_extents_noconst(REGION16* region)
{
if (!region)
return NULL;
return &region->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(&region->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);

View File

@ -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;

View File

@ -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(&region);
if (!region16_union_rect(&region, &region, &r1))
goto out;;
goto out;
rects = region16_rects(&region, &nbRects);
if (!rects || nbRects != 1 || memcmp(rects, &r1, sizeof(RECTANGLE_16)))
goto out;
/* r1 + r2 */
if (!region16_union_rect(&region, &region, &r2))
goto out;;
rects = region16_rects(&region, &nbRects);
if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2, nbRects))
goto out;
rects = region16_rects(&region, &nbRects);
if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2, nbRects))
goto out;
/* clear region */
region16_clear(&region);
region16_rects(&region, &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(&region);
/*
* +===============================================================
@ -115,20 +122,26 @@ static int test_r1_r3(void) {
/* R1 + R3 */
if (!region16_union_rect(&region, &region, &r1))
goto out;
if (!region16_union_rect(&region, &region, &r3))
goto out;
rects = region16_rects(&region, &nbRects);
if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects))
goto out;
/* R3 + R1 */
region16_clear(&region);
if (!region16_union_rect(&region, &region, &r3))
goto out;
if (!region16_union_rect(&region, &region, &r1))
goto out;
rects = region16_rects(&region, &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(&region);
if (!region16_union_rect(&region, &region, &r9))
goto out;
if (!region16_union_rect(&region, &region, &r10))
goto out;
rects = region16_rects(&region, &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(&region);
/*
* +===============================================================
* |
@ -213,28 +230,29 @@ static int test_r1_r5(void) {
*/
if (!region16_union_rect(&region, &region, &r1))
goto out;
if (!region16_union_rect(&region, &region, &r5))
goto out;
rects = region16_rects(&region, &nbRects);
if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r5, nbRects))
goto out;
retCode = 0;
out:
region16_uninit(&region);
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(&region);
/*
* +===============================================================
@ -249,11 +267,15 @@ static int test_r1_r6(void) {
* |
*/
region16_clear(&region);
if (!region16_union_rect(&region, &region, &r1))
goto out;
if (!region16_union_rect(&region, &region, &r6))
goto out;
rects = region16_rects(&region, &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(&region);
if (!region16_union_rect(&region, &region, &r1))
goto out;
if (!region16_union_rect(&region, &region, &r2))
goto out;
if (!region16_union_rect(&region, &region, &r4))
goto out;
rects = region16_rects(&region, &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(&region);
if (!region16_union_rect(&region, &region, &r1))
goto out;
if (!region16_union_rect(&region, &region, &r7))
goto out;
if (!region16_union_rect(&region, &region, &r8))
goto out;
rects = region16_rects(&region, &nbRects);
if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects))
goto out;
region16_clear(&region);
if (!region16_union_rect(&region, &region, &r1))
goto out;
if (!region16_union_rect(&region, &region, &r8))
goto out;
if (!region16_union_rect(&region, &region, &r7))
goto out;
rects = region16_rects(&region, &nbRects);
if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects))
goto out;
region16_clear(&region);
if (!region16_union_rect(&region, &region, &r8))
goto out;
if (!region16_union_rect(&region, &region, &r7))
goto out;
if (!region16_union_rect(&region, &region, &r1))
goto out;
rects = region16_rects(&region, &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(&region);
/*
* +===============================================================
* |
@ -422,11 +466,15 @@ static int test_r1_r2_r3_r4(void) {
*/
if (!region16_union_rect(&region, &region, &r1))
goto out;
if (!region16_union_rect(&region, &region, &r2))
goto out;
if (!region16_union_rect(&region, &region, &r3))
goto out;
rects = region16_rects(&region, &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(&region, &region, &r4))
goto out;
rects = region16_rects(&region, &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(&region);
/*
* +===============================================================
* |+-------------------------------------------------------------+
@ -498,12 +548,15 @@ static int test_from_weston(void)
*/
if (!region16_union_rect(&region, &region, &r1))
goto out;
if (!region16_union_rect(&region, &region, &r2))
goto out;
if (!region16_union_rect(&region, &region, &r3))
goto out;
rects = region16_rects(&region, &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(&region);
region16_init(&intersection);
@ -541,35 +594,37 @@ static int test_r1_inter_r3(void) {
*/
if (!region16_union_rect(&region, &region, &r1))
goto out;
if (!region16_intersects_rect(&region, &r3))
goto out;
if (!region16_intersect_rect(&intersection, &region, &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(&region);
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(&region);
region16_init(&intersection);
@ -595,6 +650,7 @@ static int test_r1_r3_inter_r11(void) {
*/
if (!region16_union_rect(&region, &region, &r1))
goto out;
if (!region16_union_rect(&region, &region, &r3))
goto out;
@ -603,7 +659,9 @@ static int test_r1_r3_inter_r11(void) {
if (!region16_intersect_rect(&intersection, &region, &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(&region);
region16_init(&intersection);
@ -670,16 +729,18 @@ static int test_norbert_case(void) {
goto out;
}
if (!compareRectangles(region16_extents(&region), &expected_inter_extents, 1) )
if (!compareRectangles(region16_extents(&region), &expected_inter_extents, 1))
goto out;
if (!region16_intersect_rect(&intersection, &region, &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(&region);
if (!region16_union_rect(&region, &region, &rect1)) {
if (!region16_union_rect(&region, &region, &rect1))
{
fprintf(stderr, "%s: Error 1 - region16_union_rect failed\n", __FUNCTION__);
goto out;
}
if (!(rects = region16_rects(&region, &nbRects))) {
if (!(rects = region16_rects(&region, &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(&region, &region, &rect2)) {
if (!region16_union_rect(&region, &region, &rect2))
{
fprintf(stderr, "%s: Error 5 - region16_union_rect failed\n", __FUNCTION__);
goto out;
}
if (!(rects = region16_rects(&region, &nbRects))) {
if (!(rects = region16_rects(&region, &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(&region);
region16_init(&intersection);
@ -792,7 +864,7 @@ static int test_empty_rectangle(void) {
if (!region16_intersect_rect(&region, &region, &anotherRect))
goto out;
if (!compareRectangles(region16_extents(&region), &expected_inter_extents, 1) )
if (!compareRectangles(region16_extents(&region), &expected_inter_extents, 1))
goto out;
if (!region16_is_empty(&region))
@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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 */

View File

@ -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);
}

View File

@ -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++)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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)
{

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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]);

View File

@ -713,7 +713,6 @@ char* IniFile_WriteBuffer(wIniFile* ini)
}
buffer[offset] = '\0';
size += 1;
return buffer;
}

View File

@ -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';