From: Armin Novak Date: Mon, 20 Feb 2017 17:31:58 +0000 (+0100) Subject: Scanbuild warning, argument checks and leak fixes. X-Git-Tag: 2.0.0-beta1+android10^2~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b2c29158be5114f3b98335baeb844824dd4ce3ab;p=platform%2Fupstream%2Ffreerdp.git 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 --- diff --git a/channels/audin/client/alsa/audin_alsa.c b/channels/audin/client/alsa/audin_alsa.c index c01eafc..e1e0001 100644 --- a/channels/audin/client/alsa/audin_alsa.c +++ b/channels/audin/client/alsa/audin_alsa.c @@ -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 diff --git a/channels/audin/client/pulse/audin_pulse.c b/channels/audin/client/pulse/audin_pulse.c index 56ece86..d854dca 100644 --- a/channels/audin/client/pulse/audin_pulse.c +++ b/channels/audin/client/pulse/audin_pulse.c @@ -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!"); diff --git a/channels/client/addin.c b/channels/client/addin.c index dba6154..b0a24ec 100644 --- a/channels/client/addin.c +++ b/channels/client/addin.c @@ -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) { /* -client. */ - 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) { /* -client-. */ - 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) { /* -client--. */ - 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; } } diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index fefd0e8..229124f 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -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); } /** diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c index 2dc8147..bf1114e 100644 --- a/channels/drive/client/drive_file.c +++ b/channels/drive/client/drive_file.c @@ -9,6 +9,8 @@ * Copyright 2015 DI (FH) Martin Haimberger * Copyright 2016 Inuvika Inc. * Copyright 2016 David PHAM-VAN + * Copyright 2017 Armin Novak + * 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 */ diff --git a/channels/rail/client/rail_main.c b/channels/rail/client/rail_main.c index dae8242..b9c6a13 100644 --- a/channels/rail/client/rail_main.c +++ b/channels/rail/client/rail_main.c @@ -7,6 +7,8 @@ * Copyright 2011 Vic Lee * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2017 Armin Novak + * 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) { diff --git a/channels/rail/client/rail_orders.c b/channels/rail/client/rail_orders.c index adcea21..a7ef11d 100644 --- a/channels/rail/client/rail_orders.c +++ b/channels/rail/client/rail_orders.c @@ -6,6 +6,8 @@ * Copyright 2011 Roman Barabanov * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2017 Armin Novak + * 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!"); diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index 93d3560..0e4abff 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -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); diff --git a/channels/rdpei/rdpei_common.c b/channels/rdpei/rdpei_common.c index 62625ec..41a2ec3 100644 --- a/channels/rdpei/rdpei_common.c +++ b/channels/rdpei/rdpei_common.c @@ -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) { diff --git a/channels/rdpgfx/server/rdpgfx_main.c b/channels/rdpgfx/server/rdpgfx_main.c index 78ec176..29ccfdb 100644 --- a/channels/rdpgfx/server/rdpgfx_main.c +++ b/channels/rdpgfx/server/rdpgfx_main.c @@ -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; diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 1614942..a34cc0b 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -7,6 +7,8 @@ * Copyright 2011 Anthony Tong * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2017 Armin Novak + * 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; diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index 0f8312a..560330a 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -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) { diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 531c8bc..6336a8a 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -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) - { - if (MessageQueue_Peek(queue, &msg, FALSE)) - { - if (msg.id == WMQ_QUIT) - break; - } - } - - if (WaitForSingleObject(events[1], 0) == WAIT_OBJECT_0) + switch (status) { - do - { - xf_lock_x11(xfc, FALSE); - pending_status = XPending(xfc->display); - xf_unlock_x11(xfc, FALSE); + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + case WAIT_OBJECT_0 + 2: + if (WaitForSingleObject(events[0], 0) == WAIT_OBJECT_0) + { + if (MessageQueue_Peek(queue, &msg, FALSE)) + { + if (msg.id == WMQ_QUIT) + running = FALSE; + } + } - if (pending_status) + if (WaitForSingleObject(events[1], 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); + 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 diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 2d5130b..f072021 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -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) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index db51a08..374e407 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -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); diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index 7a62855..4b9a81f 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -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; diff --git a/client/X11/xf_input.c b/client/X11/xf_input.c index c8b9cd5..cf99000 100644 --- a/client/X11/xf_input.c +++ b/client/X11/xf_input.c @@ -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); diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 575d60f..d54b2ce 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -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; } diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c index 73895c5..977ffce 100644 --- a/client/X11/xf_monitor.c +++ b/client/X11/xf_monitor.c @@ -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; diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index c9d4ea7..5050d95 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -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; } diff --git a/client/common/compatibility.c b/client/common/compatibility.c index 89c6417..a95b6a3 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -3,6 +3,8 @@ * FreeRDP Client Compatibility * * Copyright 2012 Marc-Andre Moreau + * Copyright 2017 Armin Novak + * 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); diff --git a/client/common/file.c b/client/common/file.c index b6ffc09..ea3c504 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -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) { diff --git a/libfreerdp/cache/glyph.c b/libfreerdp/cache/glyph.c index cf0f3d8..0292e0e 100644 --- a/libfreerdp/cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -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; diff --git a/libfreerdp/codec/mppc.c b/libfreerdp/codec/mppc.c index 1ae8615..0151b89 100644 --- a/libfreerdp/codec/mppc.c +++ b/libfreerdp/codec/mppc.c @@ -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)) { diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c index c66eb1b..dde1cda 100644 --- a/libfreerdp/codec/planar.c +++ b/libfreerdp/codec/planar.c @@ -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); } diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c index 8b926f0..6d228b8 100644 --- a/libfreerdp/codec/progressive.c +++ b/libfreerdp/codec/progressive.c @@ -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) diff --git a/libfreerdp/codec/region.c b/libfreerdp/codec/region.c index 7c32980..1015f46 100644 --- a/libfreerdp/codec/region.c +++ b/libfreerdp/codec/region.c @@ -3,6 +3,8 @@ * * Copyright 2014 Thincast Technologies GmbH * Copyright 2014 Hardening + * Copyright 2017 Armin Novak + * 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) +const RECTANGLE_16* region16_rects(const REGION16* region, UINT32* nbRects) { - REGION16_DATA *data; + REGION16_DATA* data; - assert(region); + if (nbRects) + *nbRects = 0; + + if (!region) + return NULL; data = region->data; + if (!data) - { - if (nbRects) - *nbRects = 0; return NULL; - } if (nbRects) *nbRects = data->nbRects; - return (RECTANGLE_16 *)(data + 1); + + return (RECTANGLE_16*)(data + 1); } -static INLINE RECTANGLE_16 *region16_rects_noconst(REGION16 *region) +static INLINE RECTANGLE_16* region16_rects_noconst(REGION16* region) { REGION16_DATA* data; - data = region->data; if (!data) @@ -120,17 +122,23 @@ static INLINE RECTANGLE_16 *region16_rects_noconst(REGION16 *region) return (RECTANGLE_16*)(&data[1]); } -const RECTANGLE_16 *region16_extents(const REGION16 *region) +const RECTANGLE_16* region16_extents(const REGION16* region) { + if (!region) + return NULL; + return ®ion->extents; } -static RECTANGLE_16 *region16_extents_noconst(REGION16 *region) +static RECTANGLE_16* region16_extents_noconst(REGION16* region) { + if (!region) + return NULL; + return ®ion->extents; } -BOOL rectangle_is_empty(const RECTANGLE_16 *rect) +BOOL rectangle_is_empty(const RECTANGLE_16* rect) { /* A rectangle with width = 0 or height = 0 should be regarded * as empty. @@ -138,38 +146,36 @@ BOOL rectangle_is_empty(const RECTANGLE_16 *rect) return ((rect->left == rect->right) || (rect->top == rect->bottom)) ? TRUE : FALSE; } -BOOL region16_is_empty(const REGION16 *region) +BOOL region16_is_empty(const REGION16* region) { assert(region); assert(region->data); - return (region->data->nbRects == 0); } -BOOL rectangles_equal(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2) +BOOL rectangles_equal(const RECTANGLE_16* r1, const RECTANGLE_16* r2) { return ((r1->left == r2->left) && (r1->top == r2->top) && - (r1->right == r2->right) && (r1->bottom == r2->bottom)) ? TRUE : FALSE; + (r1->right == r2->right) && (r1->bottom == r2->bottom)) ? TRUE : FALSE; } -BOOL rectangles_intersects(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2) +BOOL rectangles_intersects(const RECTANGLE_16* r1, const RECTANGLE_16* r2) { RECTANGLE_16 tmp; return rectangles_intersection(r1, r2, &tmp); } -BOOL rectangles_intersection(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2, - RECTANGLE_16 *dst) +BOOL rectangles_intersection(const RECTANGLE_16* r1, const RECTANGLE_16* r2, + RECTANGLE_16* dst) { dst->left = MAX(r1->left, r2->left); dst->right = MIN(r1->right, r2->right); dst->top = MAX(r1->top, r2->top); dst->bottom = MIN(r1->bottom, r2->bottom); - return (dst->left < dst->right) && (dst->top < dst->bottom); } -void region16_clear(REGION16 *region) +void region16_clear(REGION16* region) { assert(region); assert(region->data); @@ -178,14 +184,12 @@ void region16_clear(REGION16 *region) free(region->data); region->data = &empty_region; - ZeroMemory(®ion->extents, sizeof(region->extents)); } static INLINE REGION16_DATA* allocateRegion(long nbItems) { long allocSize = sizeof(REGION16_DATA) + (nbItems * sizeof(RECTANGLE_16)); - REGION16_DATA* ret = (REGION16_DATA*) malloc(allocSize); if (!ret) @@ -193,11 +197,10 @@ static INLINE REGION16_DATA* allocateRegion(long nbItems) ret->size = allocSize; ret->nbRects = nbItems; - return ret; } -BOOL region16_copy(REGION16 *dst, const REGION16 *src) +BOOL region16_copy(REGION16* dst, const REGION16* src) { assert(dst); assert(dst->data); @@ -229,12 +232,11 @@ BOOL region16_copy(REGION16 *dst, const REGION16 *src) return TRUE; } -void region16_print(const REGION16 *region) +void region16_print(const REGION16* region) { - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects, i; int currentBandY = -1; - rects = region16_rects(region, &nbRects); WLog_DBG(TAG, "nrects=%"PRIu32"", nbRects); @@ -246,19 +248,20 @@ void region16_print(const REGION16 *region) WLog_DBG(TAG, "band %d: ", currentBandY); } - WLog_DBG(TAG, "(%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16")", rects->left, rects->top, rects->right, rects->bottom); + WLog_DBG(TAG, "(%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16")", rects->left, rects->top, rects->right, + rects->bottom); } } -static void region16_copy_band_with_union(RECTANGLE_16 *dst, - const RECTANGLE_16 *src, const RECTANGLE_16 *end, - UINT16 newTop, UINT16 newBottom, - const RECTANGLE_16 *unionRect, - UINT32 *dstCounter, - const RECTANGLE_16 **srcPtr, RECTANGLE_16 **dstPtr) +static void region16_copy_band_with_union(RECTANGLE_16* dst, + const RECTANGLE_16* src, const RECTANGLE_16* end, + UINT16 newTop, UINT16 newBottom, + const RECTANGLE_16* unionRect, + UINT32* dstCounter, + const RECTANGLE_16** srcPtr, RECTANGLE_16** dstPtr) { UINT16 refY = src->top; - const RECTANGLE_16 *startOverlap, *endOverlap; + const RECTANGLE_16* startOverlap, *endOverlap; /* merges a band with the given rect * Input: @@ -293,8 +296,9 @@ static void region16_copy_band_with_union(RECTANGLE_16 *dst, dst->bottom = newBottom; dst->right = src->right; dst->left = src->left; - - src++; dst++; *dstCounter += 1; + src++; + dst++; + *dstCounter += 1; } /* treat items overlapping with unionRect */ @@ -319,7 +323,8 @@ static void region16_copy_band_with_union(RECTANGLE_16 *dst, dst->top = newTop; dst->left = startOverlap->left; dst->right = endOverlap->right; - dst++; *dstCounter += 1; + dst++; + *dstCounter += 1; } /* treat remaining items on the same band */ @@ -329,8 +334,9 @@ static void region16_copy_band_with_union(RECTANGLE_16 *dst, dst->bottom = newBottom; dst->right = src->right; dst->left = src->left; - - src++; dst++; *dstCounter += 1; + src++; + dst++; + *dstCounter += 1; } if (srcPtr) @@ -342,10 +348,9 @@ static void region16_copy_band_with_union(RECTANGLE_16 *dst, static RECTANGLE_16* next_band(RECTANGLE_16* band1, RECTANGLE_16* endPtr, int* nbItems) { UINT16 refY = band1->top; - *nbItems = 0; - while((band1 < endPtr) && (band1->top == refY)) + while ((band1 < endPtr) && (band1->top == refY)) { band1++; *nbItems += 1; @@ -380,8 +385,8 @@ static BOOL band_match(const RECTANGLE_16* band1, const RECTANGLE_16* band2, REC * @param rect the rectangle to test * @return if rect is fully included in an item of the band */ -static BOOL rectangle_contained_in_band(const RECTANGLE_16 *band, const RECTANGLE_16 *endPtr, - const RECTANGLE_16 *rect) +static BOOL rectangle_contained_in_band(const RECTANGLE_16* band, const RECTANGLE_16* endPtr, + const RECTANGLE_16* rect) { UINT16 refY = band->top; @@ -391,17 +396,18 @@ static BOOL rectangle_contained_in_band(const RECTANGLE_16 *band, const RECTANGL /* note: as the band is sorted from left to right, once we've seen an item * that is after rect->left we're sure that the result is False. */ - while( (band < endPtr) && (band->top == refY) && (band->left <= rect->left)) + while ((band < endPtr) && (band->top == refY) && (band->left <= rect->left)) { if (rect->right <= band->right) return TRUE; band++; } + return FALSE; } -BOOL region16_simplify_bands(REGION16 *region) +static BOOL region16_simplify_bands(REGION16* region) { /** Simplify consecutive bands that touch and have the same items * @@ -414,10 +420,9 @@ BOOL region16_simplify_bands(REGION16 *region) * ==================== ==================== * */ - RECTANGLE_16 *band1, *band2, *endPtr, *endBand, *tmp; + RECTANGLE_16* band1, *band2, *endPtr, *endBand, *tmp; int nbRects, finalNbRects; int bandItems, toMove; - finalNbRects = nbRects = region16_n_rects(region); if (nbRects < 2) @@ -437,6 +442,7 @@ BOOL region16_simplify_bands(REGION16 *region) { /* adjust the bottom of band1 items */ tmp = band1; + while (tmp < band2) { tmp->bottom = band2->bottom; @@ -459,7 +465,7 @@ BOOL region16_simplify_bands(REGION16 *region) band1 = band2; } } - while(TRUE); + while (TRUE); if (finalNbRects != nbRects) { @@ -479,20 +485,18 @@ BOOL region16_simplify_bands(REGION16 *region) return TRUE; } -BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *rect) +BOOL region16_union_rect(REGION16* dst, const REGION16* src, const RECTANGLE_16* rect) { const RECTANGLE_16* srcExtents; RECTANGLE_16* dstExtents; - const RECTANGLE_16 *currentBand, *endSrcRect, *nextBand; + const RECTANGLE_16* currentBand, *endSrcRect, *nextBand; REGION16_DATA* newItems = NULL; RECTANGLE_16* dstRect = NULL; UINT32 usedRects, srcNbRects; UINT16 topInterBand; - assert(src); assert(src->data); assert(dst); - srcExtents = region16_extents(src); dstExtents = region16_extents_noconst(dst); @@ -506,12 +510,10 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 return FALSE; dstRect = region16_rects_noconst(dst); - dstRect->top = rect->top; dstRect->left = rect->left; dstRect->right = rect->right; dstRect->bottom = rect->bottom; - return TRUE; } @@ -520,7 +522,7 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 if (!newItems) return FALSE; - dstRect = (RECTANGLE_16*) (&newItems[1]); + dstRect = (RECTANGLE_16*)(&newItems[1]); usedRects = 0; /* adds the piece of rect that is on the top of src */ @@ -530,7 +532,6 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 dstRect->left = rect->left; dstRect->right = rect->right; dstRect->bottom = MIN(srcExtents->top, rect->bottom); - usedRects++; dstRect++; } @@ -542,7 +543,7 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 while (currentBand < endSrcRect) { if ((currentBand->bottom <= rect->top) || (rect->bottom <= currentBand->top) || - rectangle_contained_in_band(currentBand, endSrcRect, rect)) + rectangle_contained_in_band(currentBand, endSrcRect, rect)) { /* no overlap between rect and the band, rect is totally below or totally above * the current band, or rect is already covered by an item of the band. @@ -552,33 +553,32 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 +----+ ================= - band of srcRect - ================= - +----+ - | | rect (case 2) - +----+ - */ + band of srcRect + ================= + +----+ + | | rect (case 2) + +----+ + */ region16_copy_band_with_union(dstRect, - currentBand, endSrcRect, - currentBand->top, currentBand->bottom, - NULL, &usedRects, - &nextBand, &dstRect); + currentBand, endSrcRect, + currentBand->top, currentBand->bottom, + NULL, &usedRects, + &nextBand, &dstRect); topInterBand = rect->top; } else { - /* rect overlaps the band: | | | | - ====^=================| |==| |=========================== band - | top split | | | | - v | 1 | | 2 | - ^ | | | | +----+ +----+ - | merge zone | | | | | | | 4 | - v +----+ | | | | +----+ - ^ | | | 3 | - | bottom split | | | | - ====v=========================| |==| |=================== + ====^=================| |==| |=========================== band + | top split | | | | + v | 1 | | 2 | + ^ | | | | +----+ +----+ + | merge zone | | | | | | | 4 | + v +----+ | | | | +----+ + ^ | | | 3 | + | bottom split | | | | + ====v=========================| |==| |=================== | | | | possible cases: @@ -597,10 +597,10 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 if (rect->top > currentBand->top) { region16_copy_band_with_union(dstRect, - currentBand, endSrcRect, - currentBand->top, rect->top, - NULL, &usedRects, - &nextBand, &dstRect); + currentBand, endSrcRect, + currentBand->top, rect->top, + NULL, &usedRects, + &nextBand, &dstRect); mergeTop = rect->top; } @@ -609,20 +609,21 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 mergeBottom = rect->bottom; region16_copy_band_with_union(dstRect, - currentBand, endSrcRect, - mergeTop, mergeBottom, - rect, &usedRects, - &nextBand, &dstRect); + currentBand, endSrcRect, + mergeTop, mergeBottom, + rect, &usedRects, + &nextBand, &dstRect); /* test if we need a bottom split, case 1 and 4 */ if (rect->bottom < currentBand->bottom) { region16_copy_band_with_union(dstRect, - currentBand, endSrcRect, - mergeBottom, currentBand->bottom, - NULL, &usedRects, - &nextBand, &dstRect); + currentBand, endSrcRect, + mergeBottom, currentBand->bottom, + NULL, &usedRects, + &nextBand, &dstRect); } + topInterBand = currentBand->bottom; } @@ -642,13 +643,14 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 * */ if ((nextBand < endSrcRect) && (nextBand->top != currentBand->bottom) && - (rect->bottom > currentBand->bottom) && (rect->top < nextBand->top)) + (rect->bottom > currentBand->bottom) && (rect->top < nextBand->top)) { dstRect->right = rect->right; dstRect->left = rect->left; dstRect->top = topInterBand; dstRect->bottom = MIN(nextBand->top, rect->bottom); - dstRect++; usedRects++; + dstRect++; + usedRects++; } currentBand = nextBand; @@ -661,7 +663,6 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 dstRect->left = rect->left; dstRect->right = rect->right; dstRect->bottom = rect->bottom; - usedRects++; dstRect++; } @@ -673,7 +674,6 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 dstExtents->left = MIN(rect->left, srcExtents->left); dstExtents->bottom = MAX(rect->bottom, srcExtents->bottom); dstExtents->right = MAX(rect->right, srcExtents->right); - newItems->size = sizeof(REGION16_DATA) + (usedRects * sizeof(RECTANGLE_16)); dst->data = realloc(newItems, newItems->size); @@ -684,17 +684,16 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 } dst->data->nbRects = usedRects; - return region16_simplify_bands(dst); } -BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2) +BOOL region16_intersects_rect(const REGION16* src, const RECTANGLE_16* arg2) { - const RECTANGLE_16 *rect, *endPtr, *srcExtents; + const RECTANGLE_16* rect, *endPtr, *srcExtents; UINT32 nbRects; - assert(src); - assert(src->data); + if (!src || !src->data || !arg2) + return FALSE; rect = region16_rects(src, &nbRects); @@ -709,8 +708,6 @@ BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2) if (!rectangles_intersects(srcExtents, arg2)) return FALSE; - endPtr = rect + nbRects; - for (endPtr = rect + nbRects; (rect < endPtr) && (arg2->bottom > rect->top); rect++) { if (rectangles_intersects(rect, arg2)) @@ -720,17 +717,15 @@ BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2) return FALSE; } -BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *rect) +BOOL region16_intersect_rect(REGION16* dst, const REGION16* src, const RECTANGLE_16* rect) { - REGION16_DATA *newItems; - const RECTANGLE_16 *srcPtr, *endPtr, *srcExtents; - RECTANGLE_16 *dstPtr; + REGION16_DATA* newItems; + const RECTANGLE_16* srcPtr, *endPtr, *srcExtents; + RECTANGLE_16* dstPtr; UINT32 nbRects, usedRects; RECTANGLE_16 common, newExtents; - assert(src); assert(src->data); - srcPtr = region16_rects(src, &nbRects); if (!nbRects) @@ -744,7 +739,6 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE if (nbRects == 1) { BOOL intersects = rectangles_intersection(srcExtents, rect, &common); - region16_clear(dst); if (intersects) @@ -758,7 +752,7 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE if (!newItems) return FALSE; - dstPtr = (RECTANGLE_16*) (&newItems[1]); + dstPtr = (RECTANGLE_16*)(&newItems[1]); usedRects = 0; ZeroMemory(&newExtents, sizeof(newExtents)); @@ -809,7 +803,7 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE return region16_simplify_bands(dst); } -void region16_uninit(REGION16 *region) +void region16_uninit(REGION16* region) { assert(region); diff --git a/libfreerdp/codec/rfx_sse2.c b/libfreerdp/codec/rfx_sse2.c index f89efe8..94c6b21 100644 --- a/libfreerdp/codec/rfx_sse2.c +++ b/libfreerdp/codec/rfx_sse2.c @@ -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; diff --git a/libfreerdp/codec/test/TestFreeRDPRegion.c b/libfreerdp/codec/test/TestFreeRDPRegion.c index 552c254..8dfa389 100644 --- a/libfreerdp/codec/test/TestFreeRDPRegion.c +++ b/libfreerdp/codec/test/TestFreeRDPRegion.c @@ -23,58 +23,65 @@ #include -static BOOL compareRectangles(const RECTANGLE_16 *src1, const RECTANGLE_16 *src2, int nb) +static BOOL compareRectangles(const RECTANGLE_16* src1, const RECTANGLE_16* src2, int nb) { int i; - for (i = 0; i< nb; i++, src1++, src2++) + + for (i = 0; i < nb; i++, src1++, src2++) { if (memcmp(src1, src2, sizeof(RECTANGLE_16))) { - fprintf(stderr, "expecting rect %d (%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16") and have (%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16")\n", - i, src2->left, src2->top, src2->right, src2->bottom, - src1->left, src1->top, src1->right, src1->bottom - ); + fprintf(stderr, + "expecting rect %d (%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16") and have (%"PRIu16",%"PRIu16"-%"PRIu16",%"PRIu16")\n", + i, src2->left, src2->top, src2->right, src2->bottom, + src1->left, src1->top, src1->right, src1->bottom + ); return FALSE; } } + return TRUE; } -static int test_basic(void) { +static int test_basic(void) +{ REGION16 region; int retCode = -1; - const RECTANGLE_16 *rects; - UINT32 nbRects; - + const RECTANGLE_16* rects; + UINT32 nbRects; /* R1 + R2 ==> disjointed rects */ RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r2 = {150, 301, 250, 401}; - - RECTANGLE_16 r1_r2[] = { + RECTANGLE_16 r1_r2[] = + { {0, 101, 200, 201}, {150, 301, 250, 401} }; - /* r1 */ region16_init(®ion); + if (!region16_union_rect(®ion, ®ion, &r1)) - goto out;; + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 1 || memcmp(rects, &r1, sizeof(RECTANGLE_16))) goto out; /* r1 + r2 */ if (!region16_union_rect(®ion, ®ion, &r2)) - goto out;; + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2, nbRects)) goto out; - /* clear region */ region16_clear(®ion); region16_rects(®ion, &nbRects); + if (nbRects) goto out; @@ -85,20 +92,20 @@ out: } -static int test_r1_r3(void) { +static int test_r1_r3(void) +{ REGION16 region; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects; - RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r3 = {150, 151, 250, 251}; - RECTANGLE_16 r1_r3[] = { + RECTANGLE_16 r1_r3[] = + { { 0, 101, 200, 151}, { 0, 151, 250, 201}, {150, 201, 250, 251} }; - region16_init(®ion); /* * +=============================================================== @@ -115,20 +122,26 @@ static int test_r1_r3(void) { /* R1 + R3 */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + if (!region16_union_rect(®ion, ®ion, &r3)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects)) goto out; - /* R3 + R1 */ region16_clear(®ion); + if (!region16_union_rect(®ion, ®ion, &r3)) goto out; + if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects)) goto out; @@ -139,12 +152,12 @@ out: } -static int test_r9_r10(void) { +static int test_r9_r10(void) +{ REGION16 region; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects; - /* * +=============================================================== * | @@ -160,18 +173,22 @@ static int test_r9_r10(void) { */ RECTANGLE_16 r9 = { 0, 100, 400, 200}; RECTANGLE_16 r10 = {200, 0, 300, 300}; - RECTANGLE_16 r9_r10[] = { - {200, 0, 300, 100}, - { 0, 100, 400, 200}, - {200, 200, 300, 300}, + RECTANGLE_16 r9_r10[] = + { + {200, 0, 300, 100}, + { 0, 100, 400, 200}, + {200, 200, 300, 300}, }; - region16_init(®ion); + if (!region16_union_rect(®ion, ®ion, &r9)) goto out; + if (!region16_union_rect(®ion, ®ion, &r10)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r9_r10, nbRects)) goto out; @@ -182,22 +199,22 @@ out: } -static int test_r1_r5(void) { +static int test_r1_r5(void) +{ REGION16 region; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects; - RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r5 = {150, 121, 300, 131}; - - RECTANGLE_16 r1_r5[] = { + RECTANGLE_16 r1_r5[] = + { { 0, 101, 200, 121}, { 0, 121, 300, 131}, { 0, 131, 200, 201} }; - region16_init(®ion); + /* * +=============================================================== * | @@ -213,28 +230,29 @@ static int test_r1_r5(void) { */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + if (!region16_union_rect(®ion, ®ion, &r5)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r5, nbRects)) goto out; - retCode = 0; out: region16_uninit(®ion); return retCode; } -static int test_r1_r6(void) { +static int test_r1_r6(void) +{ REGION16 region; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects; - RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r6 = {150, 121, 170, 131}; - region16_init(®ion); /* * +=============================================================== @@ -249,11 +267,15 @@ static int test_r1_r6(void) { * | */ region16_clear(®ion); + if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + if (!region16_union_rect(®ion, ®ion, &r6)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 1 || !compareRectangles(rects, &r1, nbRects)) goto out; @@ -264,19 +286,20 @@ out: } -static int test_r1_r2_r4(void) { +static int test_r1_r2_r4(void) +{ REGION16 region; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r2 = {150, 301, 250, 401}; RECTANGLE_16 r4 = {150, 251, 250, 301}; - RECTANGLE_16 r1_r2_r4[] = { + RECTANGLE_16 r1_r2_r4[] = + { { 0, 101, 200, 201}, {150, 251, 250, 401} }; - /* * +=============================================================== * | @@ -295,13 +318,18 @@ static int test_r1_r2_r4(void) { * */ region16_init(®ion); + if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + if (!region16_union_rect(®ion, ®ion, &r2)) goto out; + if (!region16_union_rect(®ion, ®ion, &r4)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2_r4, nbRects)) goto out; @@ -312,23 +340,23 @@ out: } -static int test_r1_r7_r8(void) { +static int test_r1_r7_r8(void) +{ REGION16 region; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r7 = {300, 101, 500, 201}; RECTANGLE_16 r8 = {150, 121, 400, 131}; - - RECTANGLE_16 r1_r7_r8[] = { + RECTANGLE_16 r1_r7_r8[] = + { { 0, 101, 200, 121}, {300, 101, 500, 121}, { 0, 121, 500, 131}, { 0, 131, 200, 201}, {300, 131, 500, 201}, }; - /* * +=============================================================== * | @@ -342,35 +370,50 @@ static int test_r1_r7_r8(void) { * | */ region16_init(®ion); + if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + if (!region16_union_rect(®ion, ®ion, &r7)) goto out; + if (!region16_union_rect(®ion, ®ion, &r8)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects)) goto out; region16_clear(®ion); + if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + if (!region16_union_rect(®ion, ®ion, &r8)) goto out; + if (!region16_union_rect(®ion, ®ion, &r7)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects)) goto out; region16_clear(®ion); + if (!region16_union_rect(®ion, ®ion, &r8)) goto out; + if (!region16_union_rect(®ion, ®ion, &r7)) goto out; + if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects)) goto out; @@ -381,30 +424,31 @@ out: } -static int test_r1_r2_r3_r4(void) { +static int test_r1_r2_r3_r4(void) +{ REGION16 region; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r2 = {150, 301, 250, 401}; RECTANGLE_16 r3 = {150, 151, 250, 251}; RECTANGLE_16 r4 = {150, 251, 250, 301}; - - RECTANGLE_16 r1_r2_r3[] = { + RECTANGLE_16 r1_r2_r3[] = + { { 0, 101, 200, 151}, { 0, 151, 250, 201}, {150, 201, 250, 251}, {150, 301, 250, 401} }; - - RECTANGLE_16 r1_r2_r3_r4[] = { + RECTANGLE_16 r1_r2_r3_r4[] = + { { 0, 101, 200, 151}, { 0, 151, 250, 201}, {150, 201, 250, 401} }; - region16_init(®ion); + /* * +=============================================================== * | @@ -422,11 +466,15 @@ static int test_r1_r2_r3_r4(void) { */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + if (!region16_union_rect(®ion, ®ion, &r2)) goto out; + if (!region16_union_rect(®ion, ®ion, &r3)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 4 || !compareRectangles(rects, r1_r2_r3, 4)) goto out; @@ -448,7 +496,9 @@ static int test_r1_r2_r3_r4(void) { */ if (!region16_union_rect(®ion, ®ion, &r4)) goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3_r4, 3)) goto out; @@ -468,19 +518,19 @@ static int test_from_weston(void) */ REGION16 region; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 0, 640, 32}; RECTANGLE_16 r2 = {236, 169, 268, 201}; RECTANGLE_16 r3 = {246, 258, 278, 290}; - - RECTANGLE_16 r1_r2_r3[] = { - { 0, 0, 640, 32}, - {236, 169, 268, 201}, - {246, 258, 278, 290} + RECTANGLE_16 r1_r2_r3[] = + { + { 0, 0, 640, 32}, + {236, 169, 268, 201}, + {246, 258, 278, 290} }; - region16_init(®ion); + /* * +=============================================================== * |+-------------------------------------------------------------+ @@ -498,12 +548,15 @@ static int test_from_weston(void) */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + if (!region16_union_rect(®ion, ®ion, &r2)) goto out; + if (!region16_union_rect(®ion, ®ion, &r3)) goto out; rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3, 3)) goto out; @@ -513,18 +566,18 @@ out: return retCode; } -static int test_r1_inter_r3(void) { +static int test_r1_inter_r3(void) +{ REGION16 region, intersection; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r3 = {150, 151, 250, 251}; - - RECTANGLE_16 r1_inter_r3[] = { + RECTANGLE_16 r1_inter_r3[] = + { {150, 151, 200, 201}, }; - region16_init(®ion); region16_init(&intersection); @@ -541,35 +594,37 @@ static int test_r1_inter_r3(void) { */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + if (!region16_intersects_rect(®ion, &r3)) goto out; if (!region16_intersect_rect(&intersection, ®ion, &r3)) goto out; + rects = region16_rects(&intersection, &nbRects); + if (!rects || nbRects != 1 || !compareRectangles(rects, r1_inter_r3, nbRects)) goto out; - retCode = 0; out: region16_uninit(®ion); return retCode; } -static int test_r1_r3_inter_r11(void) { +static int test_r1_r3_inter_r11(void) +{ REGION16 region, intersection; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r3 = {150, 151, 250, 251}; - RECTANGLE_16 r11 ={170, 151, 600, 301}; - - RECTANGLE_16 r1_r3_inter_r11[] = { + RECTANGLE_16 r11 = {170, 151, 600, 301}; + RECTANGLE_16 r1_r3_inter_r11[] = + { {170, 151, 250, 251}, }; - region16_init(®ion); region16_init(&intersection); @@ -595,6 +650,7 @@ static int test_r1_r3_inter_r11(void) { */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; + if (!region16_union_rect(®ion, ®ion, &r3)) goto out; @@ -603,7 +659,9 @@ static int test_r1_r3_inter_r11(void) { if (!region16_intersect_rect(&intersection, ®ion, &r11)) goto out; + rects = region16_rects(&intersection, &nbRects); + if (!rects || nbRects != 1 || !compareRectangles(rects, r1_r3_inter_r11, nbRects)) goto out; @@ -614,27 +672,28 @@ out: return retCode; } -static int test_norbert_case(void) { +static int test_norbert_case(void) +{ REGION16 region, intersection; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects, i; - - RECTANGLE_16 inRectangles[5] = { - {1680, 0, 1920, 242}, - { 294, 242, 971, 776}, - {1680, 242, 1920, 776}, - {1680, 776, 1920, 1036}, - { 2, 1040, 53, 1078} + RECTANGLE_16 inRectangles[5] = + { + {1680, 0, 1920, 242}, + { 294, 242, 971, 776}, + {1680, 242, 1920, 776}, + {1680, 776, 1920, 1036}, + { 2, 1040, 53, 1078} }; - - RECTANGLE_16 screenRect = { + RECTANGLE_16 screenRect = + { 0, 0, 1920, 1080 }; - RECTANGLE_16 expected_inter_extents = { + RECTANGLE_16 expected_inter_extents = + { 2, 0, 1920, 1078 }; - region16_init(®ion); region16_init(&intersection); @@ -670,16 +729,18 @@ static int test_norbert_case(void) { goto out; } - if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1) ) + if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1)) goto out; if (!region16_intersect_rect(&intersection, ®ion, &screenRect)) goto out; + rects = region16_rects(&intersection, &nbRects); + if (!rects || nbRects != 5 || !compareRectangles(rects, inRectangles, nbRects)) goto out; - if (!compareRectangles(region16_extents(&intersection), &expected_inter_extents, 1) ) + if (!compareRectangles(region16_extents(&intersection), &expected_inter_extents, 1)) goto out; retCode = 0; @@ -689,57 +750,66 @@ out: return retCode; } -static int test_norbert2_case(void) { +static int test_norbert2_case(void) +{ REGION16 region; int retCode = -1; - const RECTANGLE_16 *rects; + const RECTANGLE_16* rects; UINT32 nbRects = 0; RECTANGLE_16 rect1 = { 464, 696, 476, 709 }; RECTANGLE_16 rect2 = { 0, 0, 1024, 32 }; - region16_init(®ion); - if (!region16_union_rect(®ion, ®ion, &rect1)) { + if (!region16_union_rect(®ion, ®ion, &rect1)) + { fprintf(stderr, "%s: Error 1 - region16_union_rect failed\n", __FUNCTION__); goto out; } - if (!(rects = region16_rects(®ion, &nbRects))) { + if (!(rects = region16_rects(®ion, &nbRects))) + { fprintf(stderr, "%s: Error 2 - region16_rects failed\n", __FUNCTION__); goto out; } - if (nbRects != 1) { + if (nbRects != 1) + { fprintf(stderr, "%s: Error 3 - expected nbRects == 1 but got %"PRIu32"\n", __FUNCTION__, nbRects); goto out; } - if (!compareRectangles(&rects[0], &rect1, 1)) { + if (!compareRectangles(&rects[0], &rect1, 1)) + { fprintf(stderr, "%s: Error 4 - compare failed\n", __FUNCTION__); goto out; } - if (!region16_union_rect(®ion, ®ion, &rect2)) { + if (!region16_union_rect(®ion, ®ion, &rect2)) + { fprintf(stderr, "%s: Error 5 - region16_union_rect failed\n", __FUNCTION__); goto out; } - if (!(rects = region16_rects(®ion, &nbRects))) { + if (!(rects = region16_rects(®ion, &nbRects))) + { fprintf(stderr, "%s: Error 6 - region16_rects failed\n", __FUNCTION__); goto out; } - if (nbRects != 2) { + if (nbRects != 2) + { fprintf(stderr, "%s: Error 7 - expected nbRects == 2 but got %"PRIu32"\n", __FUNCTION__, nbRects); goto out; } - if (!compareRectangles(&rects[0], &rect2, 1)) { + if (!compareRectangles(&rects[0], &rect2, 1)) + { fprintf(stderr, "%s: Error 8 - compare failed\n", __FUNCTION__); goto out; } - if (!compareRectangles(&rects[1], &rect1, 1)) { + if (!compareRectangles(&rects[1], &rect1, 1)) + { fprintf(stderr, "%s: Error 9 - compare failed\n", __FUNCTION__); goto out; } @@ -750,27 +820,29 @@ out: return retCode; } -static int test_empty_rectangle(void) { +static int test_empty_rectangle(void) +{ REGION16 region, intersection; int retCode = -1; int i; - - RECTANGLE_16 emptyRectangles[3] = { + RECTANGLE_16 emptyRectangles[3] = + { { 0, 0, 0, 0}, { 10, 10, 10, 11}, { 10, 10, 11, 10} }; - - RECTANGLE_16 firstRect = { + RECTANGLE_16 firstRect = + { 0, 0, 100, 100 }; - RECTANGLE_16 anotherRect = { + RECTANGLE_16 anotherRect = + { 100, 100, 200, 200 }; - RECTANGLE_16 expected_inter_extents = { + RECTANGLE_16 expected_inter_extents = + { 0, 0, 0, 0 }; - region16_init(®ion); region16_init(&intersection); @@ -792,7 +864,7 @@ static int test_empty_rectangle(void) { if (!region16_intersect_rect(®ion, ®ion, &anotherRect)) goto out; - if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1) ) + if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1)) goto out; if (!region16_is_empty(®ion)) @@ -809,12 +881,14 @@ out: } typedef int (*TestFunction)(void); -struct UnitaryTest { - const char *name; +struct UnitaryTest +{ + const char* name; TestFunction func; }; -static struct UnitaryTest tests[] = { +static struct UnitaryTest tests[] = +{ {"Basic trivial tests", test_basic}, {"R1+R3 and R3+R1", test_r1_r3}, {"R1+R5", test_r1_r5}, @@ -825,7 +899,7 @@ static struct UnitaryTest tests[] = { {"R1+R2+R3+R4", test_r1_r2_r3_r4}, {"data from weston", test_from_weston}, {"R1 & R3", test_r1_inter_r3}, - {"(R1+R3)&R11 (band merge)",test_r1_r3_inter_r11}, + {"(R1+R3)&R11 (band merge)", test_r1_r3_inter_r11}, {"norbert's case", test_norbert_case}, {"norbert's case 2", test_norbert2_case}, {"empty rectangle case", test_empty_rectangle}, @@ -843,6 +917,7 @@ int TestFreeRDPRegion(int argc, char* argv[]) testNb++; fprintf(stderr, "%d: %s\n", testNb, tests[i].name); retCode = tests[i].func(); + if (retCode < 0) break; } diff --git a/libfreerdp/codec/xcrush.c b/libfreerdp/codec/xcrush.c index 42ac4d6..ba453b3 100644 --- a/libfreerdp/codec/xcrush.c +++ b/libfreerdp/codec/xcrush.c @@ -3,6 +3,8 @@ * XCrush (RDP6.1) Bulk Data Compression * * Copyright 2014 Marc-Andre Moreau + * Copyright 2017 Armin Novak + * 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); } diff --git a/libfreerdp/codec/zgfx.c b/libfreerdp/codec/zgfx.c index e5c6c3c..d9e0a1b 100644 --- a/libfreerdp/codec/zgfx.c +++ b/libfreerdp/codec/zgfx.c @@ -3,6 +3,8 @@ * ZGFX (RDP8) Bulk Data Compression * * Copyright 2014 Marc-Andre Moreau + * Copyright 2017 Armin Novak + * 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); } diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 16d86c5..c3d50aa 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -4,6 +4,8 @@ * * Copyright 2011 Vic Lee * Copyright 2014 Norbert Federa + * Copyright 2017 Armin Novak + * 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; diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index be88079..5a4136b 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -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_OUT_CHANNEL_WAIT: - break; - - case VIRTUAL_CONNECTION_STATE_WAIT_A3W: - - 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; - } - - 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; - } + case VIRTUAL_CONNECTION_STATE_INITIAL: + break; - rpc_virtual_connection_transition_to_state(rpc, - rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_C2); - - status = 1; + case VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT: + break; - break; + case VIRTUAL_CONNECTION_STATE_WAIT_A3W: + rts = (rpcconn_rts_hdr_t*) Stream_Buffer(pdu->s); - case VIRTUAL_CONNECTION_STATE_WAIT_C2: + if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_A3_SIGNATURE, rts)) + { + WLog_ERR(TAG, "unexpected RTS PDU: Expected CONN/A3"); + return -1; + } - rts = (rpcconn_rts_hdr_t*) Stream_Buffer(pdu->s); + status = rts_recv_CONN_A3_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s)); - if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts)) - { - WLog_ERR(TAG, "unexpected RTS PDU: Expected CONN/C2"); - return -1; - } + if (status < 0) + { + WLog_ERR(TAG, "rts_recv_CONN_A3_pdu failure"); + return -1; + } - status = rts_recv_CONN_C2_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s)); + rpc_virtual_connection_transition_to_state(rpc, + rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_C2); + status = 1; + break; - if (status < 0) - { - WLog_ERR(TAG, "rts_recv_CONN_C2_pdu failure"); - return -1; - } + case VIRTUAL_CONNECTION_STATE_WAIT_C2: + rts = (rpcconn_rts_hdr_t*) Stream_Buffer(pdu->s); - rpc_virtual_connection_transition_to_state(rpc, - rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_OPENED); + if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts)) + { + WLog_ERR(TAG, "unexpected RTS PDU: Expected CONN/C2"); + return -1; + } - rpc_client_transition_to_state(rpc, RPC_CLIENT_STATE_ESTABLISHED); + status = rts_recv_CONN_C2_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s)); - if (rpc_send_bind_pdu(rpc) < 0) - { - WLog_ERR(TAG, "rpc_send_bind_pdu failure"); - return -1; - } + if (status < 0) + { + WLog_ERR(TAG, "rts_recv_CONN_C2_pdu failure"); + return -1; + } - rpc_client_transition_to_state(rpc, RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK); + rpc_virtual_connection_transition_to_state(rpc, + rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_OPENED); + rpc_client_transition_to_state(rpc, RPC_CLIENT_STATE_ESTABLISHED); - status = 1; + if (rpc_send_bind_pdu(rpc) < 0) + { + WLog_ERR(TAG, "rpc_send_bind_pdu failure"); + return -1; + } - break; + 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_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) diff --git a/libfreerdp/core/gateway/rts.c b/libfreerdp/core/gateway/rts.c index 263ca03..e38687c 100644 --- a/libfreerdp/core/gateway/rts.c +++ b/libfreerdp/core/gateway/rts.c @@ -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); diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 61696bf..1e24f28 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -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; } diff --git a/libfreerdp/core/gateway/tsg.h b/libfreerdp/core/gateway/tsg.h index 82561b4..f6ad341 100644 --- a/libfreerdp/core/gateway/tsg.h +++ b/libfreerdp/core/gateway/tsg.h @@ -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); diff --git a/libfreerdp/core/mcs.c b/libfreerdp/core/mcs.c index 266c689..6fdd5f0 100644 --- a/libfreerdp/core/mcs.c +++ b/libfreerdp/core/mcs.c @@ -5,6 +5,8 @@ * Copyright 2011 Marc-Andre Moreau * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2017 Armin Novak + * 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; - MCSPDU = DomainMCSPDU_AttachUserConfirm; + 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; diff --git a/libfreerdp/core/message.c b/libfreerdp/core/message.c index 7b1d2ee..c791fde 100644 --- a/libfreerdp/core/message.c +++ b/libfreerdp/core/message.c @@ -3,6 +3,8 @@ * Asynchronous Message Queue * * Copyright 2012 Marc-Andre Moreau + * Copyright 2017 Armin Novak + * 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. @@ -41,64 +43,86 @@ static BOOL update_message_BeginPaint(rdpContext* context) { + if (!context || !context->update) + return FALSE; + return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, BeginPaint), NULL, NULL); + MakeMessageId(Update, BeginPaint), NULL, NULL); } static BOOL update_message_EndPaint(rdpContext* context) { + if (!context || !context->update) + return FALSE; + return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, EndPaint), NULL, NULL); + MakeMessageId(Update, EndPaint), NULL, NULL); } static BOOL update_message_SetBounds(rdpContext* context, - const rdpBounds* bounds) + const rdpBounds* bounds) { rdpBounds* wParam = NULL; + if (!context || !context->update) + return FALSE; + if (bounds) { wParam = (rdpBounds*) malloc(sizeof(rdpBounds)); + if (!wParam) return FALSE; + CopyMemory(wParam, bounds, sizeof(rdpBounds)); } return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, SetBounds), (void*) wParam, NULL); + MakeMessageId(Update, SetBounds), (void*) wParam, NULL); } static BOOL update_message_Synchronize(rdpContext* context) { + if (!context || !context->update) + return FALSE; + return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, Synchronize), NULL, NULL); + MakeMessageId(Update, Synchronize), NULL, NULL); } static BOOL update_message_DesktopResize(rdpContext* context) { + if (!context || !context->update) + return FALSE; + return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, DesktopResize), NULL, NULL); + MakeMessageId(Update, DesktopResize), NULL, NULL); } static BOOL update_message_BitmapUpdate(rdpContext* context, - const BITMAP_UPDATE* bitmap) + const BITMAP_UPDATE* bitmap) { UINT32 index; BITMAP_UPDATE* wParam; + if (!context || !context->update || !bitmap) + return FALSE; + wParam = (BITMAP_UPDATE*) malloc(sizeof(BITMAP_UPDATE)); + if (!wParam) return FALSE; wParam->number = bitmap->number; wParam->count = wParam->number; - wParam->rectangles = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * wParam->number); + if (!wParam->rectangles) { free(wParam); return FALSE; } + CopyMemory(wParam->rectangles, bitmap->rectangles, sizeof(BITMAP_DATA) * wParam->number); for (index = 0; index < wParam->number; index++) @@ -107,148 +131,185 @@ static BOOL update_message_BitmapUpdate(rdpContext* context, StreamPool_AddRef(context->rdp->transport->ReceivePool, bitmap->rectangles[index].bitmapDataStream); #else wParam->rectangles[index].bitmapDataStream = (BYTE*) malloc(wParam->rectangles[index].bitmapLength); + if (!wParam->rectangles[index].bitmapDataStream) { - while(index) + while (index) free(wParam->rectangles[--index].bitmapDataStream); free(wParam->rectangles); free(wParam); return FALSE; } + CopyMemory(wParam->rectangles[index].bitmapDataStream, bitmap->rectangles[index].bitmapDataStream, - wParam->rectangles[index].bitmapLength); + wParam->rectangles[index].bitmapLength); #endif } return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, BitmapUpdate), (void*) wParam, NULL); + MakeMessageId(Update, BitmapUpdate), (void*) wParam, NULL); } static BOOL update_message_Palette(rdpContext* context, - const PALETTE_UPDATE* palette) + const PALETTE_UPDATE* palette) { PALETTE_UPDATE* wParam; + if (!context || !context->update || !palette) + return FALSE; + wParam = (PALETTE_UPDATE*) malloc(sizeof(PALETTE_UPDATE)); + if (!wParam) return FALSE; - CopyMemory(wParam, palette, sizeof(PALETTE_UPDATE)); + CopyMemory(wParam, palette, sizeof(PALETTE_UPDATE)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, Palette), (void*) wParam, NULL); + MakeMessageId(Update, Palette), (void*) wParam, NULL); } static BOOL update_message_PlaySound(rdpContext* context, - const PLAY_SOUND_UPDATE* playSound) + const PLAY_SOUND_UPDATE* playSound) { PLAY_SOUND_UPDATE* wParam; + if (!context || !context->update || !playSound) + return FALSE; + wParam = (PLAY_SOUND_UPDATE*) malloc(sizeof(PLAY_SOUND_UPDATE)); + if (!wParam) return FALSE; - CopyMemory(wParam, playSound, sizeof(PLAY_SOUND_UPDATE)); + CopyMemory(wParam, playSound, sizeof(PLAY_SOUND_UPDATE)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, PlaySound), (void*) wParam, NULL); + MakeMessageId(Update, PlaySound), (void*) wParam, NULL); } static BOOL update_message_SetKeyboardIndicators(rdpContext* context, UINT16 led_flags) { + if (!context || !context->update) + return FALSE; + return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, SetKeyboardIndicators), (void*)(size_t)led_flags, NULL); + MakeMessageId(Update, SetKeyboardIndicators), (void*)(size_t)led_flags, NULL); } static BOOL update_message_RefreshRect(rdpContext* context, BYTE count, - const RECTANGLE_16* areas) + const RECTANGLE_16* areas) { RECTANGLE_16* lParam; + if (!context || !context->update || !areas) + return FALSE; + lParam = (RECTANGLE_16*) malloc(sizeof(RECTANGLE_16) * count); + if (!lParam) return FALSE; - CopyMemory(lParam, areas, sizeof(RECTANGLE_16) * count); + CopyMemory(lParam, areas, sizeof(RECTANGLE_16) * count); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, RefreshRect), (void*) (size_t) count, (void*) lParam); + MakeMessageId(Update, RefreshRect), (void*)(size_t) count, (void*) lParam); } static BOOL update_message_SuppressOutput(rdpContext* context, BYTE allow, - const RECTANGLE_16* area) + const RECTANGLE_16* area) { RECTANGLE_16* lParam = NULL; + if (!context || !context->update) + return FALSE; + if (area) { lParam = (RECTANGLE_16*) malloc(sizeof(RECTANGLE_16)); + if (!lParam) return FALSE; + CopyMemory(lParam, area, sizeof(RECTANGLE_16)); } return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, SuppressOutput), (void*) (size_t) allow, (void*) lParam); + MakeMessageId(Update, SuppressOutput), (void*)(size_t) allow, (void*) lParam); } static BOOL update_message_SurfaceCommand(rdpContext* context, wStream* s) { wStream* wParam; + if (!context || !context->update || !s) + return FALSE; + wParam = Stream_New(NULL, Stream_GetRemainingLength(s)); + if (!wParam) return FALSE; Stream_Copy(s, wParam, Stream_GetRemainingLength(s)); Stream_SetPosition(wParam, 0); - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, SurfaceCommand), (void*) wParam, NULL); + MakeMessageId(Update, SurfaceCommand), (void*) wParam, NULL); } static BOOL update_message_SurfaceBits(rdpContext* context, - const SURFACE_BITS_COMMAND* surfaceBitsCommand) + const SURFACE_BITS_COMMAND* surfaceBitsCommand) { SURFACE_BITS_COMMAND* wParam; + if (!context || !context->update || !surfaceBitsCommand) + return FALSE; + wParam = (SURFACE_BITS_COMMAND*) malloc(sizeof(SURFACE_BITS_COMMAND)); + if (!wParam) return FALSE; - CopyMemory(wParam, surfaceBitsCommand, sizeof(SURFACE_BITS_COMMAND)); + CopyMemory(wParam, surfaceBitsCommand, sizeof(SURFACE_BITS_COMMAND)); #ifdef WITH_STREAM_POOL StreamPool_AddRef(context->rdp->transport->ReceivePool, surfaceBitsCommand->bitmapData); #else wParam->bitmapData = (BYTE*) malloc(wParam->bitmapDataLength); + if (!wParam->bitmapData) { free(wParam); return FALSE; } + CopyMemory(wParam->bitmapData, surfaceBitsCommand->bitmapData, wParam->bitmapDataLength); #endif - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, SurfaceBits), (void*) wParam, NULL); + MakeMessageId(Update, SurfaceBits), (void*) wParam, NULL); } static BOOL update_message_SurfaceFrameMarker(rdpContext* context, - const SURFACE_FRAME_MARKER* surfaceFrameMarker) + const SURFACE_FRAME_MARKER* surfaceFrameMarker) { SURFACE_FRAME_MARKER* wParam; + if (!context || !context->update || !surfaceFrameMarker) + return FALSE; + wParam = (SURFACE_FRAME_MARKER*) malloc(sizeof(SURFACE_FRAME_MARKER)); + if (!wParam) return FALSE; - CopyMemory(wParam, surfaceFrameMarker, sizeof(SURFACE_FRAME_MARKER)); + CopyMemory(wParam, surfaceFrameMarker, sizeof(SURFACE_FRAME_MARKER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, SurfaceFrameMarker), (void*) wParam, NULL); + MakeMessageId(Update, SurfaceFrameMarker), (void*) wParam, NULL); } static BOOL update_message_SurfaceFrameAcknowledge(rdpContext* context, UINT32 frameId) { + if (!context || !context->update) + return FALSE; + return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, SurfaceFrameAcknowledge), (void*) (size_t) frameId, NULL); + MakeMessageId(Update, SurfaceFrameAcknowledge), (void*)(size_t) frameId, NULL); } /* Primary Update */ @@ -257,275 +318,346 @@ static BOOL update_message_DstBlt(rdpContext* context, const DSTBLT_ORDER* dstBl { DSTBLT_ORDER* wParam; + if (!context || !context->update || !dstBlt) + return FALSE; + wParam = (DSTBLT_ORDER*) malloc(sizeof(DSTBLT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, dstBlt, sizeof(DSTBLT_ORDER)); + CopyMemory(wParam, dstBlt, sizeof(DSTBLT_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, DstBlt), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, DstBlt), (void*) wParam, NULL); } static BOOL update_message_PatBlt(rdpContext* context, PATBLT_ORDER* patBlt) { PATBLT_ORDER* wParam; + if (!context || !context->update || !patBlt) + return FALSE; + wParam = (PATBLT_ORDER*) malloc(sizeof(PATBLT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, patBlt, sizeof(PATBLT_ORDER)); + CopyMemory(wParam, patBlt, sizeof(PATBLT_ORDER)); wParam->brush.data = (BYTE*) wParam->brush.p8x8; - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, PatBlt), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, PatBlt), (void*) wParam, NULL); } static BOOL update_message_ScrBlt(rdpContext* context, - const SCRBLT_ORDER* scrBlt) + const SCRBLT_ORDER* scrBlt) { SCRBLT_ORDER* wParam; + if (!context || !context->update || !scrBlt) + return FALSE; + wParam = (SCRBLT_ORDER*) malloc(sizeof(SCRBLT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, scrBlt, sizeof(SCRBLT_ORDER)); + CopyMemory(wParam, scrBlt, sizeof(SCRBLT_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, ScrBlt), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, ScrBlt), (void*) wParam, NULL); } static BOOL update_message_OpaqueRect( - rdpContext* context, - const OPAQUE_RECT_ORDER* opaqueRect) + rdpContext* context, + const OPAQUE_RECT_ORDER* opaqueRect) { OPAQUE_RECT_ORDER* wParam; + if (!context || !context->update || !opaqueRect) + return FALSE; + wParam = (OPAQUE_RECT_ORDER*) malloc(sizeof(OPAQUE_RECT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, opaqueRect, sizeof(OPAQUE_RECT_ORDER)); + CopyMemory(wParam, opaqueRect, sizeof(OPAQUE_RECT_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, OpaqueRect), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, OpaqueRect), (void*) wParam, NULL); } static BOOL update_message_DrawNineGrid( - rdpContext* context, - const DRAW_NINE_GRID_ORDER* drawNineGrid) + rdpContext* context, + const DRAW_NINE_GRID_ORDER* drawNineGrid) { DRAW_NINE_GRID_ORDER* wParam; + if (!context || !context->update || !drawNineGrid) + return FALSE; + wParam = (DRAW_NINE_GRID_ORDER*) malloc(sizeof(DRAW_NINE_GRID_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, drawNineGrid, sizeof(DRAW_NINE_GRID_ORDER)); + CopyMemory(wParam, drawNineGrid, sizeof(DRAW_NINE_GRID_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, DrawNineGrid), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, DrawNineGrid), (void*) wParam, NULL); } static BOOL update_message_MultiDstBlt(rdpContext* context, - const MULTI_DSTBLT_ORDER* multiDstBlt) + const MULTI_DSTBLT_ORDER* multiDstBlt) { MULTI_DSTBLT_ORDER* wParam; + if (!context || !context->update || !multiDstBlt) + return FALSE; + wParam = (MULTI_DSTBLT_ORDER*) malloc(sizeof(MULTI_DSTBLT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, multiDstBlt, sizeof(MULTI_DSTBLT_ORDER)); + CopyMemory(wParam, multiDstBlt, sizeof(MULTI_DSTBLT_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, MultiDstBlt), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, MultiDstBlt), (void*) wParam, NULL); } static BOOL update_message_MultiPatBlt(rdpContext* context, - const MULTI_PATBLT_ORDER* multiPatBlt) + const MULTI_PATBLT_ORDER* multiPatBlt) { MULTI_PATBLT_ORDER* wParam; + if (!context || !context->update || !multiPatBlt) + return FALSE; + wParam = (MULTI_PATBLT_ORDER*) malloc(sizeof(MULTI_PATBLT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, multiPatBlt, sizeof(MULTI_PATBLT_ORDER)); + CopyMemory(wParam, multiPatBlt, sizeof(MULTI_PATBLT_ORDER)); wParam->brush.data = (BYTE*) wParam->brush.p8x8; - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, MultiPatBlt), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, MultiPatBlt), (void*) wParam, NULL); } static BOOL update_message_MultiScrBlt(rdpContext* context, - const MULTI_SCRBLT_ORDER* multiScrBlt) + const MULTI_SCRBLT_ORDER* multiScrBlt) { MULTI_SCRBLT_ORDER* wParam; + if (!context || !context->update || !multiScrBlt) + return FALSE; + wParam = (MULTI_SCRBLT_ORDER*) malloc(sizeof(MULTI_SCRBLT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, multiScrBlt, sizeof(MULTI_SCRBLT_ORDER)); + CopyMemory(wParam, multiScrBlt, sizeof(MULTI_SCRBLT_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, MultiScrBlt), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, MultiScrBlt), (void*) wParam, NULL); } static BOOL update_message_MultiOpaqueRect( - rdpContext* context, - const MULTI_OPAQUE_RECT_ORDER* multiOpaqueRect) + rdpContext* context, + const MULTI_OPAQUE_RECT_ORDER* multiOpaqueRect) { MULTI_OPAQUE_RECT_ORDER* wParam; + if (!context || !context->update || !multiOpaqueRect) + return FALSE; + wParam = (MULTI_OPAQUE_RECT_ORDER*) malloc(sizeof(MULTI_OPAQUE_RECT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, multiOpaqueRect, sizeof(MULTI_OPAQUE_RECT_ORDER)); + CopyMemory(wParam, multiOpaqueRect, sizeof(MULTI_OPAQUE_RECT_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, MultiOpaqueRect), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, MultiOpaqueRect), (void*) wParam, NULL); } static BOOL update_message_MultiDrawNineGrid(rdpContext* context, - const MULTI_DRAW_NINE_GRID_ORDER* multiDrawNineGrid) + const MULTI_DRAW_NINE_GRID_ORDER* multiDrawNineGrid) { MULTI_DRAW_NINE_GRID_ORDER* wParam; + if (!context || !context->update || !multiDrawNineGrid) + return FALSE; + wParam = (MULTI_DRAW_NINE_GRID_ORDER*) malloc(sizeof(MULTI_DRAW_NINE_GRID_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, multiDrawNineGrid, sizeof(MULTI_DRAW_NINE_GRID_ORDER)); + CopyMemory(wParam, multiDrawNineGrid, sizeof(MULTI_DRAW_NINE_GRID_ORDER)); /* TODO: complete copy */ - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, MultiDrawNineGrid), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, MultiDrawNineGrid), (void*) wParam, NULL); } static BOOL update_message_LineTo(rdpContext* context, - const LINE_TO_ORDER* lineTo) + const LINE_TO_ORDER* lineTo) { LINE_TO_ORDER* wParam; + if (!context || !context->update || !lineTo) + return FALSE; + wParam = (LINE_TO_ORDER*) malloc(sizeof(LINE_TO_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, lineTo, sizeof(LINE_TO_ORDER)); + CopyMemory(wParam, lineTo, sizeof(LINE_TO_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, LineTo), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, LineTo), (void*) wParam, NULL); } static BOOL update_message_Polyline(rdpContext* context, - const POLYLINE_ORDER* polyline) + const POLYLINE_ORDER* polyline) { POLYLINE_ORDER* wParam; + if (!context || !context->update || !polyline) + return FALSE; + wParam = (POLYLINE_ORDER*) malloc(sizeof(POLYLINE_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, polyline, sizeof(POLYLINE_ORDER)); + CopyMemory(wParam, polyline, sizeof(POLYLINE_ORDER)); wParam->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * wParam->numDeltaEntries); + if (!wParam->points) { free(wParam); return FALSE; } - CopyMemory(wParam->points, polyline->points, sizeof(DELTA_POINT) * wParam->numDeltaEntries); + CopyMemory(wParam->points, polyline->points, sizeof(DELTA_POINT) * wParam->numDeltaEntries); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, Polyline), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, Polyline), (void*) wParam, NULL); } static BOOL update_message_MemBlt(rdpContext* context, MEMBLT_ORDER* memBlt) { MEMBLT_ORDER* wParam; + if (!context || !context->update || !memBlt) + return FALSE; + wParam = (MEMBLT_ORDER*) malloc(sizeof(MEMBLT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, memBlt, sizeof(MEMBLT_ORDER)); + CopyMemory(wParam, memBlt, sizeof(MEMBLT_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, MemBlt), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, MemBlt), (void*) wParam, NULL); } static BOOL update_message_Mem3Blt(rdpContext* context, MEM3BLT_ORDER* mem3Blt) { MEM3BLT_ORDER* wParam; + if (!context || !context->update || !mem3Blt) + return FALSE; + wParam = (MEM3BLT_ORDER*) malloc(sizeof(MEM3BLT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, mem3Blt, sizeof(MEM3BLT_ORDER)); + CopyMemory(wParam, mem3Blt, sizeof(MEM3BLT_ORDER)); wParam->brush.data = (BYTE*) wParam->brush.p8x8; - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, Mem3Blt), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, Mem3Blt), (void*) wParam, NULL); } static BOOL update_message_SaveBitmap(rdpContext* context, - const SAVE_BITMAP_ORDER* saveBitmap) + const SAVE_BITMAP_ORDER* saveBitmap) { SAVE_BITMAP_ORDER* wParam; + if (!context || !context->update || !saveBitmap) + return FALSE; + wParam = (SAVE_BITMAP_ORDER*) malloc(sizeof(SAVE_BITMAP_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, saveBitmap, sizeof(SAVE_BITMAP_ORDER)); + CopyMemory(wParam, saveBitmap, sizeof(SAVE_BITMAP_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, SaveBitmap), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, SaveBitmap), (void*) wParam, NULL); } static BOOL update_message_GlyphIndex(rdpContext* context, - GLYPH_INDEX_ORDER* glyphIndex) + GLYPH_INDEX_ORDER* glyphIndex) { GLYPH_INDEX_ORDER* wParam; + if (!context || !context->update || !glyphIndex) + return FALSE; + wParam = (GLYPH_INDEX_ORDER*) malloc(sizeof(GLYPH_INDEX_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, glyphIndex, sizeof(GLYPH_INDEX_ORDER)); + CopyMemory(wParam, glyphIndex, sizeof(GLYPH_INDEX_ORDER)); wParam->brush.data = (BYTE*) wParam->brush.p8x8; - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, GlyphIndex), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, GlyphIndex), (void*) wParam, NULL); } static BOOL update_message_FastIndex(rdpContext* context, - const FAST_INDEX_ORDER* fastIndex) + const FAST_INDEX_ORDER* fastIndex) { FAST_INDEX_ORDER* wParam; + if (!context || !context->update || !fastIndex) + return FALSE; + wParam = (FAST_INDEX_ORDER*) malloc(sizeof(FAST_INDEX_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, fastIndex, sizeof(FAST_INDEX_ORDER)); + CopyMemory(wParam, fastIndex, sizeof(FAST_INDEX_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, FastIndex), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, FastIndex), (void*) wParam, NULL); } static BOOL update_message_FastGlyph(rdpContext* context, - const FAST_GLYPH_ORDER* fastGlyph) + const FAST_GLYPH_ORDER* fastGlyph) { FAST_GLYPH_ORDER* wParam; + if (!context || !context->update || !fastGlyph) + return FALSE; + wParam = (FAST_GLYPH_ORDER*) malloc(sizeof(FAST_GLYPH_ORDER)); + if (!wParam) return FALSE; + CopyMemory(wParam, fastGlyph, sizeof(FAST_GLYPH_ORDER)); if (wParam->cbData > 1) { wParam->glyphData.aj = (BYTE*) malloc(fastGlyph->glyphData.cb); + if (!wParam->glyphData.aj) { free(wParam); return FALSE; } + CopyMemory(wParam->glyphData.aj, fastGlyph->glyphData.aj, fastGlyph->glyphData.cb); } else @@ -534,511 +666,628 @@ static BOOL update_message_FastGlyph(rdpContext* context, } return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, FastGlyph), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, FastGlyph), (void*) wParam, NULL); } static BOOL update_message_PolygonSC(rdpContext* context, - const POLYGON_SC_ORDER* polygonSC) + const POLYGON_SC_ORDER* polygonSC) { POLYGON_SC_ORDER* wParam; + if (!context || !context->update || !polygonSC) + return FALSE; + wParam = (POLYGON_SC_ORDER*) malloc(sizeof(POLYGON_SC_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, polygonSC, sizeof(POLYGON_SC_ORDER)); + CopyMemory(wParam, polygonSC, sizeof(POLYGON_SC_ORDER)); wParam->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * wParam->numPoints); + if (!wParam->points) { free(wParam); return FALSE; } - CopyMemory(wParam->points, polygonSC, sizeof(DELTA_POINT) * wParam->numPoints); + CopyMemory(wParam->points, polygonSC, sizeof(DELTA_POINT) * wParam->numPoints); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, PolygonSC), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, PolygonSC), (void*) wParam, NULL); } static BOOL update_message_PolygonCB(rdpContext* context, POLYGON_CB_ORDER* polygonCB) { POLYGON_CB_ORDER* wParam; + if (!context || !context->update || !polygonCB) + return FALSE; + wParam = (POLYGON_CB_ORDER*) malloc(sizeof(POLYGON_CB_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, polygonCB, sizeof(POLYGON_CB_ORDER)); + CopyMemory(wParam, polygonCB, sizeof(POLYGON_CB_ORDER)); wParam->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * wParam->numPoints); + if (!wParam->points) { free(wParam); return FALSE; } - CopyMemory(wParam->points, polygonCB, sizeof(DELTA_POINT) * wParam->numPoints); + CopyMemory(wParam->points, polygonCB, sizeof(DELTA_POINT) * wParam->numPoints); wParam->brush.data = (BYTE*) wParam->brush.p8x8; - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, PolygonCB), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, PolygonCB), (void*) wParam, NULL); } static BOOL update_message_EllipseSC(rdpContext* context, - const ELLIPSE_SC_ORDER* ellipseSC) + const ELLIPSE_SC_ORDER* ellipseSC) { ELLIPSE_SC_ORDER* wParam; + if (!context || !context->update || !ellipseSC) + return FALSE; + wParam = (ELLIPSE_SC_ORDER*) malloc(sizeof(ELLIPSE_SC_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, ellipseSC, sizeof(ELLIPSE_SC_ORDER)); + CopyMemory(wParam, ellipseSC, sizeof(ELLIPSE_SC_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, EllipseSC), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, EllipseSC), (void*) wParam, NULL); } static BOOL update_message_EllipseCB(rdpContext* context, - const ELLIPSE_CB_ORDER* ellipseCB) + const ELLIPSE_CB_ORDER* ellipseCB) { ELLIPSE_CB_ORDER* wParam; + if (!context || !context->update || !ellipseCB) + return FALSE; + wParam = (ELLIPSE_CB_ORDER*) malloc(sizeof(ELLIPSE_CB_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, ellipseCB, sizeof(ELLIPSE_CB_ORDER)); + CopyMemory(wParam, ellipseCB, sizeof(ELLIPSE_CB_ORDER)); wParam->brush.data = (BYTE*) wParam->brush.p8x8; - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PrimaryUpdate, EllipseCB), (void*) wParam, NULL); + MakeMessageId(PrimaryUpdate, EllipseCB), (void*) wParam, NULL); } /* Secondary Update */ static BOOL update_message_CacheBitmap(rdpContext* context, - const CACHE_BITMAP_ORDER* cacheBitmapOrder) + const CACHE_BITMAP_ORDER* cacheBitmapOrder) { CACHE_BITMAP_ORDER* wParam; + if (!context || !context->update || !cacheBitmapOrder) + return FALSE; + wParam = (CACHE_BITMAP_ORDER*) malloc(sizeof(CACHE_BITMAP_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, cacheBitmapOrder, sizeof(CACHE_BITMAP_ORDER)); + CopyMemory(wParam, cacheBitmapOrder, sizeof(CACHE_BITMAP_ORDER)); wParam->bitmapDataStream = (BYTE*) malloc(wParam->bitmapLength); + if (!wParam->bitmapDataStream) { free(wParam); return FALSE; } - CopyMemory(wParam->bitmapDataStream, cacheBitmapOrder, wParam->bitmapLength); + CopyMemory(wParam->bitmapDataStream, cacheBitmapOrder, wParam->bitmapLength); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(SecondaryUpdate, CacheBitmap), (void*) wParam, NULL); + MakeMessageId(SecondaryUpdate, CacheBitmap), (void*) wParam, NULL); } -static BOOL update_message_CacheBitmapV2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cacheBitmapV2Order) +static BOOL update_message_CacheBitmapV2(rdpContext* context, + CACHE_BITMAP_V2_ORDER* cacheBitmapV2Order) { CACHE_BITMAP_V2_ORDER* wParam; + if (!context || !context->update || !cacheBitmapV2Order) + return FALSE; + wParam = (CACHE_BITMAP_V2_ORDER*) malloc(sizeof(CACHE_BITMAP_V2_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, cacheBitmapV2Order, sizeof(CACHE_BITMAP_V2_ORDER)); + CopyMemory(wParam, cacheBitmapV2Order, sizeof(CACHE_BITMAP_V2_ORDER)); wParam->bitmapDataStream = (BYTE*) malloc(wParam->bitmapLength); + if (!wParam->bitmapDataStream) { free(wParam); return FALSE; } - CopyMemory(wParam->bitmapDataStream, cacheBitmapV2Order->bitmapDataStream, wParam->bitmapLength); + CopyMemory(wParam->bitmapDataStream, cacheBitmapV2Order->bitmapDataStream, wParam->bitmapLength); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(SecondaryUpdate, CacheBitmapV2), (void*) wParam, NULL); + MakeMessageId(SecondaryUpdate, CacheBitmapV2), (void*) wParam, NULL); } -static BOOL update_message_CacheBitmapV3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cacheBitmapV3Order) +static BOOL update_message_CacheBitmapV3(rdpContext* context, + CACHE_BITMAP_V3_ORDER* cacheBitmapV3Order) { CACHE_BITMAP_V3_ORDER* wParam; + if (!context || !context->update || !cacheBitmapV3Order) + return FALSE; + wParam = (CACHE_BITMAP_V3_ORDER*) malloc(sizeof(CACHE_BITMAP_V3_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, cacheBitmapV3Order, sizeof(CACHE_BITMAP_V3_ORDER)); + CopyMemory(wParam, cacheBitmapV3Order, sizeof(CACHE_BITMAP_V3_ORDER)); wParam->bitmapData.data = (BYTE*) malloc(wParam->bitmapData.length); + if (!wParam->bitmapData.data) { free(wParam); return FALSE; } - CopyMemory(wParam->bitmapData.data, cacheBitmapV3Order->bitmapData.data, wParam->bitmapData.length); + CopyMemory(wParam->bitmapData.data, cacheBitmapV3Order->bitmapData.data, wParam->bitmapData.length); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(SecondaryUpdate, CacheBitmapV3), (void*) wParam, NULL); + MakeMessageId(SecondaryUpdate, CacheBitmapV3), (void*) wParam, NULL); } static BOOL update_message_CacheColorTable( - rdpContext* context, - const CACHE_COLOR_TABLE_ORDER* cacheColorTableOrder) + rdpContext* context, + const CACHE_COLOR_TABLE_ORDER* cacheColorTableOrder) { CACHE_COLOR_TABLE_ORDER* wParam; + if (!context || !context->update || !cacheColorTableOrder) + return FALSE; + wParam = (CACHE_COLOR_TABLE_ORDER*) malloc(sizeof(CACHE_COLOR_TABLE_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, cacheColorTableOrder, sizeof(CACHE_COLOR_TABLE_ORDER)); + CopyMemory(wParam, cacheColorTableOrder, sizeof(CACHE_COLOR_TABLE_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(SecondaryUpdate, CacheColorTable), (void*) wParam, NULL); + MakeMessageId(SecondaryUpdate, CacheColorTable), (void*) wParam, NULL); } static BOOL update_message_CacheGlyph( - rdpContext* context, - const CACHE_GLYPH_ORDER* cacheGlyphOrder) + rdpContext* context, + const CACHE_GLYPH_ORDER* cacheGlyphOrder) { CACHE_GLYPH_ORDER* wParam; + if (!context || !context->update || !cacheGlyphOrder) + return FALSE; + wParam = (CACHE_GLYPH_ORDER*) malloc(sizeof(CACHE_GLYPH_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, cacheGlyphOrder, sizeof(CACHE_GLYPH_ORDER)); + CopyMemory(wParam, cacheGlyphOrder, sizeof(CACHE_GLYPH_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(SecondaryUpdate, CacheGlyph), (void*) wParam, NULL); + MakeMessageId(SecondaryUpdate, CacheGlyph), (void*) wParam, NULL); } static BOOL update_message_CacheGlyphV2( - rdpContext* context, - const CACHE_GLYPH_V2_ORDER* cacheGlyphV2Order) + rdpContext* context, + const CACHE_GLYPH_V2_ORDER* cacheGlyphV2Order) { CACHE_GLYPH_V2_ORDER* wParam; + if (!context || !context->update || !cacheGlyphV2Order) + return FALSE; + wParam = (CACHE_GLYPH_V2_ORDER*) malloc(sizeof(CACHE_GLYPH_V2_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, cacheGlyphV2Order, sizeof(CACHE_GLYPH_V2_ORDER)); + CopyMemory(wParam, cacheGlyphV2Order, sizeof(CACHE_GLYPH_V2_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(SecondaryUpdate, CacheGlyphV2), (void*) wParam, NULL); + MakeMessageId(SecondaryUpdate, CacheGlyphV2), (void*) wParam, NULL); } static BOOL update_message_CacheBrush( - rdpContext* context, - const CACHE_BRUSH_ORDER* cacheBrushOrder) + rdpContext* context, + const CACHE_BRUSH_ORDER* cacheBrushOrder) { CACHE_BRUSH_ORDER* wParam; + if (!context || !context->update || !cacheBrushOrder) + return FALSE; + wParam = (CACHE_BRUSH_ORDER*) malloc(sizeof(CACHE_BRUSH_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, cacheBrushOrder, sizeof(CACHE_BRUSH_ORDER)); + CopyMemory(wParam, cacheBrushOrder, sizeof(CACHE_BRUSH_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(SecondaryUpdate, CacheBrush), (void*) wParam, NULL); + MakeMessageId(SecondaryUpdate, CacheBrush), (void*) wParam, NULL); } /* Alternate Secondary Update */ static BOOL update_message_CreateOffscreenBitmap( - rdpContext* context, - const CREATE_OFFSCREEN_BITMAP_ORDER* createOffscreenBitmap) + rdpContext* context, + const CREATE_OFFSCREEN_BITMAP_ORDER* createOffscreenBitmap) { CREATE_OFFSCREEN_BITMAP_ORDER* wParam; + if (!context || !context->update || !createOffscreenBitmap) + return FALSE; + wParam = (CREATE_OFFSCREEN_BITMAP_ORDER*) malloc(sizeof(CREATE_OFFSCREEN_BITMAP_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, createOffscreenBitmap, sizeof(CREATE_OFFSCREEN_BITMAP_ORDER)); + CopyMemory(wParam, createOffscreenBitmap, sizeof(CREATE_OFFSCREEN_BITMAP_ORDER)); wParam->deleteList.cIndices = createOffscreenBitmap->deleteList.cIndices; wParam->deleteList.sIndices = wParam->deleteList.cIndices; wParam->deleteList.indices = (UINT16*) malloc(sizeof(UINT16) * wParam->deleteList.cIndices); + if (!wParam->deleteList.indices) { free(wParam); return FALSE; } - CopyMemory(wParam->deleteList.indices, createOffscreenBitmap->deleteList.indices, wParam->deleteList.cIndices); + CopyMemory(wParam->deleteList.indices, createOffscreenBitmap->deleteList.indices, + wParam->deleteList.cIndices); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, CreateOffscreenBitmap), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, CreateOffscreenBitmap), (void*) wParam, NULL); } static BOOL update_message_SwitchSurface( - rdpContext* context, - const SWITCH_SURFACE_ORDER* switchSurface) + rdpContext* context, + const SWITCH_SURFACE_ORDER* switchSurface) { SWITCH_SURFACE_ORDER* wParam; + if (!context || !context->update || !switchSurface) + return FALSE; + wParam = (SWITCH_SURFACE_ORDER*) malloc(sizeof(SWITCH_SURFACE_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, switchSurface, sizeof(SWITCH_SURFACE_ORDER)); + CopyMemory(wParam, switchSurface, sizeof(SWITCH_SURFACE_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, SwitchSurface), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, SwitchSurface), (void*) wParam, NULL); } static BOOL update_message_CreateNineGridBitmap( - rdpContext* context, - const CREATE_NINE_GRID_BITMAP_ORDER* createNineGridBitmap) + rdpContext* context, + const CREATE_NINE_GRID_BITMAP_ORDER* createNineGridBitmap) { CREATE_NINE_GRID_BITMAP_ORDER* wParam; + if (!context || !context->update || !createNineGridBitmap) + return FALSE; + wParam = (CREATE_NINE_GRID_BITMAP_ORDER*) malloc(sizeof(CREATE_NINE_GRID_BITMAP_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, createNineGridBitmap, sizeof(CREATE_NINE_GRID_BITMAP_ORDER)); + CopyMemory(wParam, createNineGridBitmap, sizeof(CREATE_NINE_GRID_BITMAP_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, CreateNineGridBitmap), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, CreateNineGridBitmap), (void*) wParam, NULL); } static BOOL update_message_FrameMarker( - rdpContext* context, - const FRAME_MARKER_ORDER* frameMarker) + rdpContext* context, + const FRAME_MARKER_ORDER* frameMarker) { FRAME_MARKER_ORDER* wParam; + if (!context || !context->update || !frameMarker) + return FALSE; + wParam = (FRAME_MARKER_ORDER*) malloc(sizeof(FRAME_MARKER_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, frameMarker, sizeof(FRAME_MARKER_ORDER)); + CopyMemory(wParam, frameMarker, sizeof(FRAME_MARKER_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, FrameMarker), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, FrameMarker), (void*) wParam, NULL); } static BOOL update_message_StreamBitmapFirst( - rdpContext* context, - const STREAM_BITMAP_FIRST_ORDER* streamBitmapFirst) + rdpContext* context, + const STREAM_BITMAP_FIRST_ORDER* streamBitmapFirst) { STREAM_BITMAP_FIRST_ORDER* wParam; + if (!context || !context->update || !streamBitmapFirst) + return FALSE; + wParam = (STREAM_BITMAP_FIRST_ORDER*) malloc(sizeof(STREAM_BITMAP_FIRST_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, streamBitmapFirst, sizeof(STREAM_BITMAP_FIRST_ORDER)); + CopyMemory(wParam, streamBitmapFirst, sizeof(STREAM_BITMAP_FIRST_ORDER)); /* TODO: complete copy */ - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, StreamBitmapFirst), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, StreamBitmapFirst), (void*) wParam, NULL); } static BOOL update_message_StreamBitmapNext( - rdpContext* context, - const STREAM_BITMAP_NEXT_ORDER* streamBitmapNext) + rdpContext* context, + const STREAM_BITMAP_NEXT_ORDER* streamBitmapNext) { STREAM_BITMAP_NEXT_ORDER* wParam; + if (!context || !context->update || !streamBitmapNext) + return FALSE; + wParam = (STREAM_BITMAP_NEXT_ORDER*) malloc(sizeof(STREAM_BITMAP_NEXT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, streamBitmapNext, sizeof(STREAM_BITMAP_NEXT_ORDER)); + CopyMemory(wParam, streamBitmapNext, sizeof(STREAM_BITMAP_NEXT_ORDER)); /* TODO: complete copy */ - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, StreamBitmapNext), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, StreamBitmapNext), (void*) wParam, NULL); } static BOOL update_message_DrawGdiPlusFirst( - rdpContext* context, - const DRAW_GDIPLUS_FIRST_ORDER* drawGdiPlusFirst) + rdpContext* context, + const DRAW_GDIPLUS_FIRST_ORDER* drawGdiPlusFirst) { DRAW_GDIPLUS_FIRST_ORDER* wParam; + if (!context || !context->update || !drawGdiPlusFirst) + return FALSE; + wParam = (DRAW_GDIPLUS_FIRST_ORDER*) malloc(sizeof(DRAW_GDIPLUS_FIRST_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, drawGdiPlusFirst, sizeof(DRAW_GDIPLUS_FIRST_ORDER)); + CopyMemory(wParam, drawGdiPlusFirst, sizeof(DRAW_GDIPLUS_FIRST_ORDER)); /* TODO: complete copy */ - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, DrawGdiPlusFirst), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, DrawGdiPlusFirst), (void*) wParam, NULL); } static BOOL update_message_DrawGdiPlusNext( - rdpContext* context, - const DRAW_GDIPLUS_NEXT_ORDER* drawGdiPlusNext) + rdpContext* context, + const DRAW_GDIPLUS_NEXT_ORDER* drawGdiPlusNext) { DRAW_GDIPLUS_NEXT_ORDER* wParam; + if (!context || !context->update || !drawGdiPlusNext) + return FALSE; + wParam = (DRAW_GDIPLUS_NEXT_ORDER*) malloc(sizeof(DRAW_GDIPLUS_NEXT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, drawGdiPlusNext, sizeof(DRAW_GDIPLUS_NEXT_ORDER)); + CopyMemory(wParam, drawGdiPlusNext, sizeof(DRAW_GDIPLUS_NEXT_ORDER)); /* TODO: complete copy */ - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, DrawGdiPlusNext), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, DrawGdiPlusNext), (void*) wParam, NULL); } static BOOL update_message_DrawGdiPlusEnd( - rdpContext* context, - const DRAW_GDIPLUS_END_ORDER* drawGdiPlusEnd) + rdpContext* context, + const DRAW_GDIPLUS_END_ORDER* drawGdiPlusEnd) { DRAW_GDIPLUS_END_ORDER* wParam; + if (!context || !context->update || !drawGdiPlusEnd) + return FALSE; + wParam = (DRAW_GDIPLUS_END_ORDER*) malloc(sizeof(DRAW_GDIPLUS_END_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, drawGdiPlusEnd, sizeof(DRAW_GDIPLUS_END_ORDER)); + CopyMemory(wParam, drawGdiPlusEnd, sizeof(DRAW_GDIPLUS_END_ORDER)); /* TODO: complete copy */ - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, DrawGdiPlusEnd), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, DrawGdiPlusEnd), (void*) wParam, NULL); } static BOOL update_message_DrawGdiPlusCacheFirst( - rdpContext* context, - const DRAW_GDIPLUS_CACHE_FIRST_ORDER* drawGdiPlusCacheFirst) + rdpContext* context, + const DRAW_GDIPLUS_CACHE_FIRST_ORDER* drawGdiPlusCacheFirst) { DRAW_GDIPLUS_CACHE_FIRST_ORDER* wParam; + if (!context || !context->update || !drawGdiPlusCacheFirst) + return FALSE; + wParam = (DRAW_GDIPLUS_CACHE_FIRST_ORDER*) malloc(sizeof(DRAW_GDIPLUS_CACHE_FIRST_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, drawGdiPlusCacheFirst, sizeof(DRAW_GDIPLUS_CACHE_FIRST_ORDER)); + CopyMemory(wParam, drawGdiPlusCacheFirst, sizeof(DRAW_GDIPLUS_CACHE_FIRST_ORDER)); /* TODO: complete copy */ - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, DrawGdiPlusCacheFirst), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, DrawGdiPlusCacheFirst), (void*) wParam, NULL); } static BOOL update_message_DrawGdiPlusCacheNext( - rdpContext* context, - const DRAW_GDIPLUS_CACHE_NEXT_ORDER* drawGdiPlusCacheNext) + rdpContext* context, + const DRAW_GDIPLUS_CACHE_NEXT_ORDER* drawGdiPlusCacheNext) { DRAW_GDIPLUS_CACHE_NEXT_ORDER* wParam; + if (!context || !context->update || !drawGdiPlusCacheNext) + return FALSE; + wParam = (DRAW_GDIPLUS_CACHE_NEXT_ORDER*) malloc(sizeof(DRAW_GDIPLUS_CACHE_NEXT_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, drawGdiPlusCacheNext, sizeof(DRAW_GDIPLUS_CACHE_NEXT_ORDER)); + CopyMemory(wParam, drawGdiPlusCacheNext, sizeof(DRAW_GDIPLUS_CACHE_NEXT_ORDER)); /* TODO: complete copy */ - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, DrawGdiPlusCacheNext), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, DrawGdiPlusCacheNext), (void*) wParam, NULL); } static BOOL update_message_DrawGdiPlusCacheEnd( - rdpContext* context, - const DRAW_GDIPLUS_CACHE_END_ORDER* drawGdiPlusCacheEnd) + rdpContext* context, + const DRAW_GDIPLUS_CACHE_END_ORDER* drawGdiPlusCacheEnd) { DRAW_GDIPLUS_CACHE_END_ORDER* wParam; + if (!context || !context->update || !drawGdiPlusCacheEnd) + return FALSE; + wParam = (DRAW_GDIPLUS_CACHE_END_ORDER*) malloc(sizeof(DRAW_GDIPLUS_CACHE_END_ORDER)); + if (!wParam) return FALSE; - CopyMemory(wParam, drawGdiPlusCacheEnd, sizeof(DRAW_GDIPLUS_CACHE_END_ORDER)); + CopyMemory(wParam, drawGdiPlusCacheEnd, sizeof(DRAW_GDIPLUS_CACHE_END_ORDER)); /* TODO: complete copy */ - return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(AltSecUpdate, DrawGdiPlusCacheEnd), (void*) wParam, NULL); + MakeMessageId(AltSecUpdate, DrawGdiPlusCacheEnd), (void*) wParam, NULL); } /* Window Update */ -static BOOL update_message_WindowCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState) +static BOOL update_message_WindowCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, + WINDOW_STATE_ORDER* windowState) { WINDOW_ORDER_INFO* wParam; WINDOW_STATE_ORDER* lParam; + if (!context || !context->update || !windowState) + return FALSE; + wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO)); + if (!wParam) return FALSE; - CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); + CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); lParam = (WINDOW_STATE_ORDER*) malloc(sizeof(WINDOW_STATE_ORDER)); + if (!lParam) { free(wParam); return FALSE; } - CopyMemory(lParam, windowState, sizeof(WINDOW_STATE_ORDER)); + CopyMemory(lParam, windowState, sizeof(WINDOW_STATE_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(WindowUpdate, WindowCreate), (void*) wParam, (void*) lParam); + MakeMessageId(WindowUpdate, WindowCreate), (void*) wParam, (void*) lParam); } -static BOOL update_message_WindowUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState) +static BOOL update_message_WindowUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, + WINDOW_STATE_ORDER* windowState) { WINDOW_ORDER_INFO* wParam; WINDOW_STATE_ORDER* lParam; + if (!context || !context->update || !windowState) + return FALSE; + wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO)); + if (!wParam) return FALSE; - CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); + CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); lParam = (WINDOW_STATE_ORDER*) malloc(sizeof(WINDOW_STATE_ORDER)); + if (!lParam) { free(wParam); return FALSE; } - CopyMemory(lParam, windowState, sizeof(WINDOW_STATE_ORDER)); + CopyMemory(lParam, windowState, sizeof(WINDOW_STATE_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(WindowUpdate, WindowUpdate), (void*) wParam, (void*) lParam); + MakeMessageId(WindowUpdate, WindowUpdate), (void*) wParam, (void*) lParam); } -static BOOL update_message_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon) +static BOOL update_message_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, + WINDOW_ICON_ORDER* windowIcon) { WINDOW_ORDER_INFO* wParam; WINDOW_ICON_ORDER* lParam; + if (!context || !context->update || !windowIcon) + return FALSE; + wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO)); + if (!wParam) return FALSE; - CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); + CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); lParam = (WINDOW_ICON_ORDER*) calloc(1, sizeof(WINDOW_ICON_ORDER)); + if (!lParam) { free(wParam); return FALSE; } - CopyMemory(lParam, windowIcon, sizeof(WINDOW_ICON_ORDER)); + CopyMemory(lParam, windowIcon, sizeof(WINDOW_ICON_ORDER)); WLog_VRB(TAG, "update_message_WindowIcon"); if (windowIcon->iconInfo->cbBitsColor > 0) { lParam->iconInfo->bitsColor = (BYTE*) malloc(windowIcon->iconInfo->cbBitsColor); + if (!lParam->iconInfo->bitsColor) goto out_fail; - CopyMemory(lParam->iconInfo->bitsColor, windowIcon->iconInfo->bitsColor, windowIcon->iconInfo->cbBitsColor); + + CopyMemory(lParam->iconInfo->bitsColor, windowIcon->iconInfo->bitsColor, + windowIcon->iconInfo->cbBitsColor); } if (windowIcon->iconInfo->cbBitsMask > 0) { lParam->iconInfo->bitsMask = (BYTE*) malloc(windowIcon->iconInfo->cbBitsMask); + if (!lParam->iconInfo->bitsMask) goto out_fail; - CopyMemory(lParam->iconInfo->bitsMask, windowIcon->iconInfo->bitsMask, windowIcon->iconInfo->cbBitsMask); + + CopyMemory(lParam->iconInfo->bitsMask, windowIcon->iconInfo->bitsMask, + windowIcon->iconInfo->cbBitsMask); } if (windowIcon->iconInfo->cbColorTable > 0) { lParam->iconInfo->colorTable = (BYTE*) malloc(windowIcon->iconInfo->cbColorTable); + if (!lParam->iconInfo->colorTable) goto out_fail; - CopyMemory(lParam->iconInfo->colorTable, windowIcon->iconInfo->colorTable, windowIcon->iconInfo->cbColorTable); + + CopyMemory(lParam->iconInfo->colorTable, windowIcon->iconInfo->colorTable, + windowIcon->iconInfo->cbColorTable); } return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(WindowUpdate, WindowIcon), (void*) wParam, (void*) lParam); - + MakeMessageId(WindowUpdate, WindowIcon), (void*) wParam, (void*) lParam); out_fail: free(lParam->iconInfo->bitsColor); free(lParam->iconInfo->bitsMask); @@ -1046,119 +1295,150 @@ out_fail: free(lParam); free(wParam); return FALSE; - } -static BOOL update_message_WindowCachedIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* windowCachedIcon) +static BOOL update_message_WindowCachedIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, + WINDOW_CACHED_ICON_ORDER* windowCachedIcon) { WINDOW_ORDER_INFO* wParam; WINDOW_CACHED_ICON_ORDER* lParam; + if (!context || !context->update || !windowCachedIcon) + return FALSE; + wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO)); + if (!wParam) return FALSE; - CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); + CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); lParam = (WINDOW_CACHED_ICON_ORDER*) malloc(sizeof(WINDOW_CACHED_ICON_ORDER)); + if (!lParam) { free(wParam); return FALSE; } - CopyMemory(lParam, windowCachedIcon, sizeof(WINDOW_CACHED_ICON_ORDER)); + CopyMemory(lParam, windowCachedIcon, sizeof(WINDOW_CACHED_ICON_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(WindowUpdate, WindowCachedIcon), (void*) wParam, (void*) lParam); + MakeMessageId(WindowUpdate, WindowCachedIcon), (void*) wParam, (void*) lParam); } static BOOL update_message_WindowDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) { WINDOW_ORDER_INFO* wParam; + if (!context || !context->update || !orderInfo) + return FALSE; + wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO)); + if (!wParam) return FALSE; - CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); + CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(WindowUpdate, WindowDelete), (void*) wParam, NULL); + MakeMessageId(WindowUpdate, WindowDelete), (void*) wParam, NULL); } -static BOOL update_message_NotifyIconCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) +static BOOL update_message_NotifyIconCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, + NOTIFY_ICON_STATE_ORDER* notifyIconState) { WINDOW_ORDER_INFO* wParam; NOTIFY_ICON_STATE_ORDER* lParam; + if (!context || !context->update || !notifyIconState) + return FALSE; + wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO)); + if (!wParam) return FALSE; - CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); + CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); lParam = (NOTIFY_ICON_STATE_ORDER*) malloc(sizeof(NOTIFY_ICON_STATE_ORDER)); + if (!lParam) { free(wParam); return FALSE; } - CopyMemory(lParam, notifyIconState, sizeof(NOTIFY_ICON_STATE_ORDER)); + CopyMemory(lParam, notifyIconState, sizeof(NOTIFY_ICON_STATE_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(WindowUpdate, NotifyIconCreate), (void*) wParam, (void*) lParam); + MakeMessageId(WindowUpdate, NotifyIconCreate), (void*) wParam, (void*) lParam); } -static BOOL update_message_NotifyIconUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) +static BOOL update_message_NotifyIconUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, + NOTIFY_ICON_STATE_ORDER* notifyIconState) { WINDOW_ORDER_INFO* wParam; NOTIFY_ICON_STATE_ORDER* lParam; + if (!context || !context->update || !notifyIconState) + return FALSE; + wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO)); + if (!wParam) return FALSE; - CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); + CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); lParam = (NOTIFY_ICON_STATE_ORDER*) malloc(sizeof(NOTIFY_ICON_STATE_ORDER)); + if (!lParam) { free(wParam); return FALSE; } - CopyMemory(lParam, notifyIconState, sizeof(NOTIFY_ICON_STATE_ORDER)); + CopyMemory(lParam, notifyIconState, sizeof(NOTIFY_ICON_STATE_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(WindowUpdate, NotifyIconUpdate), (void*) wParam, (void*) lParam); + MakeMessageId(WindowUpdate, NotifyIconUpdate), (void*) wParam, (void*) lParam); } static BOOL update_message_NotifyIconDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) { WINDOW_ORDER_INFO* wParam; + if (!context || !context->update || !orderInfo) + return FALSE; + wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO)); + if (!wParam) return FALSE; - CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); + CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(WindowUpdate, NotifyIconDelete), (void*) wParam, NULL); + MakeMessageId(WindowUpdate, NotifyIconDelete), (void*) wParam, NULL); } -static BOOL update_message_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitoredDesktop) +static BOOL update_message_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, + MONITORED_DESKTOP_ORDER* monitoredDesktop) { WINDOW_ORDER_INFO* wParam; MONITORED_DESKTOP_ORDER* lParam; + if (!context || !context->update || !monitoredDesktop) + return FALSE; + wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO)); + if (!wParam) return FALSE; - CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); + CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); lParam = (MONITORED_DESKTOP_ORDER*) malloc(sizeof(MONITORED_DESKTOP_ORDER)); + if (!lParam) { free(wParam); return FALSE; } - CopyMemory(lParam, monitoredDesktop, sizeof(MONITORED_DESKTOP_ORDER)); + CopyMemory(lParam, monitoredDesktop, sizeof(MONITORED_DESKTOP_ORDER)); lParam->windowIds = NULL; if (lParam->numWindowIds) @@ -1168,83 +1448,102 @@ static BOOL update_message_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_IN } return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(WindowUpdate, MonitoredDesktop), (void*) wParam, (void*) lParam); + MakeMessageId(WindowUpdate, MonitoredDesktop), (void*) wParam, (void*) lParam); } static BOOL update_message_NonMonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) { WINDOW_ORDER_INFO* wParam; + if (!context || !context->update || !orderInfo) + return FALSE; + wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO)); + if (!wParam) return FALSE; - CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); + CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(WindowUpdate, NonMonitoredDesktop), (void*) wParam, NULL); + MakeMessageId(WindowUpdate, NonMonitoredDesktop), (void*) wParam, NULL); } /* Pointer Update */ static BOOL update_message_PointerPosition(rdpContext* context, - const POINTER_POSITION_UPDATE* pointerPosition) + const POINTER_POSITION_UPDATE* pointerPosition) { POINTER_POSITION_UPDATE* wParam; + if (!context || !context->update || !pointerPosition) + return FALSE; + wParam = (POINTER_POSITION_UPDATE*) malloc(sizeof(POINTER_POSITION_UPDATE)); + if (!wParam) return FALSE; - CopyMemory(wParam, pointerPosition, sizeof(POINTER_POSITION_UPDATE)); + CopyMemory(wParam, pointerPosition, sizeof(POINTER_POSITION_UPDATE)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PointerUpdate, PointerPosition), (void*) wParam, NULL); + MakeMessageId(PointerUpdate, PointerPosition), (void*) wParam, NULL); } static BOOL update_message_PointerSystem(rdpContext* context, - const POINTER_SYSTEM_UPDATE* pointerSystem) + const POINTER_SYSTEM_UPDATE* pointerSystem) { POINTER_SYSTEM_UPDATE* wParam; + if (!context || !context->update || !pointerSystem) + return FALSE; + wParam = (POINTER_SYSTEM_UPDATE*) malloc(sizeof(POINTER_SYSTEM_UPDATE)); + if (!wParam) return FALSE; - CopyMemory(wParam, pointerSystem, sizeof(POINTER_SYSTEM_UPDATE)); + CopyMemory(wParam, pointerSystem, sizeof(POINTER_SYSTEM_UPDATE)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PointerUpdate, PointerSystem), (void*) wParam, NULL); + MakeMessageId(PointerUpdate, PointerSystem), (void*) wParam, NULL); } static BOOL update_message_PointerColor(rdpContext* context, - const POINTER_COLOR_UPDATE* pointerColor) + const POINTER_COLOR_UPDATE* pointerColor) { POINTER_COLOR_UPDATE* wParam; + if (!context || !context->update || !pointerColor) + return FALSE; + wParam = (POINTER_COLOR_UPDATE*) malloc(sizeof(POINTER_COLOR_UPDATE)); + if (!wParam) return FALSE; - CopyMemory(wParam, pointerColor, sizeof(POINTER_COLOR_UPDATE)); + CopyMemory(wParam, pointerColor, sizeof(POINTER_COLOR_UPDATE)); wParam->andMaskData = wParam->xorMaskData = NULL; if (wParam->lengthAndMask) { wParam->andMaskData = (BYTE*) malloc(wParam->lengthAndMask); + if (!wParam->andMaskData) goto out_fail; + CopyMemory(wParam->andMaskData, pointerColor->andMaskData, wParam->lengthAndMask); } if (wParam->lengthXorMask) { wParam->xorMaskData = (BYTE*) malloc(wParam->lengthXorMask); + if (!wParam->xorMaskData) goto out_fail; + CopyMemory(wParam->xorMaskData, pointerColor->xorMaskData, wParam->lengthXorMask); } return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PointerUpdate, PointerColor), (void*) wParam, NULL); - + MakeMessageId(PointerUpdate, PointerColor), (void*) wParam, NULL); out_fail: free(wParam->andMaskData); free(wParam->xorMaskData); @@ -1253,36 +1552,45 @@ out_fail: } static BOOL update_message_PointerNew(rdpContext* context, - const POINTER_NEW_UPDATE* pointerNew) + const POINTER_NEW_UPDATE* pointerNew) { POINTER_NEW_UPDATE* wParam; + if (!context || !context->update || !pointerNew) + return FALSE; + wParam = (POINTER_NEW_UPDATE*) malloc(sizeof(POINTER_NEW_UPDATE)); + if (!wParam) return FALSE; - CopyMemory(wParam, pointerNew, sizeof(POINTER_NEW_UPDATE)); + CopyMemory(wParam, pointerNew, sizeof(POINTER_NEW_UPDATE)); wParam->colorPtrAttr.andMaskData = wParam->colorPtrAttr.xorMaskData = NULL; if (wParam->colorPtrAttr.lengthAndMask) { wParam->colorPtrAttr.andMaskData = (BYTE*) malloc(wParam->colorPtrAttr.lengthAndMask); + if (!wParam->colorPtrAttr.andMaskData) goto out_fail; - CopyMemory(wParam->colorPtrAttr.andMaskData, pointerNew->colorPtrAttr.andMaskData, wParam->colorPtrAttr.lengthAndMask); + + CopyMemory(wParam->colorPtrAttr.andMaskData, pointerNew->colorPtrAttr.andMaskData, + wParam->colorPtrAttr.lengthAndMask); } if (wParam->colorPtrAttr.lengthXorMask) { wParam->colorPtrAttr.xorMaskData = (BYTE*) malloc(wParam->colorPtrAttr.lengthXorMask); + if (!wParam->colorPtrAttr.xorMaskData) goto out_fail; - CopyMemory(wParam->colorPtrAttr.xorMaskData, pointerNew->colorPtrAttr.xorMaskData, wParam->colorPtrAttr.lengthXorMask); + + CopyMemory(wParam->colorPtrAttr.xorMaskData, pointerNew->colorPtrAttr.xorMaskData, + wParam->colorPtrAttr.lengthXorMask); } return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PointerUpdate, PointerNew), (void*) wParam, NULL); - + MakeMessageId(PointerUpdate, PointerNew), (void*) wParam, NULL); out_fail: free(wParam->colorPtrAttr.andMaskData); free(wParam->colorPtrAttr.xorMaskData); @@ -1291,17 +1599,21 @@ out_fail: } static BOOL update_message_PointerCached(rdpContext* context, - const POINTER_CACHED_UPDATE* pointerCached) + const POINTER_CACHED_UPDATE* pointerCached) { POINTER_CACHED_UPDATE* wParam; + if (!context || !context->update || !pointerCached) + return FALSE; + wParam = (POINTER_CACHED_UPDATE*) malloc(sizeof(POINTER_CACHED_UPDATE)); + if (!wParam) return FALSE; - CopyMemory(wParam, pointerCached, sizeof(POINTER_CACHED_UPDATE)); + CopyMemory(wParam, pointerCached, sizeof(POINTER_CACHED_UPDATE)); return MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(PointerUpdate, PointerCached), (void*) wParam, NULL); + MakeMessageId(PointerUpdate, PointerCached), (void*) wParam, NULL); } /* Message Queue */ @@ -1309,6 +1621,9 @@ static int update_message_free_update_class(wMessage* msg, int type) { int status = 0; + if (!msg) + return -1; + switch (type) { case Update_BeginPaint: @@ -1336,7 +1651,8 @@ static int update_message_free_update_class(wMessage* msg, int type) { #ifdef WITH_STREAM_POOL rdpContext* context = (rdpContext*) msg->context; - StreamPool_Release(context->rdp->transport->ReceivePool, wParam->rectangles[index].bitmapDataStream); + StreamPool_Release(context->rdp->transport->ReceivePool, + wParam->rectangles[index].bitmapDataStream); #else free(wParam->rectangles[index].bitmapDataStream); #endif @@ -1405,6 +1721,9 @@ static int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* { int status = 0; + if (!proxy || !msg) + return -1; + switch (type) { case Update_BeginPaint: @@ -1441,12 +1760,12 @@ static int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* case Update_RefreshRect: IFCALL(proxy->RefreshRect, msg->context, - (BYTE) (size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); + (BYTE)(size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); break; case Update_SuppressOutput: IFCALL(proxy->SuppressOutput, msg->context, - (BYTE) (size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); + (BYTE)(size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); break; case Update_SurfaceCommand: @@ -1462,11 +1781,11 @@ static int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* break; case Update_SurfaceFrameAcknowledge: - IFCALL(proxy->SurfaceFrameAcknowledge, msg->context, (UINT32) (size_t) msg->wParam); + IFCALL(proxy->SurfaceFrameAcknowledge, msg->context, (UINT32)(size_t) msg->wParam); break; case Update_SetKeyboardIndicators: - IFCALL(proxy->SetKeyboardIndicators, msg->context, (UINT16) (size_t) msg->wParam); + IFCALL(proxy->SetKeyboardIndicators, msg->context, (UINT16)(size_t) msg->wParam); break; default: @@ -1481,6 +1800,9 @@ static int update_message_free_primary_update_class(wMessage* msg, int type) { int status = 0; + if (!msg) + return -1; + switch (type) { case PrimaryUpdate_DstBlt: @@ -1530,7 +1852,6 @@ static int update_message_free_primary_update_class(wMessage* msg, int type) case PrimaryUpdate_Polyline: { POLYLINE_ORDER* wParam = (POLYLINE_ORDER*) msg->wParam; - free(wParam->points); free(wParam); } @@ -1567,7 +1888,6 @@ static int update_message_free_primary_update_class(wMessage* msg, int type) case PrimaryUpdate_PolygonSC: { POLYGON_SC_ORDER* wParam = (POLYGON_SC_ORDER*) msg->wParam; - free(wParam->points); free(wParam); } @@ -1576,7 +1896,6 @@ static int update_message_free_primary_update_class(wMessage* msg, int type) case PrimaryUpdate_PolygonCB: { POLYGON_CB_ORDER* wParam = (POLYGON_CB_ORDER*) msg->wParam; - free(wParam->points); free(wParam); } @@ -1599,10 +1918,14 @@ static int update_message_free_primary_update_class(wMessage* msg, int type) } -static int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +static int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* msg, + int type) { int status = 0; + if (!proxy || !msg) + return -1; + switch (type) { case PrimaryUpdate_DstBlt: @@ -1705,12 +2028,14 @@ static int update_message_free_secondary_update_class(wMessage* msg, int type) { int status = 0; + if (!msg) + return -1; + switch (type) { case SecondaryUpdate_CacheBitmap: { CACHE_BITMAP_ORDER* wParam = (CACHE_BITMAP_ORDER*) msg->wParam; - free(wParam->bitmapDataStream); free(wParam); } @@ -1719,7 +2044,6 @@ static int update_message_free_secondary_update_class(wMessage* msg, int type) case SecondaryUpdate_CacheBitmapV2: { CACHE_BITMAP_V2_ORDER* wParam = (CACHE_BITMAP_V2_ORDER*) msg->wParam; - free(wParam->bitmapDataStream); free(wParam); } @@ -1728,7 +2052,6 @@ static int update_message_free_secondary_update_class(wMessage* msg, int type) case SecondaryUpdate_CacheBitmapV3: { CACHE_BITMAP_V3_ORDER* wParam = (CACHE_BITMAP_V3_ORDER*) msg->wParam; - free(wParam->bitmapData.data); free(wParam); } @@ -1771,10 +2094,14 @@ static int update_message_free_secondary_update_class(wMessage* msg, int type) } -static int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +static int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessage* msg, + int type) { int status = 0; + if (!proxy || !msg) + return -1; + switch (type) { case SecondaryUpdate_CacheBitmap: @@ -1817,12 +2144,14 @@ static int update_message_free_altsec_update_class(wMessage* msg, int type) { int status = 0; + if (!msg) + return -1; + switch (type) { case AltSecUpdate_CreateOffscreenBitmap: { CREATE_OFFSCREEN_BITMAP_ORDER* wParam = (CREATE_OFFSCREEN_BITMAP_ORDER*) msg->wParam; - free(wParam->deleteList.indices); free(wParam); } @@ -1881,10 +2210,14 @@ static int update_message_free_altsec_update_class(wMessage* msg, int type) } -static int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +static int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* msg, + int type) { int status = 0; + if (!proxy || !msg) + return -1; + switch (type) { case AltSecUpdate_CreateOffscreenBitmap: @@ -1947,6 +2280,9 @@ static int update_message_free_window_update_class(wMessage* msg, int type) { int status = 0; + if (!msg) + return -1; + switch (type) { case WindowUpdate_WindowCreate: @@ -2010,9 +2346,7 @@ static int update_message_free_window_update_class(wMessage* msg, int type) case WindowUpdate_MonitoredDesktop: { MONITORED_DESKTOP_ORDER* lParam = (MONITORED_DESKTOP_ORDER*) msg->lParam; - free(msg->wParam); - free(lParam->windowIds); free(lParam); } @@ -2031,34 +2365,37 @@ static int update_message_free_window_update_class(wMessage* msg, int type) } -static int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +static int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* msg, + int type) { int status = 0; + if (!proxy || !msg) + return -1; + switch (type) { case WindowUpdate_WindowCreate: IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_STATE_ORDER*) msg->lParam); + (WINDOW_STATE_ORDER*) msg->lParam); break; case WindowUpdate_WindowUpdate: IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_STATE_ORDER*) msg->lParam); + (WINDOW_STATE_ORDER*) msg->lParam); break; case WindowUpdate_WindowIcon: { WINDOW_ORDER_INFO* orderInfo = (WINDOW_ORDER_INFO*) msg->wParam; WINDOW_ICON_ORDER* windowIcon = (WINDOW_ICON_ORDER*) msg->lParam; - IFCALL(proxy->WindowIcon, msg->context, orderInfo, windowIcon); } break; case WindowUpdate_WindowCachedIcon: IFCALL(proxy->WindowCachedIcon, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_CACHED_ICON_ORDER*) msg->lParam); + (WINDOW_CACHED_ICON_ORDER*) msg->lParam); break; case WindowUpdate_WindowDelete: @@ -2067,12 +2404,12 @@ static int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMe case WindowUpdate_NotifyIconCreate: IFCALL(proxy->NotifyIconCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (NOTIFY_ICON_STATE_ORDER*) msg->lParam); + (NOTIFY_ICON_STATE_ORDER*) msg->lParam); break; case WindowUpdate_NotifyIconUpdate: IFCALL(proxy->NotifyIconUpdate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (NOTIFY_ICON_STATE_ORDER*) msg->lParam); + (NOTIFY_ICON_STATE_ORDER*) msg->lParam); break; case WindowUpdate_NotifyIconDelete: @@ -2081,7 +2418,7 @@ static int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMe case WindowUpdate_MonitoredDesktop: IFCALL(proxy->MonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (MONITORED_DESKTOP_ORDER*) msg->lParam); + (MONITORED_DESKTOP_ORDER*) msg->lParam); break; case WindowUpdate_NonMonitoredDesktop: @@ -2100,7 +2437,10 @@ int update_message_free_pointer_update_class(wMessage* msg, int type) { int status = 0; - switch(type) + if (!msg) + return -1; + + switch (type) { case PointerUpdate_PointerPosition: case PointerUpdate_PointerSystem: @@ -2111,7 +2451,6 @@ int update_message_free_pointer_update_class(wMessage* msg, int type) case PointerUpdate_PointerColor: { POINTER_COLOR_UPDATE* wParam = (POINTER_COLOR_UPDATE*) msg->wParam; - free(wParam->andMaskData); free(wParam->xorMaskData); free(wParam); @@ -2121,12 +2460,12 @@ int update_message_free_pointer_update_class(wMessage* msg, int type) case PointerUpdate_PointerNew: { POINTER_NEW_UPDATE* wParam = (POINTER_NEW_UPDATE*) msg->wParam; - free(wParam->colorPtrAttr.andMaskData); free(wParam->colorPtrAttr.xorMaskData); free(wParam); } break; + default: status = -1; break; @@ -2135,10 +2474,14 @@ int update_message_free_pointer_update_class(wMessage* msg, int type) return status; } -static int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +static int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* msg, + int type) { int status = 0; + if (!proxy || !msg) + return -1; + switch (type) { case PointerUpdate_PointerPosition: @@ -2169,7 +2512,7 @@ static int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wM return status; } -static int update_message_free_class(wMessage*msg, int msgClass, int msgType) +static int update_message_free_class(wMessage* msg, int msgClass, int msgType) { int status = 0; @@ -2210,7 +2553,8 @@ static int update_message_free_class(wMessage*msg, int msgClass, int msgType) return status; } -static int update_message_process_class(rdpUpdateProxy* proxy, wMessage* msg, int msgClass, int msgType) +static int update_message_process_class(rdpUpdateProxy* proxy, wMessage* msg, int msgClass, + int msgType) { int status = 0; @@ -2257,12 +2601,14 @@ int update_message_queue_process_message(rdpUpdate* update, wMessage* message) int msgClass; int msgType; + if (!update || !message) + return -1; + if (message->id == WMQ_QUIT) return 0; msgClass = GetMessageClass(message->id); msgType = GetMessageType(message->id); - status = update_message_process_class(update->proxy, message, msgClass, msgType); update_message_free_class(message, msgClass, msgType); @@ -2272,26 +2618,20 @@ int update_message_queue_process_message(rdpUpdate* update, wMessage* message) return 1; } -int update_message_queue_free_message(wMessage *message) +int update_message_queue_free_message(wMessage* message) { - int status; int msgClass; int msgType; - assert(message); + if (!message) + return -1; if (message->id == WMQ_QUIT) return 0; msgClass = GetMessageClass(message->id); msgType = GetMessageType(message->id); - - status = update_message_free_class(message, msgClass, msgType); - - if (status < 0) - status = -1; - - return 1; + return update_message_free_class(message, msgClass, msgType); } int update_message_queue_process_pending_messages(rdpUpdate* update) @@ -2300,6 +2640,9 @@ int update_message_queue_process_pending_messages(rdpUpdate* update) wMessage message; wMessageQueue* queue; + if (!update || !update->queue) + return -1; + status = 1; queue = update->queue; @@ -2314,7 +2657,7 @@ int update_message_queue_process_pending_messages(rdpUpdate* update) return status; } -void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* update) +static BOOL update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* update) { rdpPrimaryUpdate* primary; rdpSecondaryUpdate* secondary; @@ -2322,14 +2665,19 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat rdpWindowUpdate* window; rdpPointerUpdate* pointer; + if (!message || !update) + return FALSE; + primary = update->primary; secondary = update->secondary; altsec = update->altsec; window = update->window; pointer = update->pointer; - /* Update */ + if (!primary || !secondary || !altsec || !window || !pointer) + return FALSE; + /* Update */ message->BeginPaint = update->BeginPaint; message->EndPaint = update->EndPaint; message->SetBounds = update->SetBounds; @@ -2345,7 +2693,6 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat message->SurfaceBits = update->SurfaceBits; message->SurfaceFrameMarker = update->SurfaceFrameMarker; message->SurfaceFrameAcknowledge = update->SurfaceFrameAcknowledge; - update->BeginPaint = update_message_BeginPaint; update->EndPaint = update_message_EndPaint; update->SetBounds = update_message_SetBounds; @@ -2361,9 +2708,7 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat update->SurfaceBits = update_message_SurfaceBits; update->SurfaceFrameMarker = update_message_SurfaceFrameMarker; update->SurfaceFrameAcknowledge = update_message_SurfaceFrameAcknowledge; - /* Primary Update */ - message->DstBlt = primary->DstBlt; message->PatBlt = primary->PatBlt; message->ScrBlt = primary->ScrBlt; @@ -2386,7 +2731,6 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat message->PolygonCB = primary->PolygonCB; message->EllipseSC = primary->EllipseSC; message->EllipseCB = primary->EllipseCB; - primary->DstBlt = update_message_DstBlt; primary->PatBlt = update_message_PatBlt; primary->ScrBlt = update_message_ScrBlt; @@ -2409,9 +2753,7 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat primary->PolygonCB = update_message_PolygonCB; primary->EllipseSC = update_message_EllipseSC; primary->EllipseCB = update_message_EllipseCB; - /* Secondary Update */ - message->CacheBitmap = secondary->CacheBitmap; message->CacheBitmapV2 = secondary->CacheBitmapV2; message->CacheBitmapV3 = secondary->CacheBitmapV3; @@ -2419,7 +2761,6 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat message->CacheGlyph = secondary->CacheGlyph; message->CacheGlyphV2 = secondary->CacheGlyphV2; message->CacheBrush = secondary->CacheBrush; - secondary->CacheBitmap = update_message_CacheBitmap; secondary->CacheBitmapV2 = update_message_CacheBitmapV2; secondary->CacheBitmapV3 = update_message_CacheBitmapV3; @@ -2427,9 +2768,7 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat secondary->CacheGlyph = update_message_CacheGlyph; secondary->CacheGlyphV2 = update_message_CacheGlyphV2; secondary->CacheBrush = update_message_CacheBrush; - /* Alternate Secondary Update */ - message->CreateOffscreenBitmap = altsec->CreateOffscreenBitmap; message->SwitchSurface = altsec->SwitchSurface; message->CreateNineGridBitmap = altsec->CreateNineGridBitmap; @@ -2442,7 +2781,6 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat message->DrawGdiPlusCacheFirst = altsec->DrawGdiPlusCacheFirst; message->DrawGdiPlusCacheNext = altsec->DrawGdiPlusCacheNext; message->DrawGdiPlusCacheEnd = altsec->DrawGdiPlusCacheEnd; - altsec->CreateOffscreenBitmap = update_message_CreateOffscreenBitmap; altsec->SwitchSurface = update_message_SwitchSurface; altsec->CreateNineGridBitmap = update_message_CreateNineGridBitmap; @@ -2455,9 +2793,7 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat altsec->DrawGdiPlusCacheFirst = update_message_DrawGdiPlusCacheFirst; altsec->DrawGdiPlusCacheNext = update_message_DrawGdiPlusCacheNext; altsec->DrawGdiPlusCacheEnd = update_message_DrawGdiPlusCacheEnd; - /* Window Update */ - message->WindowCreate = window->WindowCreate; message->WindowUpdate = window->WindowUpdate; message->WindowIcon = window->WindowIcon; @@ -2468,7 +2804,6 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat message->NotifyIconDelete = window->NotifyIconDelete; message->MonitoredDesktop = window->MonitoredDesktop; message->NonMonitoredDesktop = window->NonMonitoredDesktop; - window->WindowCreate = update_message_WindowCreate; window->WindowUpdate = update_message_WindowUpdate; window->WindowIcon = update_message_WindowIcon; @@ -2479,30 +2814,29 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat window->NotifyIconDelete = update_message_NotifyIconDelete; window->MonitoredDesktop = update_message_MonitoredDesktop; window->NonMonitoredDesktop = update_message_NonMonitoredDesktop; - /* Pointer Update */ - message->PointerPosition = pointer->PointerPosition; message->PointerSystem = pointer->PointerSystem; message->PointerColor = pointer->PointerColor; message->PointerNew = pointer->PointerNew; message->PointerCached = pointer->PointerCached; - pointer->PointerPosition = update_message_PointerPosition; pointer->PointerSystem = update_message_PointerSystem; pointer->PointerColor = update_message_PointerColor; pointer->PointerNew = update_message_PointerNew; pointer->PointerCached = update_message_PointerCached; + return TRUE; } -static void *update_message_proxy_thread(void *arg) +static void* update_message_proxy_thread(void* arg) { - rdpUpdate *update = (rdpUpdate *)arg; + rdpUpdate* update = (rdpUpdate*)arg; wMessage message; if (!update || !update->queue) { - WLog_ERR(TAG, "update=%p, update->queue=%p", (void*) update, (void*) (update ? update->queue : NULL)); + WLog_ERR(TAG, "update=%p, update->queue=%p", (void*) update, + (void*)(update ? update->queue : NULL)); ExitThread(-1); return NULL; } @@ -2522,16 +2856,21 @@ static void *update_message_proxy_thread(void *arg) return NULL; } -rdpUpdateProxy *update_message_proxy_new(rdpUpdate *update) +rdpUpdateProxy* update_message_proxy_new(rdpUpdate* update) { - rdpUpdateProxy *message; + rdpUpdateProxy* message; + + if (!update) + return NULL; - if (!(message = (rdpUpdateProxy *) calloc(1, sizeof(rdpUpdateProxy)))) + if (!(message = (rdpUpdateProxy*) calloc(1, sizeof(rdpUpdateProxy)))) return NULL; message->update = update; update_message_register_interface(message, update); - if (!(message->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) update_message_proxy_thread, update, 0, NULL))) + + if (!(message->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) update_message_proxy_thread, + update, 0, NULL))) { WLog_ERR(TAG, "Failed to create proxy thread"); free(message); @@ -2547,6 +2886,7 @@ void update_message_proxy_free(rdpUpdateProxy* message) { if (MessageQueue_PostQuit(message->update->queue, 0)) WaitForSingleObject(message->thread, INFINITE); + CloseHandle(message->thread); free(message); } @@ -2556,48 +2896,69 @@ void update_message_proxy_free(rdpUpdateProxy* message) static BOOL input_message_SynchronizeEvent(rdpInput* input, UINT32 flags) { + if (!input) + return FALSE; + return MessageQueue_Post(input->queue, (void*) input, - MakeMessageId(Input, SynchronizeEvent), (void*) (size_t) flags, NULL); + MakeMessageId(Input, SynchronizeEvent), (void*)(size_t) flags, NULL); } static BOOL input_message_KeyboardEvent(rdpInput* input, UINT16 flags, UINT16 code) { + if (!input) + return FALSE; + return MessageQueue_Post(input->queue, (void*) input, - MakeMessageId(Input, KeyboardEvent), (void*) (size_t) flags, (void*) (size_t) code); + MakeMessageId(Input, KeyboardEvent), (void*)(size_t) flags, (void*)(size_t) code); } static BOOL input_message_UnicodeKeyboardEvent(rdpInput* input, UINT16 flags, UINT16 code) { + if (!input) + return FALSE; + return MessageQueue_Post(input->queue, (void*) input, - MakeMessageId(Input, UnicodeKeyboardEvent), (void*) (size_t) flags, (void*) (size_t) code); + MakeMessageId(Input, UnicodeKeyboardEvent), (void*)(size_t) flags, (void*)(size_t) code); } static BOOL input_message_MouseEvent(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { UINT32 pos = (x << 16) | y; + if (!input) + return FALSE; + return MessageQueue_Post(input->queue, (void*) input, - MakeMessageId(Input, MouseEvent), (void*) (size_t) flags, (void*) (size_t) pos); + MakeMessageId(Input, MouseEvent), (void*)(size_t) flags, (void*)(size_t) pos); } static BOOL input_message_ExtendedMouseEvent(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { UINT32 pos = (x << 16) | y; + if (!input) + return FALSE; + return MessageQueue_Post(input->queue, (void*) input, - MakeMessageId(Input, ExtendedMouseEvent), (void*) (size_t) flags, (void*) (size_t) pos); + MakeMessageId(Input, ExtendedMouseEvent), (void*)(size_t) flags, (void*)(size_t) pos); } static BOOL input_message_FocusInEvent(rdpInput* input, UINT16 toggleStates) { + if (!input) + return FALSE; + return MessageQueue_Post(input->queue, (void*) input, - MakeMessageId(Input, FocusInEvent), (void*) (size_t) toggleStates, NULL); + MakeMessageId(Input, FocusInEvent), (void*)(size_t) toggleStates, NULL); } static BOOL input_message_KeyboardPauseEvent(rdpInput* input) { + if (!input) + return FALSE; + return MessageQueue_Post(input->queue, (void*) input, - MakeMessageId(Input, KeyboardPauseEvent), NULL, NULL); + MakeMessageId(Input, KeyboardPauseEvent), NULL, NULL); } /* Event Queue */ @@ -2640,30 +3001,33 @@ static int input_message_process_input_class(rdpInputProxy* proxy, wMessage* msg { int status = 0; + if (!proxy || !msg) + return -1; + switch (type) { case Input_SynchronizeEvent: - IFCALL(proxy->SynchronizeEvent, msg->context, (UINT32) (size_t) msg->wParam); + IFCALL(proxy->SynchronizeEvent, msg->context, (UINT32)(size_t) msg->wParam); break; case Input_KeyboardEvent: - IFCALL(proxy->KeyboardEvent, msg->context, (UINT16) (size_t) msg->wParam, (UINT16) (size_t) msg->lParam); + IFCALL(proxy->KeyboardEvent, msg->context, (UINT16)(size_t) msg->wParam, + (UINT16)(size_t) msg->lParam); break; case Input_UnicodeKeyboardEvent: - IFCALL(proxy->UnicodeKeyboardEvent, msg->context, (UINT16) (size_t) msg->wParam, (UINT16) (size_t) msg->lParam); + IFCALL(proxy->UnicodeKeyboardEvent, msg->context, (UINT16)(size_t) msg->wParam, + (UINT16)(size_t) msg->lParam); break; case Input_MouseEvent: { UINT32 pos; UINT16 x, y; - - pos = (UINT32) (size_t) msg->lParam; + pos = (UINT32)(size_t) msg->lParam; x = ((pos & 0xFFFF0000) >> 16); y = (pos & 0x0000FFFF); - - IFCALL(proxy->MouseEvent, msg->context, (UINT16) (size_t) msg->wParam, x, y); + IFCALL(proxy->MouseEvent, msg->context, (UINT16)(size_t) msg->wParam, x, y); } break; @@ -2671,17 +3035,15 @@ static int input_message_process_input_class(rdpInputProxy* proxy, wMessage* msg { UINT32 pos; UINT16 x, y; - - pos = (UINT32) (size_t) msg->lParam; + pos = (UINT32)(size_t) msg->lParam; x = ((pos & 0xFFFF0000) >> 16); y = (pos & 0x0000FFFF); - - IFCALL(proxy->ExtendedMouseEvent, msg->context, (UINT16) (size_t) msg->wParam, x, y); + IFCALL(proxy->ExtendedMouseEvent, msg->context, (UINT16)(size_t) msg->wParam, x, y); } break; case Input_FocusInEvent: - IFCALL(proxy->FocusInEvent, msg->context, (UINT16) (size_t) msg->wParam); + IFCALL(proxy->FocusInEvent, msg->context, (UINT16)(size_t) msg->wParam); break; case Input_KeyboardPauseEvent: @@ -2717,7 +3079,8 @@ static int input_message_free_class(wMessage* msg, int msgClass, int msgType) return status; } -static int input_message_process_class(rdpInputProxy* proxy, wMessage* msg, int msgClass, int msgType) +static int input_message_process_class(rdpInputProxy* proxy, wMessage* msg, int msgClass, + int msgType) { int status = 0; @@ -2744,12 +3107,14 @@ int input_message_queue_free_message(wMessage* message) int msgClass; int msgType; + if (!message) + return -1; + if (message->id == WMQ_QUIT) return 0; msgClass = GetMessageClass(message->id); msgType = GetMessageType(message->id); - status = input_message_free_class(message, msgClass, msgType); if (status < 0) @@ -2764,12 +3129,14 @@ int input_message_queue_process_message(rdpInput* input, wMessage* message) int msgClass; int msgType; + if (!input || !message) + return -1; + if (message->id == WMQ_QUIT) return 0; msgClass = GetMessageClass(message->id); msgType = GetMessageType(message->id); - status = input_message_process_class(input->proxy, message, msgClass, msgType); input_message_free_class(message, msgClass, msgType); @@ -2786,6 +3153,9 @@ int input_message_queue_process_pending_messages(rdpInput* input) wMessage message; wMessageQueue* queue; + if (!input || !input->queue) + return -1; + count = 0; status = 1; queue = input->queue; @@ -2803,10 +3173,12 @@ int input_message_queue_process_pending_messages(rdpInput* input) return status; } -void input_message_proxy_register(rdpInputProxy* proxy, rdpInput* input) +static BOOL input_message_proxy_register(rdpInputProxy* proxy, rdpInput* input) { - /* Input */ + if (!proxy || !input) + return FALSE; + /* Input */ proxy->SynchronizeEvent = input->SynchronizeEvent; proxy->KeyboardEvent = input->KeyboardEvent; proxy->UnicodeKeyboardEvent = input->UnicodeKeyboardEvent; @@ -2814,7 +3186,6 @@ void input_message_proxy_register(rdpInputProxy* proxy, rdpInput* input) proxy->ExtendedMouseEvent = input->ExtendedMouseEvent; proxy->FocusInEvent = input->FocusInEvent; proxy->KeyboardPauseEvent = input->KeyboardPauseEvent; - input->SynchronizeEvent = input_message_SynchronizeEvent; input->KeyboardEvent = input_message_KeyboardEvent; input->UnicodeKeyboardEvent = input_message_UnicodeKeyboardEvent; @@ -2822,19 +3193,24 @@ void input_message_proxy_register(rdpInputProxy* proxy, rdpInput* input) input->ExtendedMouseEvent = input_message_ExtendedMouseEvent; input->FocusInEvent = input_message_FocusInEvent; input->KeyboardPauseEvent = input_message_KeyboardPauseEvent; + return TRUE; } rdpInputProxy* input_message_proxy_new(rdpInput* input) { rdpInputProxy* proxy; - proxy = (rdpInputProxy*) calloc(1, sizeof(rdpInputProxy)); if (!proxy) return NULL; proxy->input = input; - input_message_proxy_register(proxy, input); + + if (!input_message_proxy_register(proxy, input)) + { + free(proxy); + return NULL; + } return proxy; } diff --git a/libfreerdp/core/nego.h b/libfreerdp/core/nego.h index b780b32..fdbce70 100644 --- a/libfreerdp/core/nego.h +++ b/libfreerdp/core/nego.h @@ -30,15 +30,12 @@ #include /* 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 */ diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 68a519c..2212abd 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -48,7 +48,7 @@ #define TAG FREERDP_TAG("core.nla") #define SERVER_KEY "Software\\"FREERDP_VENDOR_STRING"\\" \ - FREERDP_PRODUCT_STRING"\\Server" + FREERDP_PRODUCT_STRING"\\Server" /** * TSRequest ::= SEQUENCE { @@ -120,19 +120,21 @@ void nla_identity_free(SEC_WINNT_AUTH_IDENTITY* identity) memset(identity->User, 0, identity->UserLength * 2); free(identity->User); } + if (identity->Password) { memset(identity->Password, 0, identity->PasswordLength * 2); free(identity->Password); } + if (identity->Domain) { memset(identity->Domain, 0, identity->DomainLength * 2); free(identity->Domain); } } - free(identity); + free(identity); } /** @@ -150,14 +152,13 @@ int nla_client_init(rdpNla* nla) rdpSettings* settings = nla->settings; WINPR_SAM* sam; WINPR_SAM_ENTRY* entry; - nla->state = NLA_STATE_INITIAL; if (settings->RestrictedAdminModeRequired) settings->DisableCredentialsDelegation = TRUE; if ((!settings->Password) || (!settings->Username) - || (!strlen(settings->Username))) + || (!strlen(settings->Username))) { PromptPassword = TRUE; } @@ -185,6 +186,7 @@ int nla_client_init(rdpNla* nla) } #ifndef _WIN32 + if (PromptPassword) { if (settings->RestrictedAdminModeRequired) @@ -193,6 +195,7 @@ int nla_client_init(rdpNla* nla) PromptPassword = FALSE; } } + #endif if (PromptPassword) @@ -200,7 +203,7 @@ int nla_client_init(rdpNla* nla) if (instance->Authenticate) { BOOL proceed = instance->Authenticate(instance, - &settings->Username, &settings->Password, &settings->Domain); + &settings->Username, &settings->Password, &settings->Domain); if (!proceed) { @@ -217,7 +220,7 @@ int nla_client_init(rdpNla* nla) } else sspi_SetAuthIdentity(nla->identity, settings->Username, settings->Domain, - settings->Password); + settings->Password); #ifndef _WIN32 { @@ -236,9 +239,8 @@ int nla_client_init(rdpNla* nla) if (strlen(settings->PasswordHash) == 32) { free(identity->Password); - identity->PasswordLength = ConvertToUnicode(CP_UTF8, 0, - settings->PasswordHash, -1, &identity->Password, 0) - 1; + settings->PasswordHash, -1, &identity->Password, 0) - 1; /** * Multiply password hash length by 64 to obtain a length exceeding * the maximum (256) and use it this for hash identification in WinPR. @@ -249,7 +251,6 @@ int nla_client_init(rdpNla* nla) } } #endif - tls = nla->transport->tls; if (!tls) @@ -263,16 +264,15 @@ int nla_client_init(rdpNla* nla) WLog_ERR(TAG, "Failed to allocate sspic secBuffer"); return -1; } + CopyMemory(nla->PublicKey.pvBuffer, tls->PublicKey, tls->PublicKeyLength); length = sizeof(TERMSRV_SPN_PREFIX) + strlen(settings->ServerHostname); - spn = (SEC_CHAR*) malloc(length + 1); if (!spn) return -1; sprintf(spn, "%s%s", TERMSRV_SPN_PREFIX, settings->ServerHostname); - #ifdef UNICODE nla->ServicePrincipalName = NULL; ConvertToUnicode(CP_UTF8, 0, spn, -1, &nla->ServicePrincipalName, 0); @@ -280,26 +280,25 @@ int nla_client_init(rdpNla* nla) #else nla->ServicePrincipalName = spn; #endif - nla->table = InitSecurityInterfaceEx(0); nla->status = nla->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &nla->pPackageInfo); if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "QuerySecurityPackageInfo status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } nla->cbMaxToken = nla->pPackageInfo->cbMaxToken; nla->status = nla->table->AcquireCredentialsHandle(NULL, NLA_PKG_NAME, - SECPKG_CRED_OUTBOUND, NULL, nla->identity, NULL, NULL, &nla->credentials, - &nla->expiration); + SECPKG_CRED_OUTBOUND, NULL, nla->identity, NULL, NULL, &nla->credentials, + &nla->expiration); if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "AcquireCredentialsHandle status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } @@ -309,7 +308,6 @@ int nla_client_init(rdpNla* nla) ZeroMemory(&nla->inputBuffer, sizeof(SecBuffer)); ZeroMemory(&nla->outputBuffer, sizeof(SecBuffer)); ZeroMemory(&nla->ContextSizes, sizeof(SecPkgContext_Sizes)); - /* * from tspkg.dll: 0x00000132 * ISC_REQ_MUTUAL_AUTH @@ -318,7 +316,6 @@ int nla_client_init(rdpNla* nla) * ISC_REQ_ALLOCATE_MEMORY */ nla->fContextReq = ISC_REQ_MUTUAL_AUTH | ISC_REQ_CONFIDENTIALITY | ISC_REQ_USE_SESSION_KEY; - return 1; } @@ -341,24 +338,23 @@ int nla_client_begin(rdpNla* nla) return -1; nla->status = nla->table->InitializeSecurityContext(&nla->credentials, - NULL, nla->ServicePrincipalName, nla->fContextReq, 0, - SECURITY_NATIVE_DREP, NULL, 0, &nla->context, - &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration); - + NULL, nla->ServicePrincipalName, nla->fContextReq, 0, + SECURITY_NATIVE_DREP, NULL, 0, &nla->context, + &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration); WLog_VRB(TAG, " InitializeSecurityContext status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED)) { if (nla->table->CompleteAuthToken) { SECURITY_STATUS status; - status = nla->table->CompleteAuthToken(&nla->context, &nla->outputBufferDesc); + if (status != SEC_E_OK) { WLog_WARN(TAG, "CompleteAuthToken status %s [0x%08"PRIX32"]", - GetSecurityStatusString(status), status); + GetSecurityStatusString(status), status); return -1; } } @@ -377,7 +373,6 @@ int nla_client_begin(rdpNla* nla) nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer; nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer; - WLog_DBG(TAG, "Sending Authentication Token"); winpr_HexDump(TAG, WLOG_DEBUG, nla->negoToken.pvBuffer, nla->negoToken.cbBuffer); @@ -388,9 +383,7 @@ int nla_client_begin(rdpNla* nla) } nla_buffer_free(nla); - nla->state = NLA_STATE_NEGO_TOKEN; - return 1; } @@ -406,7 +399,6 @@ int nla_client_recv(rdpNla* nla) nla->inputBuffer.BufferType = SECBUFFER_TOKEN; nla->inputBuffer.pvBuffer = nla->negoToken.pvBuffer; nla->inputBuffer.cbBuffer = nla->negoToken.cbBuffer; - nla->outputBufferDesc.ulVersion = SECBUFFER_VERSION; nla->outputBufferDesc.cBuffers = 1; nla->outputBufferDesc.pBuffers = &nla->outputBuffer; @@ -418,13 +410,11 @@ int nla_client_recv(rdpNla* nla) return -1; nla->status = nla->table->InitializeSecurityContext(&nla->credentials, - &nla->context, nla->ServicePrincipalName, nla->fContextReq, 0, - SECURITY_NATIVE_DREP, &nla->inputBufferDesc, - 0, &nla->context, &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration); - + &nla->context, nla->ServicePrincipalName, nla->fContextReq, 0, + SECURITY_NATIVE_DREP, &nla->inputBufferDesc, + 0, &nla->context, &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration); WLog_VRB(TAG, "InitializeSecurityContext %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); - + GetSecurityStatusString(nla->status), nla->status); free(nla->inputBuffer.pvBuffer); nla->inputBuffer.pvBuffer = NULL; @@ -434,10 +424,11 @@ int nla_client_recv(rdpNla* nla) { SECURITY_STATUS status; status = nla->table->CompleteAuthToken(&nla->context, &nla->outputBufferDesc); + if (status != SEC_E_OK) { WLog_WARN(TAG, "CompleteAuthToken status %s [0x%08"PRIX32"]", - GetSecurityStatusString(status), status); + GetSecurityStatusString(status), status); return -1; } } @@ -451,23 +442,24 @@ int nla_client_recv(rdpNla* nla) if (nla->status == SEC_E_OK) { nla->havePubKeyAuth = TRUE; + nla->status = nla->table->QueryContextAttributes(&nla->context, SECPKG_ATTR_SIZES, + &nla->ContextSizes); - nla->status = nla->table->QueryContextAttributes(&nla->context, SECPKG_ATTR_SIZES, &nla->ContextSizes); if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } nla->status = nla_encrypt_public_key_echo(nla); + if (nla->status != SEC_E_OK) return -1; } nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer; nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer; - WLog_DBG(TAG, "Sending Authentication Token"); winpr_HexDump(TAG, WLOG_DEBUG, nla->negoToken.pvBuffer, nla->negoToken.cbBuffer); @@ -476,10 +468,12 @@ int nla_client_recv(rdpNla* nla) nla_buffer_free(nla); return -1; } + nla_buffer_free(nla); if (nla->status == SEC_E_OK) nla->state = NLA_STATE_PUB_KEY_AUTH; + status = 1; } else if (nla->state == NLA_STATE_PUB_KEY_AUTH) @@ -491,7 +485,7 @@ int nla_client_recv(rdpNla* nla) if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "Could not verify public key echo %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } @@ -501,7 +495,7 @@ int nla_client_recv(rdpNla* nla) if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "nla_encrypt_ts_credentials status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } @@ -510,20 +504,22 @@ int nla_client_recv(rdpNla* nla) nla_buffer_free(nla); return -1; } - nla_buffer_free(nla); + nla_buffer_free(nla); nla->table->FreeCredentialsHandle(&nla->credentials); + if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "FreeCredentialsHandle status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); } nla->status = nla->table->FreeContextBuffer(nla->pPackageInfo); + if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "FreeContextBuffer status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); } if (nla->status != SEC_E_OK) @@ -540,7 +536,6 @@ int nla_client_authenticate(rdpNla* nla) { wStream* s; int status; - s = Stream_New(NULL, 4096); if (!s) @@ -558,7 +553,6 @@ int nla_client_authenticate(rdpNla* nla) while (nla->state < NLA_STATE_AUTH_INFO) { Stream_SetPosition(s, 0); - status = transport_read_pdu(nla->transport, s); if (status < 0) @@ -578,7 +572,6 @@ int nla_client_authenticate(rdpNla* nla) } Stream_Free(s, TRUE); - return 1; } @@ -596,13 +589,13 @@ int nla_server_init(rdpNla* nla) WLog_ERR(TAG, "Failed to allocate SecBuffer for public key"); return -1; } + CopyMemory(nla->PublicKey.pvBuffer, tls->PublicKey, tls->PublicKeyLength); if (nla->SspiModule) { HMODULE hSSPI; INIT_SECURITY_INTERFACE pInitSecurityInterface; - hSSPI = LoadLibrary(nla->SspiModule); if (!hSSPI) @@ -628,18 +621,18 @@ int nla_server_init(rdpNla* nla) if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "QuerySecurityPackageInfo status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } nla->cbMaxToken = nla->pPackageInfo->cbMaxToken; nla->status = nla->table->AcquireCredentialsHandle(NULL, NLA_PKG_NAME, - SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &nla->credentials, &nla->expiration); + SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &nla->credentials, &nla->expiration); if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "AcquireCredentialsHandle status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } @@ -651,7 +644,6 @@ int nla_server_init(rdpNla* nla) ZeroMemory(&nla->inputBufferDesc, sizeof(SecBufferDesc)); ZeroMemory(&nla->outputBufferDesc, sizeof(SecBufferDesc)); ZeroMemory(&nla->ContextSizes, sizeof(SecPkgContext_Sizes)); - /* * from tspkg.dll: 0x00000112 * ASC_REQ_MUTUAL_AUTH @@ -666,7 +658,6 @@ int nla_server_init(rdpNla* nla) nla->fContextReq |= ASC_REQ_REPLAY_DETECT; nla->fContextReq |= ASC_REQ_SEQUENCE_DETECT; nla->fContextReq |= ASC_REQ_EXTENDED_ERROR; - return 1; } @@ -694,7 +685,6 @@ int nla_server_authenticate(rdpNla* nla) WLog_DBG(TAG, "Receiving Authentication Token"); nla_buffer_print(nla); - nla->inputBuffer.pvBuffer = nla->negoToken.pvBuffer; nla->inputBuffer.cbBuffer = nla->negoToken.cbBuffer; @@ -715,12 +705,11 @@ int nla_server_authenticate(rdpNla* nla) return -1; nla->status = nla->table->AcceptSecurityContext(&nla->credentials, - nla->haveContext? &nla->context: NULL, - &nla->inputBufferDesc, nla->fContextReq, SECURITY_NATIVE_DREP, &nla->context, - &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration); - + nla->haveContext ? &nla->context : NULL, + &nla->inputBufferDesc, nla->fContextReq, SECURITY_NATIVE_DREP, &nla->context, + &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration); WLog_VRB(TAG, "AcceptSecurityContext status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer; nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer; @@ -729,7 +718,7 @@ int nla_server_authenticate(rdpNla* nla) if (nla->SamFile) { nla->table->SetContextAttributes(&nla->context, - SECPKG_ATTR_AUTH_NTLM_SAM_FILE, nla->SamFile, strlen(nla->SamFile) + 1); + SECPKG_ATTR_AUTH_NTLM_SAM_FILE, nla->SamFile, strlen(nla->SamFile) + 1); } if (nla->table->CompleteAuthToken) @@ -740,7 +729,7 @@ int nla_server_authenticate(rdpNla* nla) if (status != SEC_E_OK) { WLog_WARN(TAG, "CompleteAuthToken status %s [0x%08"PRIX32"]", - GetSecurityStatusString(status), status); + GetSecurityStatusString(status), status); return -1; } } @@ -769,20 +758,22 @@ int nla_server_authenticate(rdpNla* nla) } nla->havePubKeyAuth = TRUE; + nla->status = nla->table->QueryContextAttributes(&nla->context, SECPKG_ATTR_SIZES, + &nla->ContextSizes); - nla->status = nla->table->QueryContextAttributes(&nla->context, SECPKG_ATTR_SIZES, &nla->ContextSizes); if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } nla->status = nla_decrypt_public_key_echo(nla); + if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "Error: could not verify client's public key echo %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } @@ -790,6 +781,7 @@ int nla_server_authenticate(rdpNla* nla) nla->negoToken.pvBuffer = NULL; nla->negoToken.cbBuffer = 0; nla->status = nla_encrypt_public_key_echo(nla); + if (nla->status != SEC_E_OK) return -1; } @@ -804,25 +796,27 @@ int nla_server_authenticate(rdpNla* nla) case ERROR_PASSWORD_MUST_CHANGE: nla->errorCode = STATUS_PASSWORD_MUST_CHANGE; break; + case ERROR_PASSWORD_EXPIRED: nla->errorCode = STATUS_PASSWORD_EXPIRED; break; + case ERROR_ACCOUNT_DISABLED: nla->errorCode = STATUS_ACCOUNT_DISABLED; break; + default: nla->errorCode = NTSTATUS_FROM_WIN32(GetLastError()); break; } WLog_ERR(TAG, "AcceptSecurityContext status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); nla_send(nla); return -1; /* Access Denied */ } /* send authentication token */ - WLog_DBG(TAG, "Sending Authentication Token"); nla_buffer_print(nla); @@ -831,6 +825,7 @@ int nla_server_authenticate(rdpNla* nla) nla_buffer_free(nla); return -1; } + nla_buffer_free(nla); if (nla->status != SEC_I_CONTINUE_NEEDED) @@ -845,10 +840,11 @@ int nla_server_authenticate(rdpNla* nla) return -1; nla->status = nla_decrypt_ts_credentials(nla); + if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "Could not decrypt TSCredentials status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } @@ -857,7 +853,7 @@ int nla_server_authenticate(rdpNla* nla) if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "ImpersonateSecurityContext status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } else @@ -867,16 +863,17 @@ int nla_server_authenticate(rdpNla* nla) if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "RevertSecurityContext status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } } nla->status = nla->table->FreeContextBuffer(nla->pPackageInfo); + if (nla->status != SEC_E_OK) { WLog_ERR(TAG, "DeleteSecurityContext status %s [0x%08"PRIX32"]", - GetSecurityStatusString(nla->status), nla->status); + GetSecurityStatusString(nla->status), nla->status); return -1; } @@ -941,14 +938,14 @@ SECURITY_STATUS nla_encrypt_public_key_echo(rdpNla* nla) SecBufferDesc Message; SECURITY_STATUS status; int public_key_length; - public_key_length = nla->PublicKey.cbBuffer; + if (!sspi_SecBufferAlloc(&nla->pubKeyAuth, nla->ContextSizes.cbSecurityTrailer + public_key_length)) return SEC_E_INSUFFICIENT_MEMORY; + Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */ Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer; Buffers[0].pvBuffer = nla->pubKeyAuth.pvBuffer; - Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */ Buffers[1].cbBuffer = public_key_length; Buffers[1].pvBuffer = ((BYTE*) nla->pubKeyAuth.pvBuffer) + nla->ContextSizes.cbSecurityTrailer; @@ -968,14 +965,15 @@ SECURITY_STATUS nla_encrypt_public_key_echo(rdpNla* nla) if (status != SEC_E_OK) { WLog_ERR(TAG, "EncryptMessage status %s [0x%08"PRIX32"]", - GetSecurityStatusString(status), status); + GetSecurityStatusString(status), status); return status; } if (Buffers[0].cbBuffer < nla->ContextSizes.cbSecurityTrailer) { /* EncryptMessage may not use all the signature space, so we need to shrink the excess */ - MoveMemory(((BYTE*)nla->pubKeyAuth.pvBuffer) + Buffers[0].cbBuffer, Buffers[1].pvBuffer, Buffers[1].cbBuffer); + MoveMemory(((BYTE*)nla->pubKeyAuth.pvBuffer) + Buffers[0].cbBuffer, Buffers[1].pvBuffer, + Buffers[1].cbBuffer); nla->pubKeyAuth.cbBuffer = Buffers[0].cbBuffer + Buffers[1].cbBuffer; } @@ -994,8 +992,8 @@ SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla) SecBuffer Buffers[2]; SecBufferDesc Message; SECURITY_STATUS status; - signature_length = nla->pubKeyAuth.cbBuffer - nla->PublicKey.cbBuffer; + if (signature_length < 0 || signature_length > nla->ContextSizes.cbSecurityTrailer) { WLog_ERR(TAG, "unexpected pubKeyAuth buffer size: %"PRIu32"", nla->pubKeyAuth.cbBuffer); @@ -1013,7 +1011,6 @@ SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla) Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */ Buffers[0].cbBuffer = signature_length; Buffers[0].pvBuffer = buffer; - Buffers[1].BufferType = SECBUFFER_DATA; /* Encrypted TLS Public Key */ Buffers[1].cbBuffer = length - signature_length; Buffers[1].pvBuffer = buffer + signature_length; @@ -1025,7 +1022,7 @@ SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla) if (status != SEC_E_OK) { WLog_ERR(TAG, "DecryptMessage failure %s [%08"PRIX32"]", - GetSecurityStatusString(status), status); + GetSecurityStatusString(status), status); return status; } @@ -1055,12 +1052,14 @@ SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla) int nla_sizeof_ts_password_creds(rdpNla* nla) { int length = 0; + if (nla->identity) { length += ber_sizeof_sequence_octet_string(nla->identity->DomainLength * 2); length += ber_sizeof_sequence_octet_string(nla->identity->UserLength * 2); length += ber_sizeof_sequence_octet_string(nla->identity->PasswordLength * 2); } + return length; } @@ -1077,13 +1076,10 @@ BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s) /* TSPasswordCreds (SEQUENCE) * Initialise to default values. */ nla->identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; - nla->identity->UserLength = (UINT32) 0; nla->identity->User = NULL; - nla->identity->DomainLength = (UINT32) 0; nla->identity->Domain = NULL; - nla->identity->Password = NULL; nla->identity->PasswordLength = (UINT32) 0; @@ -1097,17 +1093,20 @@ BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s) /* [0] domainName (OCTET STRING) */ if (!ber_read_contextual_tag(s, 0, &length, TRUE) || - !ber_read_octet_string_tag(s, &length)) + !ber_read_octet_string_tag(s, &length)) { return FALSE; } nla->identity->DomainLength = (UINT32) length; + if (nla->identity->DomainLength > 0) { nla->identity->Domain = (UINT16*) malloc(length); + if (!nla->identity->Domain) return FALSE; + CopyMemory(nla->identity->Domain, Stream_Pointer(s), nla->identity->DomainLength); Stream_Seek(s, nla->identity->DomainLength); nla->identity->DomainLength /= 2; @@ -1115,17 +1114,20 @@ BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s) /* [1] userName (OCTET STRING) */ if (!ber_read_contextual_tag(s, 1, &length, TRUE) || - !ber_read_octet_string_tag(s, &length)) + !ber_read_octet_string_tag(s, &length)) { return FALSE; } nla->identity->UserLength = (UINT32) length; + if (nla->identity->UserLength > 0) { - nla->identity->User = (UINT16 *) malloc(length); + nla->identity->User = (UINT16*) malloc(length); + if (!nla->identity->User) return FALSE; + CopyMemory(nla->identity->User, Stream_Pointer(s), nla->identity->UserLength); Stream_Seek(s, nla->identity->UserLength); nla->identity->UserLength /= 2; @@ -1133,17 +1135,20 @@ BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s) /* [2] password (OCTET STRING) */ if (!ber_read_contextual_tag(s, 2, &length, TRUE) || - !ber_read_octet_string_tag(s, &length)) + !ber_read_octet_string_tag(s, &length)) { return FALSE; } nla->identity->PasswordLength = (UINT32) length; + if (nla->identity->PasswordLength > 0) { - nla->identity->Password = (UINT16 *) malloc(length); + nla->identity->Password = (UINT16*) malloc(length); + if (!nla->identity->Password) return FALSE; + CopyMemory(nla->identity->Password, Stream_Pointer(s), nla->identity->PasswordLength); Stream_Seek(s, nla->identity->PasswordLength); nla->identity->PasswordLength /= 2; @@ -1158,21 +1163,23 @@ int nla_write_ts_password_creds(rdpNla* nla, wStream* s) int innerSize = nla_sizeof_ts_password_creds(nla); /* TSPasswordCreds (SEQUENCE) */ size += ber_write_sequence_tag(s, innerSize); + if (nla->identity) { /* [0] domainName (OCTET STRING) */ size += ber_write_sequence_octet_string( - s, 0, (BYTE*) nla->identity->Domain, - nla->identity->DomainLength * 2); + s, 0, (BYTE*) nla->identity->Domain, + nla->identity->DomainLength * 2); /* [1] userName (OCTET STRING) */ size += ber_write_sequence_octet_string( - s, 1, (BYTE*) nla->identity->User, - nla->identity->UserLength * 2); + s, 1, (BYTE*) nla->identity->User, + nla->identity->UserLength * 2); /* [2] password (OCTET STRING) */ size += ber_write_sequence_octet_string( - s, 2, (BYTE*) nla->identity->Password, - nla->identity->PasswordLength * 2); + s, 2, (BYTE*) nla->identity->Password, + nla->identity->PasswordLength * 2); } + return size; } @@ -1191,7 +1198,6 @@ static BOOL nla_read_ts_credentials(rdpNla* nla, PSecBuffer ts_credentials) int length; int ts_password_creds_length; BOOL ret; - s = Stream_New(ts_credentials->pvBuffer, ts_credentials->cbBuffer); if (!s) @@ -1200,17 +1206,15 @@ static BOOL nla_read_ts_credentials(rdpNla* nla, PSecBuffer ts_credentials) return FALSE; } - - /* TSCredentials (SEQUENCE) */ + /* TSCredentials (SEQUENCE) */ ret = ber_read_sequence_tag(s, &length) && - /* [0] credType (INTEGER) */ - ber_read_contextual_tag(s, 0, &length, TRUE) && - ber_read_integer(s, NULL) && - /* [1] credentials (OCTET STRING) */ - ber_read_contextual_tag(s, 1, &length, TRUE) && - ber_read_octet_string_tag(s, &ts_password_creds_length) && - nla_read_ts_password_creds(nla, s); - + /* [0] credType (INTEGER) */ + ber_read_contextual_tag(s, 0, &length, TRUE) && + ber_read_integer(s, NULL) && + /* [1] credentials (OCTET STRING) */ + ber_read_contextual_tag(s, 1, &length, TRUE) && + ber_read_octet_string_tag(s, &ts_password_creds_length) && + nla_read_ts_password_creds(nla, s); Stream_Free(s, FALSE); return ret; } @@ -1220,20 +1224,16 @@ int nla_write_ts_credentials(rdpNla* nla, wStream* s) int size = 0; int passwordSize; int innerSize = nla_sizeof_ts_credentials(nla); - /* TSCredentials (SEQUENCE) */ size += ber_write_sequence_tag(s, innerSize); - /* [0] credType (INTEGER) */ size += ber_write_contextual_tag(s, 0, ber_sizeof_integer(1), TRUE); size += ber_write_integer(s, 1); - /* [1] credentials (OCTET STRING) */ passwordSize = ber_sizeof_sequence(nla_sizeof_ts_password_creds(nla)); size += ber_write_contextual_tag(s, 1, ber_sizeof_octet_string(passwordSize), TRUE); size += ber_write_octet_string_tag(s, passwordSize); size += nla_write_ts_password_creds(nla, s); - return size; } @@ -1265,11 +1265,13 @@ BOOL nla_encode_ts_credentials(rdpNla* nla) } length = ber_sizeof_sequence(nla_sizeof_ts_credentials(nla)); + if (!sspi_SecBufferAlloc(&nla->tsCredentials, length)) { WLog_ERR(TAG, "sspi_SecBufferAlloc failed!"); return FALSE; } + s = Stream_New((BYTE*) nla->tsCredentials.pvBuffer, length); if (!s) @@ -1301,34 +1303,35 @@ SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla) if (!nla_encode_ts_credentials(nla)) return SEC_E_INSUFFICIENT_MEMORY; - if (!sspi_SecBufferAlloc(&nla->authInfo, nla->ContextSizes.cbSecurityTrailer + nla->tsCredentials.cbBuffer)) + if (!sspi_SecBufferAlloc(&nla->authInfo, + nla->ContextSizes.cbSecurityTrailer + nla->tsCredentials.cbBuffer)) return SEC_E_INSUFFICIENT_MEMORY; - Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */ + + Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */ Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer; Buffers[0].pvBuffer = nla->authInfo.pvBuffer; ZeroMemory(Buffers[0].pvBuffer, Buffers[0].cbBuffer); - Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */ Buffers[1].cbBuffer = nla->tsCredentials.cbBuffer; Buffers[1].pvBuffer = &((BYTE*) nla->authInfo.pvBuffer)[Buffers[0].cbBuffer]; CopyMemory(Buffers[1].pvBuffer, nla->tsCredentials.pvBuffer, Buffers[1].cbBuffer); - Message.cBuffers = 2; Message.ulVersion = SECBUFFER_VERSION; Message.pBuffers = (PSecBuffer) &Buffers; - status = nla->table->EncryptMessage(&nla->context, 0, &Message, nla->sendSeqNum++); if (status != SEC_E_OK) { WLog_ERR(TAG, "EncryptMessage failure %s [0x%08"PRIX32"]", - GetSecurityStatusString(status), status); + GetSecurityStatusString(status), status); return status; } - if (Buffers[0].cbBuffer < nla->ContextSizes.cbSecurityTrailer) { + if (Buffers[0].cbBuffer < nla->ContextSizes.cbSecurityTrailer) + { /* EncryptMessage may not use all the signature space, so we need to shrink the excess */ - MoveMemory(((BYTE*)nla->authInfo.pvBuffer) + Buffers[0].cbBuffer, Buffers[1].pvBuffer, Buffers[1].cbBuffer); + MoveMemory(((BYTE*)nla->authInfo.pvBuffer) + Buffers[0].cbBuffer, Buffers[1].pvBuffer, + Buffers[1].cbBuffer); nla->authInfo.cbBuffer = Buffers[0].cbBuffer + Buffers[1].cbBuffer; } @@ -1371,17 +1374,17 @@ SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla) if (status != SEC_E_OK) { WLog_ERR(TAG, "DecryptMessage failure %s [0x%08"PRIX32"]", - GetSecurityStatusString(status), status); + GetSecurityStatusString(status), status); return status; } - if(!nla_read_ts_credentials(nla, &Buffers[1])) + if (!nla_read_ts_credentials(nla, &Buffers[1])) { free(buffer); return SEC_E_INSUFFICIENT_MEMORY; } - free(buffer); + free(buffer); return SEC_E_OK; } @@ -1440,8 +1443,10 @@ BOOL nla_send(rdpNla* nla) if (nla->version < 3 || nla->errorCode == 0) { - nego_tokens_length = (nla->negoToken.cbBuffer > 0) ? nla_sizeof_nego_tokens(nla->negoToken.cbBuffer) : 0; - pub_key_auth_length = (nla->pubKeyAuth.cbBuffer > 0) ? nla_sizeof_pub_key_auth(nla->pubKeyAuth.cbBuffer) : 0; + nego_tokens_length = (nla->negoToken.cbBuffer > 0) ? nla_sizeof_nego_tokens( + nla->negoToken.cbBuffer) : 0; + pub_key_auth_length = (nla->pubKeyAuth.cbBuffer > 0) ? nla_sizeof_pub_key_auth( + nla->pubKeyAuth.cbBuffer) : 0; auth_info_length = (nla->authInfo.cbBuffer > 0) ? nla_sizeof_auth_info(nla->authInfo.cbBuffer) : 0; } else @@ -1449,9 +1454,10 @@ BOOL nla_send(rdpNla* nla) error_code_length = ber_sizeof_integer(nla->errorCode); error_code_context_length = ber_sizeof_contextual_tag(error_code_length); } - length = nego_tokens_length + pub_key_auth_length + auth_info_length + error_code_context_length + error_code_length; - ts_request_length = nla_sizeof_ts_request(length); + length = nego_tokens_length + pub_key_auth_length + auth_info_length + error_code_context_length + + error_code_length; + ts_request_length = nla_sizeof_ts_request(length); s = Stream_New(NULL, ber_sizeof_sequence(ts_request_length)); if (!s) @@ -1460,7 +1466,6 @@ BOOL nla_send(rdpNla* nla) return FALSE; } - /* TSRequest */ ber_write_sequence_tag(s, ts_request_length); /* SEQUENCE */ /* [0] version */ @@ -1470,25 +1475,37 @@ BOOL nla_send(rdpNla* nla) /* [1] negoTokens (NegoData) */ if (nego_tokens_length > 0) { - length = nego_tokens_length; - length -= ber_write_contextual_tag(s, 1, ber_sizeof_sequence(ber_sizeof_sequence(ber_sizeof_sequence_octet_string(nla->negoToken.cbBuffer))), TRUE); /* NegoData */ - length -= ber_write_sequence_tag(s, ber_sizeof_sequence(ber_sizeof_sequence_octet_string(nla->negoToken.cbBuffer))); /* SEQUENCE OF NegoDataItem */ - length -= ber_write_sequence_tag(s, ber_sizeof_sequence_octet_string(nla->negoToken.cbBuffer)); /* NegoDataItem */ - length -= ber_write_sequence_octet_string(s, 0, (BYTE*) nla->negoToken.pvBuffer, nla->negoToken.cbBuffer); /* OCTET STRING */ + int length = ber_write_contextual_tag(s, 1, + ber_sizeof_sequence(ber_sizeof_sequence(ber_sizeof_sequence_octet_string(nla->negoToken.cbBuffer))), + TRUE); /* NegoData */ + length += ber_write_sequence_tag(s, + ber_sizeof_sequence(ber_sizeof_sequence_octet_string( + nla->negoToken.cbBuffer))); /* SEQUENCE OF NegoDataItem */ + length += ber_write_sequence_tag(s, + ber_sizeof_sequence_octet_string(nla->negoToken.cbBuffer)); /* NegoDataItem */ + length += ber_write_sequence_octet_string(s, 0, (BYTE*) nla->negoToken.pvBuffer, + nla->negoToken.cbBuffer); /* OCTET STRING */ + + if (length != nego_tokens_length) + return FALSE; } /* [2] authInfo (OCTET STRING) */ if (auth_info_length > 0) { length = auth_info_length; - length -= ber_write_sequence_octet_string(s, 2, nla->authInfo.pvBuffer, nla->authInfo.cbBuffer); + + if (ber_write_sequence_octet_string(s, 2, nla->authInfo.pvBuffer, + nla->authInfo.cbBuffer) != auth_info_length) + return FALSE; } /* [3] pubKeyAuth (OCTET STRING) */ if (pub_key_auth_length > 0) { - length = pub_key_auth_length; - length -= ber_write_sequence_octet_string(s, 3, nla->pubKeyAuth.pvBuffer, nla->pubKeyAuth.cbBuffer); + if (ber_write_sequence_octet_string(s, 3, nla->pubKeyAuth.pvBuffer, + nla->pubKeyAuth.cbBuffer) != pub_key_auth_length) + return FALSE; } /* [4] errorCode (INTEGER) */ @@ -1510,8 +1527,8 @@ int nla_decode_ts_request(rdpNla* nla, wStream* s) /* TSRequest */ if (!ber_read_sequence_tag(s, &length) || - !ber_read_contextual_tag(s, 0, &length, TRUE) || - !ber_read_integer(s, &nla->version)) + !ber_read_contextual_tag(s, 0, &length, TRUE) || + !ber_read_integer(s, &nla->version)) { return -1; } @@ -1520,10 +1537,10 @@ int nla_decode_ts_request(rdpNla* nla, wStream* s) if (ber_read_contextual_tag(s, 1, &length, TRUE) != FALSE) { if (!ber_read_sequence_tag(s, &length) || /* SEQUENCE OF NegoDataItem */ - !ber_read_sequence_tag(s, &length) || /* NegoDataItem */ - !ber_read_contextual_tag(s, 0, &length, TRUE) || /* [0] negoToken */ - !ber_read_octet_string_tag(s, &length) || /* OCTET STRING */ - ((int) Stream_GetRemainingLength(s)) < length) + !ber_read_sequence_tag(s, &length) || /* NegoDataItem */ + !ber_read_contextual_tag(s, 0, &length, TRUE) || /* [0] negoToken */ + !ber_read_octet_string_tag(s, &length) || /* OCTET STRING */ + ((int) Stream_GetRemainingLength(s)) < length) { return -1; } @@ -1539,7 +1556,7 @@ int nla_decode_ts_request(rdpNla* nla, wStream* s) if (ber_read_contextual_tag(s, 2, &length, TRUE) != FALSE) { if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */ - ((int) Stream_GetRemainingLength(s)) < length) + ((int) Stream_GetRemainingLength(s)) < length) return -1; if (!sspi_SecBufferAlloc(&nla->authInfo, length)) @@ -1553,7 +1570,7 @@ int nla_decode_ts_request(rdpNla* nla, wStream* s) if (ber_read_contextual_tag(s, 3, &length, TRUE) != FALSE) { if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */ - ((int) Stream_GetRemainingLength(s)) < length) + ((int) Stream_GetRemainingLength(s)) < length) return -1; if (!sspi_SecBufferAlloc(&nla->pubKeyAuth, length)) @@ -1598,7 +1615,6 @@ int nla_recv(rdpNla* nla) { wStream* s; int status; - s = Stream_New(NULL, 4096); if (!s) @@ -1668,6 +1684,7 @@ LPTSTR nla_make_spn(const char* ServiceClass, const char* hostname) hostnameX = _strdup(hostname); ServiceClassX = _strdup(ServiceClass); #endif + if (!hostnameX || !ServiceClassX) { free(hostnameX); @@ -1769,14 +1786,14 @@ rdpNla* nla_new(freerdp* instance, rdpTransport* transport, rdpSettings* setting HKEY hKey; DWORD dwType; DWORD dwSize; - status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, SERVER_KEY, - 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + 0, KEY_READ | KEY_WOW64_64KEY, &hKey); if (status != ERROR_SUCCESS) return nla; status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType, NULL, &dwSize); + if (status != ERROR_SUCCESS) { RegCloseKey(hKey); @@ -1784,6 +1801,7 @@ rdpNla* nla_new(freerdp* instance, rdpTransport* transport, rdpSettings* setting } nla->SspiModule = (LPTSTR) malloc(dwSize + sizeof(TCHAR)); + if (!nla->SspiModule) { RegCloseKey(hKey); @@ -1792,7 +1810,7 @@ rdpNla* nla_new(freerdp* instance, rdpTransport* transport, rdpSettings* setting } status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType, - (BYTE*) nla->SspiModule, &dwSize); + (BYTE*) nla->SspiModule, &dwSize); if (status == ERROR_SUCCESS) WLog_INFO(TAG, "Using SSPI Module: %s", nla->SspiModule); @@ -1817,19 +1835,18 @@ void nla_free(rdpNla* nla) { SECURITY_STATUS status; status = nla->table->DeleteSecurityContext(&nla->context); + if (status != SEC_E_OK) { WLog_WARN(TAG, "DeleteSecurityContext status %s [0x%08"PRIX32"]", - GetSecurityStatusString(status), status); + GetSecurityStatusString(status), status); } } free(nla->SamFile); nla->SamFile = NULL; - sspi_SecBufferFree(&nla->PublicKey); sspi_SecBufferFree(&nla->tsCredentials); - free(nla->ServicePrincipalName); nla_identity_free(nla->identity); free(nla); diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index d20e40b..c9492ce 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -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) diff --git a/libfreerdp/core/proxy.c b/libfreerdp/core/proxy.c index ae6f16c..22462a7 100644 --- a/libfreerdp/core/proxy.c +++ b/libfreerdp/core/proxy.c @@ -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) diff --git a/libfreerdp/core/timezone.c b/libfreerdp/core/timezone.c index 0fc0776..982c577 100644 --- a/libfreerdp/core/timezone.c +++ b/libfreerdp/core/timezone.c @@ -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; } diff --git a/rdtk/librdtk/rdtk_font.c b/rdtk/librdtk/rdtk_font.c index b8d9575..7d341df 100644 --- a/rdtk/librdtk/rdtk_font.c +++ b/rdtk/librdtk/rdtk_font.c @@ -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, ""); if (!p) return -1; p += sizeof("") - 1; - p = strstr(p, ""); 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(""); 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(""); 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; diff --git a/rdtk/librdtk/rdtk_nine_patch.c b/rdtk/librdtk/rdtk_nine_patch.c index bd726c9..82a0914 100644 --- a/rdtk/librdtk/rdtk_nine_patch.c +++ b/rdtk/librdtk/rdtk_nine_patch.c @@ -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) diff --git a/server/shadow/X11/x11_shadow.c b/server/shadow/X11/x11_shadow.c index 8ea0eb6..6bd91b9 100644 --- a/server/shadow/X11/x11_shadow.c +++ b/server/shadow/X11/x11_shadow.c @@ -2,6 +2,8 @@ * FreeRDP: A Remote Desktop Protocol Implementation * * Copyright 2011-2014 Marc-Andre Moreau + * Copyright 2017 Armin Novak + * 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); - - if (count == 1) + region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), + &invalidRect); + region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), + &surfaceRect); + + 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 (!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 (client) + if (count == 1) { - subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder); + rdpShadowClient* client; + client = (rdpShadowClient*) ArrayList_GetItem(server->clients, 0); + + if (client) + subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder); } - } - region16_clear(&(surface->invalidRegion)); + 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; diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index 414df5c..6994769 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -2,6 +2,8 @@ * FreeRDP: A Remote Desktop Protocol Implementation * * Copyright 2014 Marc-Andre Moreau + * Copyright 2017 Armin Novak + * 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 */ diff --git a/server/shadow/shadow_server.c b/server/shadow/shadow_server.c index 9d92df4..2c0e0bf 100644 --- a/server/shadow/shadow_server.c +++ b/server/shadow/shadow_server.c @@ -2,6 +2,8 @@ * FreeRDP: A Remote Desktop Protocol Implementation * * Copyright 2014 Marc-Andre Moreau + * Copyright 2017 Armin Novak + * 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: (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"); + sprintf_s(str, length + 1, "%s (default:%s)", arg->Name, + 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); } diff --git a/server/shadow/shadow_subsystem_builtin.c b/server/shadow/shadow_subsystem_builtin.c index be143d7..8dbbe7e 100644 --- a/server/shadow/shadow_subsystem_builtin.c +++ b/server/shadow/shadow_subsystem_builtin.c @@ -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++) diff --git a/winpr/include/winpr/stream.h b/winpr/include/winpr/stream.h index 7571a13..730540e 100644 --- a/winpr/include/winpr/stream.h +++ b/winpr/include/winpr/stream.h @@ -4,6 +4,8 @@ * * Copyright 2011 Vic Lee * Copyright 2012 Marc-Andre Moreau + * Copyright 2017 Armin Novak + * 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; } diff --git a/winpr/libwinpr/crt/utf.c b/winpr/libwinpr/crt/utf.c index abf4bfc..65e2738 100644 --- a/winpr/libwinpr/crt/utf.c +++ b/winpr/libwinpr/crt/utf.c @@ -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; } diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 799ae94..f52d80b 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -3,6 +3,8 @@ * Pipe Functions * * Copyright 2012 Marc-Andre Moreau + * Copyright 2017 Armin Novak + * 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); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_message.c b/winpr/libwinpr/sspi/NTLM/ntlm_message.c index 637ebe9..96e8e96 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_message.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_message.c @@ -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) { diff --git a/winpr/libwinpr/sspi/Schannel/schannel_openssl.c b/winpr/libwinpr/sspi/Schannel/schannel_openssl.c index f005adb..24a2cc3 100644 --- a/winpr/libwinpr/sspi/Schannel/schannel_openssl.c +++ b/winpr/libwinpr/sspi/Schannel/schannel_openssl.c @@ -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 diff --git a/winpr/libwinpr/synch/event.c b/winpr/libwinpr/synch/event.c index 976efc1..9f7c168 100644 --- a/winpr/libwinpr/synch/event.c +++ b/winpr/libwinpr/synch/event.c @@ -3,6 +3,8 @@ * Synchronization Functions * * Copyright 2012 Marc-Andre Moreau + * Copyright 2017 Armin Novak + * 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; diff --git a/winpr/libwinpr/thread/argv.c b/winpr/libwinpr/thread/argv.c index 823858f..cdef7d2 100644 --- a/winpr/libwinpr/thread/argv.c +++ b/winpr/libwinpr/thread/argv.c @@ -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; } diff --git a/winpr/libwinpr/utils/image.c b/winpr/libwinpr/utils/image.c index ece3867..8370515 100644 --- a/winpr/libwinpr/utils/image.c +++ b/winpr/libwinpr/utils/image.c @@ -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]); diff --git a/winpr/libwinpr/utils/ini.c b/winpr/libwinpr/utils/ini.c index a464e0a..9cad4d3 100644 --- a/winpr/libwinpr/utils/ini.c +++ b/winpr/libwinpr/utils/ini.c @@ -713,7 +713,6 @@ char* IniFile_WriteBuffer(wIniFile* ini) } buffer[offset] = '\0'; - size += 1; return buffer; } diff --git a/winpr/libwinpr/utils/wlog/Layout.c b/winpr/libwinpr/utils/wlog/Layout.c index 0232042..73d1844 100644 --- a/winpr/libwinpr/utils/wlog/Layout.c +++ b/winpr/libwinpr/utils/wlog/Layout.c @@ -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';