diff --git a/CMakeLists.txt b/CMakeLists.txt index 22c361b1a..ca6e154b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,15 +76,7 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Default to release build type if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release") -endif() - -if(NOT DEFINED WITH_CLIENT_INTERFACE) - set(WITH_CLIENT_INTERFACE ON) -endif() - -if(NOT DEFINED WITH_SERVER_INTERFACE) - set(WITH_SERVER_INTERFACE ON) + set(CMAKE_BUILD_TYPE "Release") endif() if(NOT DEFINED BUILD_SHARED_LIBS) @@ -120,7 +112,9 @@ endif() # Compiler-specific flags if(CMAKE_COMPILER_IS_GNUCC) if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "i686") - if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686") endif() endif() @@ -151,14 +145,17 @@ if(CMAKE_COMPILER_IS_GNUCC) set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") endif() - if(${CMAKE_VERSION} VERSION_LESS 2.8.8) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - endif() if(WITH_SSE2) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2") endif() endif() +if(CMAKE_COMPILER_IS_CLANG) + if(WITH_SSE2) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mssse3") + endif() +endif() + if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MT") @@ -224,7 +221,7 @@ if(APPLE) include_directories(/opt/local/include) link_directories(/opt/local/lib) endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.4") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.5") endif() if(WITH_CLANG) set(CMAKE_C_COMPILER "clang") @@ -246,6 +243,7 @@ if(ANDROID) endif() set(CMAKE_THREAD_PREFER_PTHREAD TRUE) + if(NOT IOS AND NOT ANDROID) find_package(Threads REQUIRED) endif() @@ -300,6 +298,10 @@ set(IPP_FEATURE_TYPE "OPTIONAL") set(IPP_FEATURE_PURPOSE "performance") set(IPP_FEATURE_DESCRIPTION "Intel Integrated Performance Primitives library") +set(NPP_FEATURE_TYPE "OPTIONAL") +set(NPP_FEATURE_PURPOSE "performance") +set(NPP_FEATURE_DESCRIPTION "NVIDIA Performance Primitives library") + if(WIN32) set(X11_FEATURE_TYPE "DISABLED") set(ZLIB_FEATURE_TYPE "DISABLED") @@ -316,8 +318,8 @@ if(APPLE) set(DIRECTFB_FEATURE_TYPE "DISABLED") set(FFMPEG_FEATURE_TYPE "OPTIONAL") set(GSTREAMER_FEATURE_TYPE "OPTIONAL") + set(X11_FEATURE_TYPE "DISABLED") if(IOS) - set(X11_FEATURE_TYPE "DISABLED") set(ALSA_FEATURE_TYPE "DISABLED") set(PULSE_FEATURE_TYPE "DISABLED") set(CUPS_FEATURE_TYPE "DISABLED") @@ -358,6 +360,7 @@ if(TARGET_ARCH MATCHES "x86|x64") # Intel Performance Primitives find_feature(IPP ${IPP_FEATURE_TYPE} ${IPP_FEATURE_PURPOSE} ${IPP_FEATURE_DESCRIPTION}) endif() + find_feature(NPP ${NPP_FEATURE_TYPE} ${NPP_FEATURE_PURPOSE} ${NPP_FEATURE_DESCRIPTION}) endif() # Installation Paths @@ -444,9 +447,10 @@ if(WITH_CHANNELS) endif() if (IOS) -set(CMAKE_OSX_DEPLOYMENT_TARGET "") -set(CMAKE_OSX_SYSROOT "iphoneos") + set(CMAKE_OSX_DEPLOYMENT_TARGET "") + set(CMAKE_OSX_SYSROOT "iphoneos") endif() + if(WITH_CLIENT) add_subdirectory(client) endif() @@ -478,7 +482,6 @@ if(NOT WIN32) endif() endif() - endif() set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") @@ -557,10 +560,9 @@ set(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION "Development") # problems when compiling freerdp/jni. To prevent this problem # we set the macros to "". if (ANDROID AND CMAKE_EXTRA_GENERATOR STREQUAL "Eclipse CDT4") - set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS "") - message(STATUS "Disabled CXX system defines for eclipse (workaround).") + set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS "") + message(STATUS "Disabled CXX system defines for eclipse (workaround).") endif() - - include(CPack) + diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index 428684519..1b1604490 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -94,15 +94,15 @@ static int audin_process_version(IWTSVirtualChannelCallback* pChannelCallback, w UINT32 Version; AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; - stream_read_UINT32(s, Version); + Stream_Read_UINT32(s, Version); DEBUG_DVC("Version=%d", Version); - out = stream_new(5); - stream_write_BYTE(out, MSG_SNDIN_VERSION); - stream_write_UINT32(out, Version); - error = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL); - stream_free(out); + out = Stream_New(NULL, 5); + Stream_Write_UINT8(out, MSG_SNDIN_VERSION); + Stream_Write_UINT32(out, Version); + error = callback->channel->Write(callback->channel, Stream_GetPosition(s), Stream_Buffer(s), NULL); + Stream_Free(out, TRUE); return error; } @@ -128,34 +128,34 @@ static int audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, w audinFormat format; UINT32 cbSizeFormatsPacket; - stream_read_UINT32(s, NumFormats); + Stream_Read_UINT32(s, NumFormats); DEBUG_DVC("NumFormats %d", NumFormats); if ((NumFormats < 1) || (NumFormats > 1000)) { DEBUG_WARN("bad NumFormats %d", NumFormats); return 1; } - stream_seek_UINT32(s); /* cbSizeFormatsPacket */ + Stream_Seek_UINT32(s); /* cbSizeFormatsPacket */ callback->formats = (audinFormat*) malloc(NumFormats * sizeof(audinFormat)); ZeroMemory(callback->formats, NumFormats * sizeof(audinFormat)); - out = stream_new(9); - stream_seek(out, 9); + out = Stream_New(NULL, 9); + Stream_Seek(out, 9); /* SoundFormats (variable) */ for (i = 0; i < NumFormats; i++) { - stream_get_mark(s, fm); - stream_read_UINT16(s, format.wFormatTag); - stream_read_UINT16(s, format.nChannels); - stream_read_UINT32(s, format.nSamplesPerSec); - stream_seek_UINT32(s); /* nAvgBytesPerSec */ - stream_read_UINT16(s, format.nBlockAlign); - stream_read_UINT16(s, format.wBitsPerSample); - stream_read_UINT16(s, format.cbSize); - format.data = stream_get_tail(s); - stream_seek(s, format.cbSize); + Stream_GetPointer(s, fm); + Stream_Read_UINT16(s, format.wFormatTag); + Stream_Read_UINT16(s, format.nChannels); + Stream_Read_UINT32(s, format.nSamplesPerSec); + Stream_Seek_UINT32(s); /* nAvgBytesPerSec */ + Stream_Read_UINT16(s, format.nBlockAlign); + Stream_Read_UINT16(s, format.wBitsPerSample); + Stream_Read_UINT16(s, format.cbSize); + format.data = Stream_Pointer(s); + Stream_Seek(s, format.cbSize); DEBUG_DVC("wFormatTag=%d nChannels=%d nSamplesPerSec=%d " "nBlockAlign=%d wBitsPerSample=%d cbSize=%d", @@ -175,22 +175,22 @@ static int audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, w /* Store the agreed format in the corresponding index */ callback->formats[callback->formats_count++] = format; /* Put the format to output buffer */ - stream_check_size(out, 18 + format.cbSize); - stream_write(out, fm, 18 + format.cbSize); + Stream_EnsureRemainingCapacity(out, 18 + format.cbSize); + Stream_Write(out, fm, 18 + format.cbSize); } } audin_send_incoming_data_pdu(pChannelCallback); - cbSizeFormatsPacket = stream_get_pos(out); - stream_set_pos(out, 0); + cbSizeFormatsPacket = Stream_GetPosition(out); + Stream_SetPosition(out, 0); - stream_write_BYTE(out, MSG_SNDIN_FORMATS); /* Header (1 byte) */ - stream_write_UINT32(out, callback->formats_count); /* NumFormats (4 bytes) */ - stream_write_UINT32(out, cbSizeFormatsPacket); /* cbSizeFormatsPacket (4 bytes) */ + Stream_Write_UINT8(out, MSG_SNDIN_FORMATS); /* Header (1 byte) */ + Stream_Write_UINT32(out, callback->formats_count); /* NumFormats (4 bytes) */ + Stream_Write_UINT32(out, cbSizeFormatsPacket); /* cbSizeFormatsPacket (4 bytes) */ - error = callback->channel->Write(callback->channel, cbSizeFormatsPacket, stream_get_head(out), NULL); - stream_free(out); + error = callback->channel->Write(callback->channel, cbSizeFormatsPacket, Stream_Buffer(out), NULL); + Stream_Free(out, TRUE); return error; } @@ -201,11 +201,11 @@ static int audin_send_format_change_pdu(IWTSVirtualChannelCallback* pChannelCall wStream* out; AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; - out = stream_new(5); - stream_write_BYTE(out, MSG_SNDIN_FORMATCHANGE); - stream_write_UINT32(out, NewFormat); - error = callback->channel->Write(callback->channel, 5, stream_get_head(out), NULL); - stream_free(out); + out = Stream_New(NULL, 5); + Stream_Write_UINT8(out, MSG_SNDIN_FORMATCHANGE); + Stream_Write_UINT32(out, NewFormat); + error = callback->channel->Write(callback->channel, 5, Stream_Buffer(out), NULL); + Stream_Free(out, TRUE); return error; } @@ -216,11 +216,11 @@ static int audin_send_open_reply_pdu(IWTSVirtualChannelCallback* pChannelCallbac wStream* out; AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; - out = stream_new(5); - stream_write_BYTE(out, MSG_SNDIN_OPEN_REPLY); - stream_write_UINT32(out, Result); - error = callback->channel->Write(callback->channel, 5, stream_get_head(out), NULL); - stream_free(out); + out = Stream_New(NULL, 5); + Stream_Write_UINT8(out, MSG_SNDIN_OPEN_REPLY); + Stream_Write_UINT32(out, Result); + error = callback->channel->Write(callback->channel, 5, Stream_Buffer(out), NULL); + Stream_Free(out, TRUE); return error; } @@ -236,11 +236,11 @@ static BOOL audin_receive_wave_data(BYTE* data, int size, void* user_data) if (error != 0) return FALSE; - out = stream_new(size + 1); - stream_write_BYTE(out, MSG_SNDIN_DATA); - stream_write(out, data, size); - error = callback->channel->Write(callback->channel, stream_get_length(out), stream_get_head(out), NULL); - stream_free(out); + out = Stream_New(NULL, size + 1); + Stream_Write_UINT8(out, MSG_SNDIN_DATA); + Stream_Write(out, data, size); + error = callback->channel->Write(callback->channel, Stream_GetPosition(out), Stream_Buffer(out), NULL); + Stream_Free(out, TRUE); return (error == 0 ? TRUE : FALSE); } @@ -253,8 +253,8 @@ static int audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wStr UINT32 initialFormat; UINT32 FramesPerPacket; - stream_read_UINT32(s, FramesPerPacket); - stream_read_UINT32(s, initialFormat); + Stream_Read_UINT32(s, FramesPerPacket); + Stream_Read_UINT32(s, initialFormat); DEBUG_DVC("FramesPerPacket=%d initialFormat=%d", FramesPerPacket, initialFormat); @@ -286,7 +286,7 @@ static int audin_process_format_change(IWTSVirtualChannelCallback* pChannelCallb UINT32 NewFormat; audinFormat* format; - stream_read_UINT32(s, NewFormat); + Stream_Read_UINT32(s, NewFormat); DEBUG_DVC("NewFormat=%d", NewFormat); @@ -317,10 +317,9 @@ static int audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream* s; BYTE MessageId; - s = stream_new(0); - stream_attach(s, pBuffer, cbSize); + s = Stream_New(pBuffer, cbSize); - stream_read_BYTE(s, MessageId); + Stream_Read_UINT8(s, MessageId); DEBUG_DVC("MessageId=0x%x", MessageId); @@ -348,8 +347,7 @@ static int audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, break; } - stream_detach(s); - stream_free(s); + Stream_Free(s, FALSE); return error; } diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index 75a143fda..564630d8c 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -76,9 +76,9 @@ static void audin_server_select_format(audin_server_context* context, int client static void audin_server_send_version(audin_server* audin, wStream* s) { - stream_write_BYTE(s, MSG_SNDIN_VERSION); - stream_write_UINT32(s, 1); /* Version (4 bytes) */ - WTSVirtualChannelWrite(audin->audin_channel, stream_get_head(s), stream_get_length(s), NULL); + Stream_Write_UINT8(s, MSG_SNDIN_VERSION); + Stream_Write_UINT32(s, 1); /* Version (4 bytes) */ + WTSVirtualChannelWrite(audin->audin_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); } static BOOL audin_server_recv_version(audin_server* audin, wStream* s, UINT32 length) @@ -88,7 +88,7 @@ static BOOL audin_server_recv_version(audin_server* audin, wStream* s, UINT32 le if (length < 4) return FALSE; - stream_read_UINT32(s, Version); + Stream_Read_UINT32(s, Version); if (Version < 1) return FALSE; @@ -101,33 +101,36 @@ static void audin_server_send_formats(audin_server* audin, wStream* s) int i; UINT32 nAvgBytesPerSec; - stream_set_pos(s, 0); - stream_write_BYTE(s, MSG_SNDIN_FORMATS); - stream_write_UINT32(s, audin->context.num_server_formats); /* NumFormats (4 bytes) */ - stream_write_UINT32(s, 0); /* cbSizeFormatsPacket (4 bytes), client-to-server only */ + Stream_SetPosition(s, 0); + Stream_Write_UINT8(s, MSG_SNDIN_FORMATS); + Stream_Write_UINT32(s, audin->context.num_server_formats); /* NumFormats (4 bytes) */ + Stream_Write_UINT32(s, 0); /* cbSizeFormatsPacket (4 bytes), client-to-server only */ for (i = 0; i < audin->context.num_server_formats; i++) { nAvgBytesPerSec = audin->context.server_formats[i].nSamplesPerSec * audin->context.server_formats[i].nChannels * audin->context.server_formats[i].wBitsPerSample / 8; - stream_check_size(s, 18); - stream_write_UINT16(s, audin->context.server_formats[i].wFormatTag); - stream_write_UINT16(s, audin->context.server_formats[i].nChannels); - stream_write_UINT32(s, audin->context.server_formats[i].nSamplesPerSec); - stream_write_UINT32(s, nAvgBytesPerSec); - stream_write_UINT16(s, audin->context.server_formats[i].nBlockAlign); - stream_write_UINT16(s, audin->context.server_formats[i].wBitsPerSample); - stream_write_UINT16(s, audin->context.server_formats[i].cbSize); + + Stream_EnsureRemainingCapacity(s, 18); + + Stream_Write_UINT16(s, audin->context.server_formats[i].wFormatTag); + Stream_Write_UINT16(s, audin->context.server_formats[i].nChannels); + Stream_Write_UINT32(s, audin->context.server_formats[i].nSamplesPerSec); + Stream_Write_UINT32(s, nAvgBytesPerSec); + Stream_Write_UINT16(s, audin->context.server_formats[i].nBlockAlign); + Stream_Write_UINT16(s, audin->context.server_formats[i].wBitsPerSample); + Stream_Write_UINT16(s, audin->context.server_formats[i].cbSize); + if (audin->context.server_formats[i].cbSize) { - stream_check_size(s, audin->context.server_formats[i].cbSize); - stream_write(s, audin->context.server_formats[i].data, + Stream_EnsureRemainingCapacity(s, audin->context.server_formats[i].cbSize); + Stream_Write(s, audin->context.server_formats[i].data, audin->context.server_formats[i].cbSize); } } - WTSVirtualChannelWrite(audin->audin_channel, stream_get_head(s), stream_get_length(s), NULL); + WTSVirtualChannelWrite(audin->audin_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); } static BOOL audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 length) @@ -137,8 +140,8 @@ static BOOL audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 le if (length < 8) return FALSE; - stream_read_UINT32(s, audin->context.num_client_formats); /* NumFormats (4 bytes) */ - stream_seek_UINT32(s); /* cbSizeFormatsPacket (4 bytes) */ + Stream_Read_UINT32(s, audin->context.num_client_formats); /* NumFormats (4 bytes) */ + Stream_Seek_UINT32(s); /* cbSizeFormatsPacket (4 bytes) */ length -= 8; if (audin->context.num_client_formats <= 0) @@ -156,16 +159,16 @@ static BOOL audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 le return FALSE; } - stream_read_UINT16(s, audin->context.client_formats[i].wFormatTag); - stream_read_UINT16(s, audin->context.client_formats[i].nChannels); - stream_read_UINT32(s, audin->context.client_formats[i].nSamplesPerSec); - stream_seek_UINT32(s); /* nAvgBytesPerSec */ - stream_read_UINT16(s, audin->context.client_formats[i].nBlockAlign); - stream_read_UINT16(s, audin->context.client_formats[i].wBitsPerSample); - stream_read_UINT16(s, audin->context.client_formats[i].cbSize); + Stream_Read_UINT16(s, audin->context.client_formats[i].wFormatTag); + Stream_Read_UINT16(s, audin->context.client_formats[i].nChannels); + Stream_Read_UINT32(s, audin->context.client_formats[i].nSamplesPerSec); + Stream_Seek_UINT32(s); /* nAvgBytesPerSec */ + Stream_Read_UINT16(s, audin->context.client_formats[i].nBlockAlign); + Stream_Read_UINT16(s, audin->context.client_formats[i].wBitsPerSample); + Stream_Read_UINT16(s, audin->context.client_formats[i].cbSize); if (audin->context.client_formats[i].cbSize > 0) { - stream_seek(s, audin->context.client_formats[i].cbSize); + Stream_Seek(s, audin->context.client_formats[i].cbSize); } } @@ -181,24 +184,24 @@ static void audin_server_send_open(audin_server* audin, wStream* s) audin->opened = TRUE; - stream_set_pos(s, 0); - stream_write_BYTE(s, MSG_SNDIN_OPEN); - stream_write_UINT32(s, audin->context.frames_per_packet); /* FramesPerPacket (4 bytes) */ - stream_write_UINT32(s, audin->context.selected_client_format); /* initialFormat (4 bytes) */ + Stream_SetPosition(s, 0); + Stream_Write_UINT8(s, MSG_SNDIN_OPEN); + Stream_Write_UINT32(s, audin->context.frames_per_packet); /* FramesPerPacket (4 bytes) */ + Stream_Write_UINT32(s, audin->context.selected_client_format); /* initialFormat (4 bytes) */ /* * [MS-RDPEAI] 3.2.5.1.6 * The second format specify the format that SHOULD be used to capture data from * the actual audio input device. */ - stream_write_UINT16(s, 1); /* wFormatTag = PCM */ - stream_write_UINT16(s, 2); /* nChannels */ - stream_write_UINT32(s, 44100); /* nSamplesPerSec */ - stream_write_UINT32(s, 44100 * 2 * 2); /* nAvgBytesPerSec */ - stream_write_UINT16(s, 4); /* nBlockAlign */ - stream_write_UINT16(s, 16); /* wBitsPerSample */ - stream_write_UINT16(s, 0); /* cbSize */ + Stream_Write_UINT16(s, 1); /* wFormatTag = PCM */ + Stream_Write_UINT16(s, 2); /* nChannels */ + Stream_Write_UINT32(s, 44100); /* nSamplesPerSec */ + Stream_Write_UINT32(s, 44100 * 2 * 2); /* nAvgBytesPerSec */ + Stream_Write_UINT16(s, 4); /* nBlockAlign */ + Stream_Write_UINT16(s, 16); /* wBitsPerSample */ + Stream_Write_UINT16(s, 0); /* cbSize */ - WTSVirtualChannelWrite(audin->audin_channel, stream_get_head(s), stream_get_length(s), NULL); + WTSVirtualChannelWrite(audin->audin_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); } static BOOL audin_server_recv_open_reply(audin_server* audin, wStream* s, UINT32 length) @@ -208,7 +211,7 @@ static BOOL audin_server_recv_open_reply(audin_server* audin, wStream* s, UINT32 if (length < 4) return FALSE; - stream_read_UINT32(s, Result); + Stream_Read_UINT32(s, Result); IFCALL(audin->context.OpenResult, &audin->context, Result); @@ -232,7 +235,7 @@ static BOOL audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt if (format->wFormatTag == WAVE_FORMAT_ADPCM) { audin->dsp_context->decode_ms_adpcm(audin->dsp_context, - stream_get_tail(s), length, format->nChannels, format->nBlockAlign); + Stream_Pointer(s), length, format->nChannels, format->nBlockAlign); size = audin->dsp_context->adpcm_size; src = audin->dsp_context->adpcm_buffer; sbytes_per_sample = 2; @@ -241,7 +244,7 @@ static BOOL audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt else if (format->wFormatTag == WAVE_FORMAT_DVI_ADPCM) { audin->dsp_context->decode_ima_adpcm(audin->dsp_context, - stream_get_tail(s), length, format->nChannels, format->nBlockAlign); + Stream_Pointer(s), length, format->nChannels, format->nBlockAlign); size = audin->dsp_context->adpcm_size; src = audin->dsp_context->adpcm_buffer; sbytes_per_sample = 2; @@ -250,7 +253,7 @@ static BOOL audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt else { size = length; - src = stream_get_tail(s); + src = Stream_Pointer(s); sbytes_per_sample = format->wBitsPerSample / 8; sbytes_per_frame = format->nChannels * sbytes_per_sample; } @@ -311,7 +314,7 @@ static void* audin_server_thread_func(void* arg) break; } - s = stream_new(4096); + s = Stream_New(NULL, 4096); if (ready) { @@ -325,25 +328,25 @@ static void* audin_server_thread_func(void* arg) if (WaitForSingleObject(audin->stopEvent, 0) == WAIT_OBJECT_0) break; - stream_set_pos(s, 0); + Stream_SetPosition(s, 0); - if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s), - stream_get_size(s), &bytes_returned) == FALSE) + if (WTSVirtualChannelRead(audin->audin_channel, 0, Stream_Buffer(s), + Stream_Capacity(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; - stream_check_size(s, (int) bytes_returned); + Stream_EnsureRemainingCapacity(s, (int) bytes_returned); - if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s), - stream_get_size(s), &bytes_returned) == FALSE) + if (WTSVirtualChannelRead(audin->audin_channel, 0, Stream_Buffer(s), + Stream_Capacity(s), &bytes_returned) == FALSE) break; } if (bytes_returned < 1) continue; - stream_read_BYTE(s, MessageId); + Stream_Read_UINT8(s, MessageId); bytes_returned--; switch (MessageId) @@ -378,7 +381,7 @@ static void* audin_server_thread_func(void* arg) } } - stream_free(s); + Stream_Free(s, TRUE); WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; diff --git a/channels/client/CMakeLists.txt b/channels/client/CMakeLists.txt index d1726657d..6aa60777a 100644 --- a/channels/client/CMakeLists.txt +++ b/channels/client/CMakeLists.txt @@ -23,7 +23,12 @@ set(${MODULE_PREFIX}_SRCS tables.h addin.c addin.h - channels.c) + init.c + init.h + open.c + open.h + channels.c + channels.h) list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES) diff --git a/channels/client/channels.c b/channels/client/channels.c index 82ee13e1c..a9ea2b0dc 100644 --- a/channels/client/channels.c +++ b/channels/client/channels.c @@ -44,14 +44,10 @@ #include #include "addin.h" +#include "init.h" +#include "open.h" -#ifdef WITH_DEBUG_CHANNELS -#define DEBUG_CHANNELS(fmt, ...) DEBUG_CLASS(CHANNELS, fmt, ## __VA_ARGS__) -#else -#define DEBUG_CHANNELS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) -#endif - -#define CHANNEL_MAX_COUNT 30 +#include "channels.h" /** * MS compatible plugin interface @@ -67,88 +63,23 @@ * from the main thread. */ -struct rdp_library_data -{ - PVIRTUALCHANNELENTRY entry; /* the one and only exported function */ - PCHANNEL_INIT_EVENT_FN init_event_proc; - void* init_handle; -}; -typedef struct rdp_library_data rdpLibraryData; - -struct rdp_channel_data -{ - char name[CHANNEL_NAME_LEN + 1]; - int open_handle; - int options; - int flags; /* 0 nothing 1 init 2 open */ - PCHANNEL_OPEN_EVENT_FN open_event_proc; -}; -typedef struct rdp_channel_data rdpChannelData; - -struct _CHANNEL_OPEN_EVENT -{ - void* Data; - UINT32 DataLength; - void* UserData; - int Index; -}; -typedef struct _CHANNEL_OPEN_EVENT CHANNEL_OPEN_EVENT; - -typedef struct rdp_init_handle rdpInitHandle; - -struct rdp_init_handle -{ - rdpChannels* channels; -}; - -struct rdp_channels -{ - /** - * Only the main thread alters these arrays, before any - * library thread is allowed in(post_connect is called) - * so no need to use mutex locking - * After post_connect, each library thread can only access it's - * own array items - * ie, no two threads can access index 0, ... - */ - - int libraryDataCount; - rdpLibraryData libraryDataList[CHANNEL_MAX_COUNT]; - - int channelDataCount; - rdpChannelData channelDataList[CHANNEL_MAX_COUNT]; - - int initHandleCount; - rdpInitHandle initHandleList[CHANNEL_MAX_COUNT]; - - /* control for entry into MyVirtualChannelInit */ - int can_call_init; - rdpSettings* settings; - - /* true once freerdp_channels_post_connect is called */ - int is_connected; - - /* used for locating the channels for a given instance */ - freerdp* instance; - - wMessagePipe* MsgPipe; -}; - /** * The current channel manager reference passes from VirtualChannelEntry to * VirtualChannelInit for the pInitHandle. */ -static rdpChannels* g_init_channels; + +void* g_pInterface; +CHANNEL_INIT_DATA g_ChannelInitData; static wArrayList* g_ChannelsList = NULL; /* To generate unique sequence for all open handles */ -static int g_open_handle_sequence; +int g_open_handle_sequence; /* For locking the global resources */ static HANDLE g_mutex_init; -static rdpChannels* freerdp_channels_find_by_open_handle(int open_handle, int* pindex) +rdpChannels* freerdp_channels_find_by_open_handle(int open_handle, int* pindex) { int i, j; BOOL found = FALSE; @@ -161,9 +92,9 @@ static rdpChannels* freerdp_channels_find_by_open_handle(int open_handle, int* p while (channels) { - for (j = 0; j < channels->channelDataCount; j++) + for (j = 0; j < channels->openDataCount; j++) { - if (channels->channelDataList[j].open_handle == open_handle) + if (channels->openDataList[j].OpenHandle == open_handle) { *pindex = j; found = TRUE; @@ -182,7 +113,7 @@ static rdpChannels* freerdp_channels_find_by_open_handle(int open_handle, int* p return (found) ? channels : NULL; } -static rdpChannels* freerdp_channels_find_by_instance(freerdp* instance) +rdpChannels* freerdp_channels_find_by_instance(freerdp* instance) { int index; BOOL found = FALSE; @@ -209,30 +140,24 @@ static rdpChannels* freerdp_channels_find_by_instance(freerdp* instance) return (found) ? channels : NULL; } -/* returns rdpChannelData for the channel name passed in */ -static rdpChannelData* freerdp_channels_find_channel_data_by_name(rdpChannels* channels, const char* channel_name, int* pindex) +CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name(rdpChannels* channels, const char* channel_name) { int index; - rdpChannelData* lchannel_data; + CHANNEL_OPEN_DATA* pChannelOpenData; - for (index = 0; index < channels->channelDataCount; index++) + for (index = 0; index < channels->openDataCount; index++) { - lchannel_data = &channels->channelDataList[index]; + pChannelOpenData = &channels->openDataList[index]; - if (strcmp(channel_name, lchannel_data->name) == 0) - { - if (pindex != 0) - *pindex = index; - - return lchannel_data; - } + if (strcmp(channel_name, pChannelOpenData->name) == 0) + return pChannelOpenData; } return NULL; } /* returns rdpChannel for the channel id passed in */ -static rdpChannel* freerdp_channels_find_channel_by_id(rdpChannels* channels, rdpSettings* settings, int channel_id, int* pindex) +rdpChannel* freerdp_channels_find_channel_by_id(rdpChannels* channels, rdpSettings* settings, int channel_id, int* pindex) { int index; int count; @@ -257,7 +182,7 @@ static rdpChannel* freerdp_channels_find_channel_by_id(rdpChannels* channels, rd } /* returns rdpChannel for the channel name passed in */ -static rdpChannel* freerdp_channels_find_channel_by_name(rdpChannels* channels, +rdpChannel* freerdp_channels_find_channel_by_name(rdpChannels* channels, rdpSettings* settings, const char* channel_name, int* pindex) { int index; @@ -282,204 +207,12 @@ static rdpChannel* freerdp_channels_find_channel_by_name(rdpChannels* channels, return NULL; } -/** - * must be called by same thread that calls freerdp_chanman_load_plugin - * according to MS docs - * only called from main thread - */ -static UINT32 FREERDP_CC MyVirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF pChannel, - int channelCount, UINT32 versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc) -{ - int index; - rdpChannel* channel; - rdpChannels* channels; - rdpLibraryData* llib; - PCHANNEL_DEF lchannel_def; - rdpChannelData* lchannel_data; - - if (!ppInitHandle) - { - DEBUG_CHANNELS("error bad init handle"); - return CHANNEL_RC_BAD_INIT_HANDLE; - } - - channels = g_init_channels; - - channels->initHandleList[channels->initHandleCount].channels = channels; - *ppInitHandle = &channels->initHandleList[channels->initHandleCount]; - - channels->initHandleCount++; - - DEBUG_CHANNELS("enter"); - - if (!channels->can_call_init) - { - DEBUG_CHANNELS("error not in entry"); - return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY; - } - - if (channels->channelDataCount + channelCount >= CHANNEL_MAX_COUNT) - { - DEBUG_CHANNELS("error too many channels"); - return CHANNEL_RC_TOO_MANY_CHANNELS; - } - - if (!pChannel) - { - DEBUG_CHANNELS("error bad channel"); - return CHANNEL_RC_BAD_CHANNEL; - } - - if (channels->is_connected) - { - DEBUG_CHANNELS("error already connected"); - return CHANNEL_RC_ALREADY_CONNECTED; - } - - if (versionRequested != VIRTUAL_CHANNEL_VERSION_WIN2000) - { - DEBUG_CHANNELS("warning version"); - } - - for (index = 0; index < channelCount; index++) - { - lchannel_def = &pChannel[index]; - - if (freerdp_channels_find_channel_data_by_name(channels, lchannel_def->name, 0) != 0) - { - DEBUG_CHANNELS("error channel already used"); - return CHANNEL_RC_BAD_CHANNEL; - } - } - - llib = &channels->libraryDataList[channels->libraryDataCount]; - llib->init_event_proc = pChannelInitEventProc; - llib->init_handle = *ppInitHandle; - channels->libraryDataCount++; - - for (index = 0; index < channelCount; index++) - { - lchannel_def = &pChannel[index]; - lchannel_data = &channels->channelDataList[channels->channelDataCount]; - - lchannel_data->open_handle = g_open_handle_sequence++; - - lchannel_data->flags = 1; /* init */ - strncpy(lchannel_data->name, lchannel_def->name, CHANNEL_NAME_LEN); - lchannel_data->options = lchannel_def->options; - - if (channels->settings->ChannelCount < 16) - { - channel = channels->settings->ChannelDefArray + channels->settings->ChannelCount; - strncpy(channel->Name, lchannel_def->name, 7); - channel->options = lchannel_def->options; - channels->settings->ChannelCount++; - } - else - { - DEBUG_CHANNELS("warning more than 16 channels"); - } - - channels->channelDataCount++; - } - - return CHANNEL_RC_OK; -} - -/** - * can be called from any thread - * thread safe because no 2 threads can have the same channel name registered - */ -static UINT32 FREERDP_CC MyVirtualChannelOpen(void* pInitHandle, UINT32* pOpenHandle, - char* pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc) +UINT32 FreeRDP_VirtualChannelWrite(UINT32 openHandle, void* pData, UINT32 dataLength, void* pUserData) { int index; rdpChannels* channels; - rdpChannelData* lchannel_data; - - DEBUG_CHANNELS("enter"); - - channels = ((rdpInitHandle*) pInitHandle)->channels; - - if (!pOpenHandle) - { - DEBUG_CHANNELS("error bad channel handle"); - return CHANNEL_RC_BAD_CHANNEL_HANDLE; - } - - if (!pChannelOpenEventProc) - { - DEBUG_CHANNELS("error bad proc"); - return CHANNEL_RC_BAD_PROC; - } - - if (!channels->is_connected) - { - DEBUG_CHANNELS("error not connected"); - return CHANNEL_RC_NOT_CONNECTED; - } - - lchannel_data = freerdp_channels_find_channel_data_by_name(channels, pChannelName, &index); - - if (!lchannel_data) - { - DEBUG_CHANNELS("error channel name"); - return CHANNEL_RC_UNKNOWN_CHANNEL_NAME; - } - - if (lchannel_data->flags == 2) - { - DEBUG_CHANNELS("error channel already open"); - return CHANNEL_RC_ALREADY_OPEN; - } - - lchannel_data->flags = 2; /* open */ - lchannel_data->open_event_proc = pChannelOpenEventProc; - *pOpenHandle = lchannel_data->open_handle; - - return CHANNEL_RC_OK; -} - -/** - * can be called from any thread - * thread safe because no 2 threads can have the same openHandle - */ -static UINT32 FREERDP_CC MyVirtualChannelClose(UINT32 openHandle) -{ - int index; - rdpChannels* channels; - rdpChannelData* lchannel_data; - - DEBUG_CHANNELS("enter"); - - channels = freerdp_channels_find_by_open_handle(openHandle, &index); - - if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) - { - DEBUG_CHANNELS("error bad channels"); - return CHANNEL_RC_BAD_CHANNEL_HANDLE; - } - - lchannel_data = &channels->channelDataList[index]; - - if (lchannel_data->flags != 2) - { - DEBUG_CHANNELS("error not open"); - return CHANNEL_RC_NOT_OPEN; - } - - lchannel_data->flags = 0; - - return CHANNEL_RC_OK; -} - -/* can be called from any thread */ -static UINT32 FREERDP_CC MyVirtualChannelWrite(UINT32 openHandle, void* pData, UINT32 dataLength, void* pUserData) -{ - int index; CHANNEL_OPEN_EVENT* item; - rdpChannels* channels; - rdpChannelData* lchannel_data; + CHANNEL_OPEN_DATA* pChannelOpenData; channels = freerdp_channels_find_by_open_handle(openHandle, &index); @@ -507,9 +240,9 @@ static UINT32 FREERDP_CC MyVirtualChannelWrite(UINT32 openHandle, void* pData, U return CHANNEL_RC_ZERO_LENGTH; } - lchannel_data = &channels->channelDataList[index]; + pChannelOpenData = &channels->openDataList[index]; - if (lchannel_data->flags != 2) + if (pChannelOpenData->flags != 2) { DEBUG_CHANNELS("error not open"); return CHANNEL_RC_NOT_OPEN; @@ -532,11 +265,11 @@ static UINT32 FREERDP_CC MyVirtualChannelWrite(UINT32 openHandle, void* pData, U return CHANNEL_RC_OK; } -static UINT32 FREERDP_CC MyVirtualChannelEventPush(UINT32 openHandle, wMessage* event) +UINT32 FreeRDP_VirtualChannelEventPush(UINT32 openHandle, wMessage* event) { int index; rdpChannels* channels; - rdpChannelData* lchannel_data; + CHANNEL_OPEN_DATA* pChannelOpenData; channels = freerdp_channels_find_by_open_handle(openHandle, &index); @@ -558,9 +291,9 @@ static UINT32 FREERDP_CC MyVirtualChannelEventPush(UINT32 openHandle, wMessage* return CHANNEL_RC_NULL_DATA; } - lchannel_data = &channels->channelDataList[index]; + pChannelOpenData = &channels->openDataList[index]; - if (lchannel_data->flags != 2) + if (pChannelOpenData->flags != 2) { DEBUG_CHANNELS("error not open"); return CHANNEL_RC_NOT_OPEN; @@ -591,7 +324,6 @@ static UINT32 FREERDP_CC MyVirtualChannelEventPush(UINT32 openHandle, wMessage* */ int freerdp_channels_global_init(void) { - g_init_channels = NULL; g_open_handle_sequence = 1; g_mutex_init = CreateMutex(NULL, FALSE, NULL); @@ -636,43 +368,45 @@ void freerdp_channels_free(rdpChannels* channels) int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, void* entry, void* data) { int status; - rdpLibraryData* lib; CHANNEL_ENTRY_POINTS_EX ep; + CHANNEL_CLIENT_DATA* pChannelClientData; - if (channels->libraryDataCount + 1 >= CHANNEL_MAX_COUNT) + if (channels->clientDataCount + 1 >= CHANNEL_MAX_COUNT) { fprintf(stderr, "error: too many channels\n"); return 1; } - lib = &channels->libraryDataList[channels->libraryDataCount]; - lib->entry = (PVIRTUALCHANNELENTRY) entry; + pChannelClientData = &channels->clientDataList[channels->clientDataCount]; + pChannelClientData->entry = (PVIRTUALCHANNELENTRY) entry; ep.cbSize = sizeof(ep); ep.protocolVersion = VIRTUAL_CHANNEL_VERSION_WIN2000; - ep.pVirtualChannelInit = MyVirtualChannelInit; - ep.pVirtualChannelOpen = MyVirtualChannelOpen; - ep.pVirtualChannelClose = MyVirtualChannelClose; - ep.pVirtualChannelWrite = MyVirtualChannelWrite; + ep.pVirtualChannelInit = FreeRDP_VirtualChannelInit; + ep.pVirtualChannelOpen = FreeRDP_VirtualChannelOpen; + ep.pVirtualChannelClose = FreeRDP_VirtualChannelClose; + ep.pVirtualChannelWrite = FreeRDP_VirtualChannelWrite; + g_pInterface = NULL; + ep.MagicNumber = FREERDP_CHANNEL_MAGIC_NUMBER; + ep.ppInterface = &g_pInterface; ep.pExtendedData = data; - ep.pVirtualChannelEventPush = MyVirtualChannelEventPush; + ep.pVirtualChannelEventPush = FreeRDP_VirtualChannelEventPush; - /* enable MyVirtualChannelInit */ - channels->can_call_init = 1; + /* enable VirtualChannelInit */ + channels->can_call_init = TRUE; channels->settings = settings; WaitForSingleObject(g_mutex_init, INFINITE); - g_init_channels = channels; - status = lib->entry((PCHANNEL_ENTRY_POINTS) &ep); - g_init_channels = NULL; + g_ChannelInitData.channels = channels; + status = pChannelClientData->entry((PCHANNEL_ENTRY_POINTS) &ep); ReleaseMutex(g_mutex_init); /* disable MyVirtualChannelInit */ - channels->settings = 0; - channels->can_call_init = 0; + channels->settings = NULL; + channels->can_call_init = FALSE; if (!status) { @@ -704,6 +438,28 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c return freerdp_channels_client_load(channels, settings, entry, data); } +int freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, const char* name, void* pInterface) +{ + int status = 0; + rdpChannels* channels = (rdpChannels*) context->custom; + freerdp* instance = channels->instance; + + IFCALLRET(instance->OnChannelConnected, status, instance, name, pInterface); + + return status; +} + +int freerdp_drdynvc_on_channel_disconnected(DrdynvcClientContext* context, const char* name, void* pInterface) +{ + int status = 0; + rdpChannels* channels = (rdpChannels*) context->custom; + freerdp* instance = channels->instance; + + IFCALLRET(instance->OnChannelDisconnected, status, instance, name, pInterface); + + return status; +} + /** * go through and inform all the libraries that we are initialized * called only from main thread @@ -711,17 +467,17 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c int freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance) { int index; - rdpLibraryData* llib; + CHANNEL_CLIENT_DATA* pChannelClientData; DEBUG_CHANNELS("enter"); channels->instance = instance; - for (index = 0; index < channels->libraryDataCount; index++) + for (index = 0; index < channels->clientDataCount; index++) { - llib = &channels->libraryDataList[index]; + pChannelClientData = &channels->clientDataList[index]; - if (llib->init_event_proc != 0) - llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_INITIALIZED, 0, 0); + if (pChannelClientData->pChannelInitEventProc) + pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_INITIALIZED, 0, 0); } return 0; @@ -736,28 +492,37 @@ int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance) { int index; char* hostname; - int hostname_len; - rdpLibraryData* llib; + int hostnameLength; + CHANNEL_CLIENT_DATA* pChannelClientData; channels->is_connected = 1; hostname = instance->settings->ServerHostname; - hostname_len = strlen(hostname); + hostnameLength = strlen(hostname); - DEBUG_CHANNELS("hostname [%s] channels->num_libs [%d]", hostname, channels->libraryDataCount); + DEBUG_CHANNELS("hostname [%s] channels->num_libs [%d]", hostname, channels->clientDataCount); - for (index = 0; index < channels->libraryDataCount; index++) + for (index = 0; index < channels->clientDataCount; index++) { - llib = &channels->libraryDataList[index]; + pChannelClientData = &channels->clientDataList[index]; - if (llib->init_event_proc != 0) - llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_CONNECTED, hostname, hostname_len); + if (pChannelClientData->pChannelInitEventProc) + pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_CONNECTED, hostname, hostnameLength); + } + + channels->drdynvc = (DrdynvcClientContext*) freerdp_channels_get_static_channel_interface(channels, "drdynvc"); + + if (channels->drdynvc) + { + channels->drdynvc->custom = (void*) channels; + channels->drdynvc->OnChannelConnected = freerdp_drdynvc_on_channel_connected; + channels->drdynvc->OnChannelDisconnected = freerdp_drdynvc_on_channel_disconnected; } return 0; } /** - * data comming from the server to the client + * data coming from the server to the client * called only from main thread */ int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int data_size, int flags, int total_size) @@ -765,7 +530,7 @@ int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int dat int index; rdpChannel* channel; rdpChannels* channels; - rdpChannelData* lchannel_data; + CHANNEL_OPEN_DATA* pChannelOpenData; channels = freerdp_channels_find_by_instance(instance); @@ -783,17 +548,17 @@ int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int dat return 1; } - lchannel_data = freerdp_channels_find_channel_data_by_name(channels, channel->Name, &index); + pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, channel->Name); - if (!lchannel_data) + if (!pChannelOpenData) { DEBUG_CHANNELS("could not find channel name"); return 1; } - if (lchannel_data->open_event_proc != 0) + if (pChannelOpenData->pChannelOpenEventProc) { - lchannel_data->open_event_proc(lchannel_data->open_handle, + pChannelOpenData->pChannelOpenEventProc(pChannelOpenData->OpenHandle, CHANNEL_EVENT_DATA_RECEIVED, data, data_size, total_size, flags); } @@ -808,9 +573,8 @@ int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int dat */ FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, wMessage* event) { - int index; const char* name = NULL; - rdpChannelData* lchannel_data; + CHANNEL_OPEN_DATA* pChannelOpenData; switch (GetMessageClass(event->id)) { @@ -833,23 +597,23 @@ FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, wMessage* eve if (!name) { - DEBUG_CHANNELS("unknown event_class %d", event->event_class); + DEBUG_CHANNELS("unknown event_class %d", GetMessageClass(event->id)); freerdp_event_free(event); return 1; } - lchannel_data = freerdp_channels_find_channel_data_by_name(channels, name, &index); + pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, name); - if (!lchannel_data) + if (!pChannelOpenData) { DEBUG_CHANNELS("could not find channel name %s", name); freerdp_event_free(event); return 1; } - if (lchannel_data->open_event_proc) + if (pChannelOpenData->pChannelOpenEventProc) { - lchannel_data->open_event_proc(lchannel_data->open_handle, CHANNEL_EVENT_USER, + pChannelOpenData->pChannelOpenEventProc(pChannelOpenData->OpenHandle, CHANNEL_EVENT_USER, event, sizeof(wMessage), sizeof(wMessage), 0); } @@ -865,7 +629,7 @@ static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instan wMessage* event; rdpChannel* channel; CHANNEL_OPEN_EVENT* item; - rdpChannelData* lchannel_data; + CHANNEL_OPEN_DATA* pChannelOpenData; while (MessageQueue_Peek(channels->MsgPipe->Out, &message, TRUE)) { @@ -879,17 +643,17 @@ static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instan if (!item) break; - lchannel_data = &channels->channelDataList[item->Index]; + pChannelOpenData = &channels->openDataList[item->Index]; channel = freerdp_channels_find_channel_by_name(channels, instance->settings, - lchannel_data->name, &item->Index); + pChannelOpenData->name, &item->Index); if (channel) instance->SendChannelData(instance, channel->ChannelId, item->Data, item->DataLength); - if (lchannel_data->open_event_proc) + if (pChannelOpenData->pChannelOpenEventProc) { - lchannel_data->open_event_proc(lchannel_data->open_handle, + pChannelOpenData->pChannelOpenEventProc(pChannelOpenData->OpenHandle, CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, item->DataLength, item->DataLength, 0); } @@ -926,6 +690,19 @@ BOOL freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** r return TRUE; } +void* freerdp_channels_get_static_channel_interface(rdpChannels* channels, const char* name) +{ + void* pInterface = NULL; + CHANNEL_OPEN_DATA* pChannelOpenData; + + pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, name); + + if (pChannelOpenData) + pInterface = pChannelOpenData->pInterface; + + return pInterface; +} + HANDLE freerdp_channels_get_event_handle(freerdp* instance) { HANDLE event = NULL; @@ -983,23 +760,18 @@ wMessage* freerdp_channels_pop_event(rdpChannels* channels) void freerdp_channels_close(rdpChannels* channels, freerdp* instance) { int index; - rdpLibraryData* llib; + CHANNEL_CLIENT_DATA* pChannelClientData; DEBUG_CHANNELS("closing"); channels->is_connected = 0; freerdp_channels_check_fds(channels, instance); /* tell all libraries we are shutting down */ - for (index = 0; index < channels->libraryDataCount; index++) + for (index = 0; index < channels->clientDataCount; index++) { - llib = &channels->libraryDataList[index]; + pChannelClientData = &channels->clientDataList[index]; - if (llib->init_event_proc != 0) - llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_TERMINATED, 0, 0); + if (pChannelClientData->pChannelInitEventProc) + pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); } } - -/* Local variables: */ -/* c-basic-offset: 8 */ -/* c-file-style: "linux" */ -/* End: */ diff --git a/channels/client/channels.h b/channels/client/channels.h new file mode 100644 index 000000000..7e801e59b --- /dev/null +++ b/channels/client/channels.h @@ -0,0 +1,122 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Client Channels + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_PRIVATE_CLIENT_CHANNELS +#define FREERDP_PRIVATE_CLIENT_CHANNELS + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define CHANNEL_MAX_COUNT 30 + +struct rdp_channel_client_data +{ + PVIRTUALCHANNELENTRY entry; + PCHANNEL_INIT_EVENT_FN pChannelInitEventProc; + void* pInitHandle; +}; +typedef struct rdp_channel_client_data CHANNEL_CLIENT_DATA; + +struct rdp_channel_open_data +{ + char name[8]; + int OpenHandle; + int options; + int flags; + void* pInterface; + PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc; +}; +typedef struct rdp_channel_open_data CHANNEL_OPEN_DATA; + +struct _CHANNEL_OPEN_EVENT +{ + void* Data; + UINT32 DataLength; + void* UserData; + int Index; +}; +typedef struct _CHANNEL_OPEN_EVENT CHANNEL_OPEN_EVENT; + +/** + * pInitHandle: handle that identifies the client connection + * Obtained by the client with VirtualChannelInit + * Used by the client with VirtualChannelOpen + */ + +struct rdp_channel_init_data +{ + rdpChannels* channels; + void* pInterface; +}; +typedef struct rdp_channel_init_data CHANNEL_INIT_DATA; + +struct rdp_channels +{ + /* internal */ + + int clientDataCount; + CHANNEL_CLIENT_DATA clientDataList[CHANNEL_MAX_COUNT]; + + int openDataCount; + CHANNEL_OPEN_DATA openDataList[CHANNEL_MAX_COUNT]; + + int initDataCount; + CHANNEL_INIT_DATA initDataList[CHANNEL_MAX_COUNT]; + + /* control for entry into MyVirtualChannelInit */ + int can_call_init; + rdpSettings* settings; + + /* true once freerdp_channels_post_connect is called */ + int is_connected; + + /* used for locating the channels for a given instance */ + freerdp* instance; + + wMessagePipe* MsgPipe; + + DrdynvcClientContext* drdynvc; +}; + +#ifdef WITH_DEBUG_CHANNELS +#define DEBUG_CHANNELS(fmt, ...) DEBUG_CLASS(CHANNELS, fmt, ## __VA_ARGS__) +#else +#define DEBUG_CHANNELS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +rdpChannels* freerdp_channels_find_by_open_handle(int open_handle, int* pindex); +CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name(rdpChannels* channels, const char* channel_name); + +#endif /* FREERDP_PRIVATE_CLIENT_CHANNELS */ diff --git a/channels/client/init.c b/channels/client/init.c new file mode 100644 index 000000000..f88867a6a --- /dev/null +++ b/channels/client/init.c @@ -0,0 +1,135 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Client Channels + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "channels.h" + +#include "init.h" + +extern int g_open_handle_sequence; + +extern void* g_pInterface; +extern CHANNEL_INIT_DATA g_ChannelInitData; + +UINT32 FreeRDP_VirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF pChannel, + int channelCount, UINT32 versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc) +{ + int index; + void* pInterface; + rdpChannel* channel; + rdpChannels* channels; + PCHANNEL_DEF pChannelDef; + CHANNEL_INIT_DATA* pChannelInitData; + CHANNEL_OPEN_DATA* pChannelOpenData; + CHANNEL_CLIENT_DATA* pChannelClientData; + + if (!ppInitHandle) + { + DEBUG_CHANNELS("error bad init handle"); + return CHANNEL_RC_BAD_INIT_HANDLE; + } + + channels = g_ChannelInitData.channels; + pInterface = g_pInterface; + + pChannelInitData = &(channels->initDataList[channels->initDataCount]); + *ppInitHandle = pChannelInitData; + channels->initDataCount++; + + pChannelInitData->channels = channels; + pChannelInitData->pInterface = pInterface; + + DEBUG_CHANNELS("enter"); + + if (!channels->can_call_init) + { + DEBUG_CHANNELS("error not in entry"); + return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY; + } + + if (channels->openDataCount + channelCount >= CHANNEL_MAX_COUNT) + { + DEBUG_CHANNELS("error too many channels"); + return CHANNEL_RC_TOO_MANY_CHANNELS; + } + + if (!pChannel) + { + DEBUG_CHANNELS("error bad channel"); + return CHANNEL_RC_BAD_CHANNEL; + } + + if (channels->is_connected) + { + DEBUG_CHANNELS("error already connected"); + return CHANNEL_RC_ALREADY_CONNECTED; + } + + if (versionRequested != VIRTUAL_CHANNEL_VERSION_WIN2000) + { + DEBUG_CHANNELS("warning version"); + } + + for (index = 0; index < channelCount; index++) + { + pChannelDef = &pChannel[index]; + + if (freerdp_channels_find_channel_open_data_by_name(channels, pChannelDef->name) != 0) + { + DEBUG_CHANNELS("error channel already used"); + return CHANNEL_RC_BAD_CHANNEL; + } + } + + pChannelClientData = &channels->clientDataList[channels->clientDataCount]; + pChannelClientData->pChannelInitEventProc = pChannelInitEventProc; + pChannelClientData->pInitHandle = *ppInitHandle; + channels->clientDataCount++; + + for (index = 0; index < channelCount; index++) + { + pChannelDef = &pChannel[index]; + pChannelOpenData = &channels->openDataList[channels->openDataCount]; + + pChannelOpenData->OpenHandle = g_open_handle_sequence++; + + pChannelOpenData->flags = 1; /* init */ + strncpy(pChannelOpenData->name, pChannelDef->name, CHANNEL_NAME_LEN); + pChannelOpenData->options = pChannelDef->options; + + if (channels->settings->ChannelCount < CHANNEL_MAX_COUNT) + { + channel = channels->settings->ChannelDefArray + channels->settings->ChannelCount; + strncpy(channel->Name, pChannelDef->name, 7); + channel->options = pChannelDef->options; + channels->settings->ChannelCount++; + } + else + { + DEBUG_CHANNELS("warning more than %d channels", CHANNEL_MAX_COUNT); + } + + channels->openDataCount++; + } + + return CHANNEL_RC_OK; +} diff --git a/channels/client/init.h b/channels/client/init.h new file mode 100644 index 000000000..a5dccc133 --- /dev/null +++ b/channels/client/init.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Client Channels + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_PRIVATE_CLIENT_CHANNELS_INIT +#define FREERDP_PRIVATE_CLIENT_CHANNELS_INIT + +#include "channels.h" + +UINT32 FreeRDP_VirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF pChannel, + int channelCount, UINT32 versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc); + +#endif /* FREERDP_PRIVATE_CLIENT_CHANNELS_INIT */ diff --git a/channels/client/open.c b/channels/client/open.c new file mode 100644 index 000000000..1233fb964 --- /dev/null +++ b/channels/client/open.c @@ -0,0 +1,103 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Client Channels + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "open.h" + +UINT32 FreeRDP_VirtualChannelOpen(void* pInitHandle, UINT32* pOpenHandle, + char* pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc) +{ + void* pInterface; + rdpChannels* channels; + CHANNEL_INIT_DATA* pChannelInitData; + CHANNEL_OPEN_DATA* pChannelOpenData; + + DEBUG_CHANNELS("enter"); + + pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle; + channels = pChannelInitData->channels; + pInterface = pChannelInitData->pInterface; + + if (!pOpenHandle) + { + DEBUG_CHANNELS("error bad channel handle"); + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + } + + if (!pChannelOpenEventProc) + { + DEBUG_CHANNELS("error bad proc"); + return CHANNEL_RC_BAD_PROC; + } + + if (!channels->is_connected) + { + DEBUG_CHANNELS("error not connected"); + return CHANNEL_RC_NOT_CONNECTED; + } + + pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, pChannelName); + + if (!pChannelOpenData) + { + DEBUG_CHANNELS("error channel name"); + return CHANNEL_RC_UNKNOWN_CHANNEL_NAME; + } + + if (pChannelOpenData->flags == 2) + { + DEBUG_CHANNELS("error channel already open"); + return CHANNEL_RC_ALREADY_OPEN; + } + + pChannelOpenData->flags = 2; /* open */ + pChannelOpenData->pInterface = pInterface; + pChannelOpenData->pChannelOpenEventProc = pChannelOpenEventProc; + *pOpenHandle = pChannelOpenData->OpenHandle; + + return CHANNEL_RC_OK; +} + +UINT32 FreeRDP_VirtualChannelClose(UINT32 openHandle) +{ + int index; + rdpChannels* channels; + CHANNEL_OPEN_DATA* pChannelOpenData; + + DEBUG_CHANNELS("enter"); + + channels = freerdp_channels_find_by_open_handle(openHandle, &index); + + if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) + { + DEBUG_CHANNELS("error bad channels"); + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + } + + pChannelOpenData = &channels->openDataList[index]; + + if (pChannelOpenData->flags != 2) + { + DEBUG_CHANNELS("error not open"); + return CHANNEL_RC_NOT_OPEN; + } + + pChannelOpenData->flags = 0; + + return CHANNEL_RC_OK; +} diff --git a/channels/client/open.h b/channels/client/open.h new file mode 100644 index 000000000..4bb525d53 --- /dev/null +++ b/channels/client/open.h @@ -0,0 +1,30 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Client Channels + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_PRIVATE_CLIENT_CHANNELS_OPEN +#define FREERDP_PRIVATE_CLIENT_CHANNELS_OPEN + +#include "channels.h" + +UINT32 FreeRDP_VirtualChannelOpen(void* pInitHandle, UINT32* pOpenHandle, + char* pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc); + +UINT32 FreeRDP_VirtualChannelClose(UINT32 openHandle); + +#endif /* FREERDP_PRIVATE_CLIENT_CHANNELS_OPEN */ diff --git a/channels/cliprdr/client/cliprdr_format.c b/channels/cliprdr/client/cliprdr_format.c index aa4dfa03b..023bbf8e1 100644 --- a/channels/cliprdr/client/cliprdr_format.c +++ b/channels/cliprdr/client/cliprdr_format.c @@ -53,11 +53,11 @@ void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIS if (cb_event->raw_format_data) { s = cliprdr_packet_new(CB_FORMAT_LIST, 0, cb_event->raw_format_data_size); - stream_write(s, cb_event->raw_format_data, cb_event->raw_format_data_size); + Stream_Write(s, cb_event->raw_format_data, cb_event->raw_format_data_size); } else { - wStream* body = stream_new(0); + wStream* body = Stream_New(NULL, 64); for (i = 0; i < cb_event->num_formats; i++) { @@ -87,15 +87,15 @@ void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIS if (!cliprdr->use_long_format_names) name_length = 32; - stream_extend(body, stream_get_size(body) + 4 + name_length); + Stream_EnsureRemainingCapacity(body, Stream_Capacity(body) + 4 + name_length); - stream_write_UINT32(body, cb_event->formats[i]); - stream_write(body, name, name_length); + Stream_Write_UINT32(body, cb_event->formats[i]); + Stream_Write(body, name, name_length); } - s = cliprdr_packet_new(CB_FORMAT_LIST, 0, stream_get_size(body)); - stream_write(s, stream_get_head(body), stream_get_size(body)); - stream_free(body); + s = cliprdr_packet_new(CB_FORMAT_LIST, 0, Stream_Capacity(body)); + Stream_Write(s, Stream_Buffer(body), Stream_Capacity(body)); + Stream_Free(body, TRUE); } cliprdr_packet_send(cliprdr, s); @@ -137,7 +137,7 @@ void cliprdr_process_short_format_names(cliprdrPlugin* cliprdr, wStream* s, UINT { format_name = &cliprdr->format_names[i]; - stream_read_UINT32(s, format_name->id); + Stream_Read_UINT32(s, format_name->id); if (ascii) { @@ -150,7 +150,7 @@ void cliprdr_process_short_format_names(cliprdrPlugin* cliprdr, wStream* s, UINT format_name->length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) s->pointer, 32 / 2, &format_name->name, 0, NULL, NULL); } - stream_seek(s, 32); + Stream_Seek(s, 32); } } @@ -160,13 +160,13 @@ void cliprdr_process_long_format_names(cliprdrPlugin* cliprdr, wStream* s, UINT3 BYTE* end_mark; CLIPRDR_FORMAT_NAME* format_name; - stream_get_mark(s, end_mark); + Stream_GetPointer(s, end_mark); end_mark += length; cliprdr->format_names = (CLIPRDR_FORMAT_NAME*) malloc(sizeof(CLIPRDR_FORMAT_NAME) * allocated_formats); cliprdr->num_format_names = 0; - while (stream_get_left(s) >= 6) + while (Stream_GetRemainingLength(s) >= 6) { BYTE* p; int name_len; @@ -179,20 +179,20 @@ void cliprdr_process_long_format_names(cliprdrPlugin* cliprdr, wStream* s, UINT3 } format_name = &cliprdr->format_names[cliprdr->num_format_names++]; - stream_read_UINT32(s, format_name->id); + Stream_Read_UINT32(s, format_name->id); format_name->name = NULL; format_name->length = 0; - for (p = stream_get_tail(s), name_len = 0; p + 1 < end_mark; p += 2, name_len += 2) + for (p = Stream_Pointer(s), name_len = 0; p + 1 < end_mark; p += 2, name_len += 2) { if (*((unsigned short*) p) == 0) break; } - format_name->length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), name_len / 2, &format_name->name, 0, NULL, NULL); + format_name->length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), name_len / 2, &format_name->name, 0, NULL, NULL); - stream_seek(s, name_len + 2); + Stream_Seek(s, name_len + 2); } } @@ -210,7 +210,7 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data if (dataLen > 0) { cb_event->raw_format_data = (BYTE*) malloc(dataLen); - memcpy(cb_event->raw_format_data, stream_get_tail(s), dataLen); + memcpy(cb_event->raw_format_data, Stream_Pointer(s), dataLen); cb_event->raw_format_data_size = dataLen; } @@ -309,7 +309,7 @@ void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UIN cb_event = (RDP_CB_DATA_REQUEST_EVENT*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_DataRequest, NULL, NULL); - stream_read_UINT32(s, cb_event->format); + Stream_Read_UINT32(s, cb_event->format); svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event); } @@ -322,7 +322,7 @@ void cliprdr_process_format_data_response_event(cliprdrPlugin* cliprdr, RDP_CB_D if (cb_event->size > 0) { s = cliprdr_packet_new(CB_FORMAT_DATA_RESPONSE, CB_RESPONSE_OK, cb_event->size); - stream_write(s, cb_event->data, cb_event->size); + Stream_Write(s, cb_event->data, cb_event->size); } else { @@ -339,7 +339,7 @@ void cliprdr_process_format_data_request_event(cliprdrPlugin* cliprdr, RDP_CB_DA DEBUG_CLIPRDR("Sending Format Data Request"); s = cliprdr_packet_new(CB_FORMAT_DATA_REQUEST, 0, 4); - stream_write_UINT32(s, cb_event->format); + Stream_Write_UINT32(s, cb_event->format); cliprdr_packet_send(cliprdr, s); } @@ -354,7 +354,7 @@ void cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UI { cb_event->size = dataLen; cb_event->data = (BYTE*) malloc(dataLen); - CopyMemory(cb_event->data, stream_get_tail(s), dataLen); + CopyMemory(cb_event->data, Stream_Pointer(s), dataLen); } svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event); diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index c19479e85..f83abba7a 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -57,11 +57,11 @@ wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen) { wStream* s; - s = stream_new(dataLen + 8); - stream_write_UINT16(s, msgType); - stream_write_UINT16(s, msgFlags); + s = Stream_New(NULL, dataLen + 8); + Stream_Write_UINT16(s, msgType); + Stream_Write_UINT16(s, msgFlags); /* Write actual length after the entire packet has been constructed. */ - stream_seek(s, 4); + Stream_Seek(s, 4); return s; } @@ -71,11 +71,11 @@ void cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) int pos; UINT32 dataLen; - pos = stream_get_pos(s); + pos = Stream_GetPosition(s); dataLen = pos - 8; - stream_set_pos(s, 4); - stream_write_UINT32(s, dataLen); - stream_set_pos(s, pos); + Stream_SetPosition(s, 4); + Stream_Write_UINT32(s, dataLen); + Stream_SetPosition(s, pos); svc_plugin_send((rdpSvcPlugin*) cliprdr, s); } @@ -106,8 +106,8 @@ static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* UINT32 version; UINT32 generalFlags; - stream_read_UINT32(s, version); /* version (4 bytes) */ - stream_read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */ + Stream_Read_UINT32(s, version); /* version (4 bytes) */ + Stream_Read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */ DEBUG_CLIPRDR("Version: %d", version); @@ -137,15 +137,15 @@ static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 UINT16 cCapabilitiesSets; UINT16 capabilitySetType; - stream_read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */ - stream_seek_UINT16(s); /* pad1 (2 bytes) */ + Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */ + Stream_Seek_UINT16(s); /* pad1 (2 bytes) */ DEBUG_CLIPRDR("cCapabilitiesSets %d", cCapabilitiesSets); for (i = 0; i < cCapabilitiesSets; i++) { - stream_read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */ - stream_read_UINT16(s, lengthCapability); /* lengthCapability (2 bytes) */ + Stream_Read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */ + Stream_Read_UINT16(s, lengthCapability); /* lengthCapability (2 bytes) */ switch (capabilitySetType) { @@ -171,12 +171,12 @@ static void cliprdr_send_clip_caps(cliprdrPlugin* cliprdr) flags = CB_USE_LONG_FORMAT_NAMES; - stream_write_UINT16(s, 1); /* cCapabilitiesSets */ - stream_write_UINT16(s, 0); /* pad1 */ - stream_write_UINT16(s, CB_CAPSTYPE_GENERAL); /* capabilitySetType */ - stream_write_UINT16(s, CB_CAPSTYPE_GENERAL_LEN); /* lengthCapability */ - stream_write_UINT32(s, CB_CAPS_VERSION_2); /* version */ - stream_write_UINT32(s, flags); /* generalFlags */ + Stream_Write_UINT16(s, 1); /* cCapabilitiesSets */ + Stream_Write_UINT16(s, 0); /* pad1 */ + Stream_Write_UINT16(s, CB_CAPSTYPE_GENERAL); /* capabilitySetType */ + Stream_Write_UINT16(s, CB_CAPSTYPE_GENERAL_LEN); /* lengthCapability */ + Stream_Write_UINT32(s, CB_CAPS_VERSION_2); /* version */ + Stream_Write_UINT32(s, flags); /* generalFlags */ cliprdr_packet_send(cliprdr, s); } @@ -200,9 +200,9 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s) UINT32 dataLen; cliprdrPlugin* cliprdr = (cliprdrPlugin*) plugin; - stream_read_UINT16(s, msgType); - stream_read_UINT16(s, msgFlags); - stream_read_UINT32(s, dataLen); + Stream_Read_UINT16(s, msgType); + Stream_Read_UINT16(s, msgFlags); + Stream_Read_UINT32(s, dataLen); DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d", CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen); @@ -238,7 +238,7 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s) break; } - stream_free(s); + Stream_Free(s, TRUE); } static void cliprdr_process_event(rdpSvcPlugin* plugin, wMessage* event) @@ -301,6 +301,7 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) { cliprdrPlugin* _p; CliprdrClientContext* context; + CHANNEL_ENTRY_POINTS_EX* pEntryPointsEx; _p = (cliprdrPlugin*) malloc(sizeof(cliprdrPlugin)); ZeroMemory(_p, sizeof(cliprdrPlugin)); @@ -318,14 +319,20 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) _p->plugin.event_callback = cliprdr_process_event; _p->plugin.terminate_callback = cliprdr_process_terminate; - context = (CliprdrClientContext*) malloc(sizeof(CliprdrClientContext)); + pEntryPointsEx = (CHANNEL_ENTRY_POINTS_EX*) pEntryPoints; - context->MonitorReady = cliprdr_monitor_ready; - context->FormatList = cliprdr_format_list; - context->DataRequest = cliprdr_data_request; - context->DataResponse = cliprdr_data_response; + if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_EX)) && + (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) + { + context = (CliprdrClientContext*) malloc(sizeof(CliprdrClientContext)); - _p->plugin.channel_entry_points.pInterface = (void*) context; + context->MonitorReady = cliprdr_monitor_ready; + context->FormatList = cliprdr_format_list; + context->DataRequest = cliprdr_data_request; + context->DataResponse = cliprdr_data_response; + + *(pEntryPointsEx->ppInterface) = (void*) context; + } svc_plugin_init((rdpSvcPlugin*) _p, pEntryPoints); diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index a6b062692..a605ba205 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -26,35 +26,15 @@ #include #include +#include #include -#include #include #include "dvcman.h" #include "drdynvc_types.h" #include "drdynvc_main.h" -#define CREATE_REQUEST_PDU 0x01 -#define DATA_FIRST_PDU 0x02 -#define DATA_PDU 0x03 -#define CLOSE_REQUEST_PDU 0x04 -#define CAPABILITY_REQUEST_PDU 0x05 - -struct drdynvc_plugin -{ - rdpSvcPlugin plugin; - - int version; - int PriorityCharge0; - int PriorityCharge1; - int PriorityCharge2; - int PriorityCharge3; - int channel_error; - - IWTSVirtualChannelManager* channel_mgr; -}; - static int drdynvc_write_variable_uint(wStream* stream, UINT32 val) { int cb; @@ -62,17 +42,17 @@ static int drdynvc_write_variable_uint(wStream* stream, UINT32 val) if (val <= 0xFF) { cb = 0; - stream_write_BYTE(stream, val); + Stream_Write_UINT8(stream, val); } else if (val <= 0xFFFF) { cb = 1; - stream_write_UINT16(stream, val); + Stream_Write_UINT16(stream, val); } else { cb = 2; - stream_write_UINT32(stream, val); + Stream_Write_UINT32(stream, val); } return cb; @@ -92,56 +72,56 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN if (drdynvc->channel_error != CHANNEL_RC_OK) return 1; - data_out = stream_new(CHANNEL_CHUNK_LENGTH); - stream_set_pos(data_out, 1); + data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); + Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); if (data_size == 0) { - pos = stream_get_pos(data_out); - stream_set_pos(data_out, 0); - stream_write_BYTE(data_out, 0x40 | cbChId); - stream_set_pos(data_out, pos); + pos = Stream_GetPosition(data_out); + Stream_SetPosition(data_out, 0); + Stream_Write_UINT8(data_out, 0x40 | cbChId); + Stream_SetPosition(data_out, pos); error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); } else if (data_size <= CHANNEL_CHUNK_LENGTH - pos) { - pos = stream_get_pos(data_out); - stream_set_pos(data_out, 0); - stream_write_BYTE(data_out, 0x30 | cbChId); - stream_set_pos(data_out, pos); - stream_write(data_out, data, data_size); + pos = Stream_GetPosition(data_out); + Stream_SetPosition(data_out, 0); + Stream_Write_UINT8(data_out, 0x30 | cbChId); + Stream_SetPosition(data_out, pos); + Stream_Write(data_out, data, data_size); error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); } else { /* Fragment the data */ cbLen = drdynvc_write_variable_uint(data_out, data_size); - pos = stream_get_pos(data_out); - stream_set_pos(data_out, 0); - stream_write_BYTE(data_out, 0x20 | cbChId | (cbLen << 2)); - stream_set_pos(data_out, pos); + pos = Stream_GetPosition(data_out); + Stream_SetPosition(data_out, 0); + Stream_Write_UINT8(data_out, 0x20 | cbChId | (cbLen << 2)); + Stream_SetPosition(data_out, pos); chunk_len = CHANNEL_CHUNK_LENGTH - pos; - stream_write(data_out, data, chunk_len); + Stream_Write(data_out, data, chunk_len); data += chunk_len; data_size -= chunk_len; error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); while (error == CHANNEL_RC_OK && data_size > 0) { - data_out = stream_new(CHANNEL_CHUNK_LENGTH); - stream_set_pos(data_out, 1); + data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); + Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); - pos = stream_get_pos(data_out); - stream_set_pos(data_out, 0); - stream_write_BYTE(data_out, 0x30 | cbChId); - stream_set_pos(data_out, pos); + pos = Stream_GetPosition(data_out); + Stream_SetPosition(data_out, 0); + Stream_Write_UINT8(data_out, 0x30 | cbChId); + Stream_SetPosition(data_out, pos); chunk_len = data_size; if (chunk_len > CHANNEL_CHUNK_LENGTH - pos) chunk_len = CHANNEL_CHUNK_LENGTH - pos; - stream_write(data_out, data, chunk_len); + Stream_Write(data_out, data, chunk_len); data += chunk_len; data_size -= chunk_len; error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); @@ -179,20 +159,23 @@ static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, in int error; DEBUG_DVC("Sp=%d cbChId=%d", Sp, cbChId); - stream_seek(s, 1); /* pad */ - stream_read_UINT16(s, drdynvc->version); + Stream_Seek(s, 1); /* pad */ + Stream_Read_UINT16(s, drdynvc->version); - if (drdynvc->version == 2) + /* RDP8 servers offer version 3, though Microsoft forgot to document it + * in their early documents. It behaves the same as version 2. + */ + if ((drdynvc->version == 2) || (drdynvc->version == 3)) { - stream_read_UINT16(s, drdynvc->PriorityCharge0); - stream_read_UINT16(s, drdynvc->PriorityCharge1); - stream_read_UINT16(s, drdynvc->PriorityCharge2); - stream_read_UINT16(s, drdynvc->PriorityCharge3); + Stream_Read_UINT16(s, drdynvc->PriorityCharge0); + Stream_Read_UINT16(s, drdynvc->PriorityCharge1); + Stream_Read_UINT16(s, drdynvc->PriorityCharge2); + Stream_Read_UINT16(s, drdynvc->PriorityCharge3); } - data_out = stream_new(4); - stream_write_UINT16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */ - stream_write_UINT16(data_out, drdynvc->version); + data_out = Stream_New(NULL, 4); + Stream_Write_UINT16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */ + Stream_Write_UINT16(data_out, drdynvc->version); error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); if (error != CHANNEL_RC_OK) @@ -213,15 +196,15 @@ static UINT32 drdynvc_read_variable_uint(wStream* stream, int cbLen) switch (cbLen) { case 0: - stream_read_BYTE(stream, val); + Stream_Read_UINT8(stream, val); break; case 1: - stream_read_UINT16(stream, val); + Stream_Read_UINT16(stream, val); break; default: - stream_read_UINT32(stream, val); + Stream_Read_UINT32(stream, val); break; } @@ -231,37 +214,37 @@ static UINT32 drdynvc_read_variable_uint(wStream* stream, int cbLen) static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) { int pos; - int error; + int status; UINT32 ChannelId; wStream* data_out; ChannelId = drdynvc_read_variable_uint(s, cbChId); - pos = stream_get_pos(s); - DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, stream_get_tail(s)); + pos = Stream_GetPosition(s); + DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s)); - error = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) stream_get_tail(s)); + status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) Stream_Pointer(s)); - data_out = stream_new(pos + 4); - stream_write_BYTE(data_out, 0x10 | cbChId); - stream_set_pos(s, 1); - stream_copy(data_out, s, pos - 1); + data_out = Stream_New(NULL, pos + 4); + Stream_Write_UINT8(data_out, 0x10 | cbChId); + Stream_SetPosition(s, 1); + Stream_Copy(data_out, s, pos - 1); - if (error == 0) + if (status == 0) { DEBUG_DVC("channel created"); - stream_write_UINT32(data_out, 0); + Stream_Write_UINT32(data_out, 0); } else { DEBUG_DVC("no listener"); - stream_write_UINT32(data_out, (UINT32)(-1)); + Stream_Write_UINT32(data_out, (UINT32)(-1)); } - error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); + status = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); - if (error != CHANNEL_RC_OK) + if (status != CHANNEL_RC_OK) { - DEBUG_WARN("VirtualChannelWrite failed %d", error); + DEBUG_WARN("VirtualChannelWrite failed %d", status); return 1; } @@ -270,7 +253,7 @@ static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cb static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) { - int error; + int status; UINT32 Length; UINT32 ChannelId; @@ -278,13 +261,13 @@ static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId Length = drdynvc_read_variable_uint(s, Sp); DEBUG_DVC("ChannelId=%d Length=%d", ChannelId, Length); - error = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length); + status = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length); - if (error) - return error; + if (status) + return status; return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId, - stream_get_tail(s), stream_get_left(s)); + Stream_Pointer(s), Stream_GetRemainingLength(s)); } static int drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) @@ -295,7 +278,7 @@ static int drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStr DEBUG_DVC("ChannelId=%d", ChannelId); return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId, - stream_get_tail(s), stream_get_left(s)); + Stream_Pointer(s), Stream_GetRemainingLength(s)); } static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) @@ -317,7 +300,7 @@ static void drdynvc_process_receive(rdpSvcPlugin* plugin, wStream* s) int cbChId; drdynvcPlugin* drdynvc = (drdynvcPlugin*) plugin; - stream_read_BYTE(s, value); + Stream_Read_UINT8(s, value); Cmd = (value & 0xf0) >> 4; Sp = (value & 0x0c) >> 2; cbChId = (value & 0x03) >> 0; @@ -329,24 +312,29 @@ static void drdynvc_process_receive(rdpSvcPlugin* plugin, wStream* s) case CAPABILITY_REQUEST_PDU: drdynvc_process_capability_request(drdynvc, Sp, cbChId, s); break; + case CREATE_REQUEST_PDU: drdynvc_process_create_request(drdynvc, Sp, cbChId, s); break; + case DATA_FIRST_PDU: drdynvc_process_data_first(drdynvc, Sp, cbChId, s); break; + case DATA_PDU: drdynvc_process_data(drdynvc, Sp, cbChId, s); break; + case CLOSE_REQUEST_PDU: drdynvc_process_close_request(drdynvc, Sp, cbChId, s); break; + default: DEBUG_WARN("unknown drdynvc cmd 0x%x", Cmd); break; } - stream_free(s); + Stream_Free(s, TRUE); } static void drdynvc_process_connect(rdpSvcPlugin* plugin) @@ -383,18 +371,30 @@ static void drdynvc_process_terminate(rdpSvcPlugin* plugin) DEBUG_DVC("terminating"); - if (drdynvc->channel_mgr != NULL) + if (drdynvc->channel_mgr) dvcman_free(drdynvc->channel_mgr); free(drdynvc); } +/** + * Channel Client Interface + */ + +int drdynvc_get_version(DrdynvcClientContext* context) +{ + drdynvcPlugin* drdynvc = (drdynvcPlugin*) context->handle; + return drdynvc->version; +} + /* drdynvc is always built-in */ #define VirtualChannelEntry drdynvc_VirtualChannelEntry int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) { drdynvcPlugin* _p; + DrdynvcClientContext* context; + CHANNEL_ENTRY_POINTS_EX* pEntryPointsEx; _p = (drdynvcPlugin*) malloc(sizeof(drdynvcPlugin)); ZeroMemory(_p, sizeof(drdynvcPlugin)); @@ -411,6 +411,21 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) _p->plugin.event_callback = drdynvc_process_event; _p->plugin.terminate_callback = drdynvc_process_terminate; + pEntryPointsEx = (CHANNEL_ENTRY_POINTS_EX*) pEntryPoints; + + if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_EX)) && + (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) + { + context = (DrdynvcClientContext*) malloc(sizeof(DrdynvcClientContext)); + + context->handle = (void*) _p; + _p->context = context; + + context->GetVersion = drdynvc_get_version; + + *(pEntryPointsEx->ppInterface) = (void*) context; + } + svc_plugin_init((rdpSvcPlugin*) _p, pEntryPoints); return 1; diff --git a/channels/drdynvc/client/drdynvc_main.h b/channels/drdynvc/client/drdynvc_main.h index 4cc9a6695..369084a19 100644 --- a/channels/drdynvc/client/drdynvc_main.h +++ b/channels/drdynvc/client/drdynvc_main.h @@ -20,10 +20,36 @@ #ifndef __DRDYNVC_MAIN_H #define __DRDYNVC_MAIN_H -#include +#include +#include +#include +#include +#include + +#define CREATE_REQUEST_PDU 0x01 +#define DATA_FIRST_PDU 0x02 +#define DATA_PDU 0x03 +#define CLOSE_REQUEST_PDU 0x04 +#define CAPABILITY_REQUEST_PDU 0x05 typedef struct drdynvc_plugin drdynvcPlugin; +struct drdynvc_plugin +{ + rdpSvcPlugin plugin; + + DrdynvcClientContext* context; + + int version; + int PriorityCharge0; + int PriorityCharge1; + int PriorityCharge2; + int PriorityCharge3; + int channel_error; + + IWTSVirtualChannelManager* channel_mgr; +}; + int drdynvc_write_data(drdynvcPlugin* plugin, UINT32 ChannelId, BYTE* data, UINT32 data_size); int drdynvc_push_event(drdynvcPlugin* plugin, wMessage* event); diff --git a/channels/drdynvc/client/dvcman.c b/channels/drdynvc/client/dvcman.c index 831205a3a..ac897a669 100644 --- a/channels/drdynvc/client/dvcman.c +++ b/channels/drdynvc/client/dvcman.c @@ -27,70 +27,14 @@ #include #include +#include #include - -#include #include #include "drdynvc_types.h" #include "dvcman.h" -#define MAX_PLUGINS 10 - -typedef struct _DVCMAN DVCMAN; - -struct _DVCMAN -{ - IWTSVirtualChannelManager iface; - - drdynvcPlugin* drdynvc; - - const char* plugin_names[MAX_PLUGINS]; - IWTSPlugin* plugins[MAX_PLUGINS]; - int num_plugins; - - IWTSListener* listeners[MAX_PLUGINS]; - int num_listeners; - - LIST* channels; -}; - -typedef struct _DVCMAN_LISTENER DVCMAN_LISTENER; -struct _DVCMAN_LISTENER -{ - IWTSListener iface; - - DVCMAN* dvcman; - char* channel_name; - UINT32 flags; - IWTSListenerCallback* listener_callback; -}; - -typedef struct _DVCMAN_ENTRY_POINTS DVCMAN_ENTRY_POINTS; -struct _DVCMAN_ENTRY_POINTS -{ - IDRDYNVC_ENTRY_POINTS iface; - - DVCMAN* dvcman; - ADDIN_ARGV* args; -}; - -typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL; -struct _DVCMAN_CHANNEL -{ - IWTSVirtualChannel iface; - - DVCMAN* dvcman; - DVCMAN_CHANNEL* next; - UINT32 channel_id; - IWTSVirtualChannelCallback* channel_callback; - - wStream* dvc_data; - - HANDLE dvc_chan_mutex; -}; - static int dvcman_get_configuration(IWTSListener* pListener, void** ppPropertyBag) { *ppPropertyBag = NULL; @@ -112,15 +56,17 @@ static int dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, ZeroMemory(listener, sizeof(DVCMAN_LISTENER)); listener->iface.GetConfiguration = dvcman_get_configuration; + listener->iface.pInterface = NULL; + listener->dvcman = dvcman; listener->channel_name = _strdup(pszChannelName); listener->flags = ulFlags; listener->listener_callback = pListenerCallback; if (ppListener) - *ppListener = (IWTSListener*)listener; + *ppListener = (IWTSListener*) listener; - dvcman->listeners[dvcman->num_listeners++] = (IWTSListener*)listener; + dvcman->listeners[dvcman->num_listeners++] = (IWTSListener*) listener; return 0; } @@ -197,18 +143,53 @@ UINT32 dvcman_get_channel_id(IWTSVirtualChannel * channel) IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId) { - LIST_ITEM* curr; + int index; + BOOL found = FALSE; + DVCMAN_CHANNEL* channel; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - for (curr = dvcman->channels->head; curr; curr = curr->next) + ArrayList_Lock(dvcman->channels); + + index = 0; + channel = (DVCMAN_CHANNEL*) ArrayList_GetItem(dvcman->channels, index++); + + while (channel) { - if (((DVCMAN_CHANNEL*) curr->data)->channel_id == ChannelId) + if (channel->channel_id == ChannelId) { - return (IWTSVirtualChannel*) curr->data; + found = TRUE; + break; + } + + channel = (DVCMAN_CHANNEL*) ArrayList_GetItem(dvcman->channels, index++); + } + + ArrayList_Unlock(dvcman->channels); + + return (found) ? ((IWTSVirtualChannel*) channel) : NULL; +} + +void* dvcman_get_channel_interface_by_name(IWTSVirtualChannelManager* pChannelMgr, const char* ChannelName) +{ + int i; + BOOL found = FALSE; + void* pInterface = NULL; + DVCMAN_LISTENER* listener; + DVCMAN* dvcman = (DVCMAN*) pChannelMgr; + + for (i = 0; i < dvcman->num_listeners; i++) + { + listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; + + if (strcmp(listener->channel_name, ChannelName) == 0) + { + pInterface = listener->iface.pInterface; + found = TRUE; + break; } } - return NULL; + return (found) ? pInterface : NULL; } IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) @@ -223,7 +204,7 @@ IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) dvcman->iface.FindChannelById = dvcman_find_channel_by_id; dvcman->iface.GetChannelId = dvcman_get_channel_id; dvcman->drdynvc = plugin; - dvcman->channels = list_new(); + dvcman->channels = ArrayList_New(TRUE); return (IWTSVirtualChannelManager*) dvcman; } @@ -238,13 +219,14 @@ int dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args) pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[0], NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); - if (pDVCPluginEntry != NULL) + if (pDVCPluginEntry) { entryPoints.iface.RegisterPlugin = dvcman_register_plugin; entryPoints.iface.GetPlugin = dvcman_get_plugin; entryPoints.iface.GetPluginData = dvcman_get_plugin_data; entryPoints.dvcman = (DVCMAN*) pChannelMgr; entryPoints.args = args; + pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints); } @@ -262,15 +244,25 @@ static void dvcman_channel_free(DVCMAN_CHANNEL* channel) void dvcman_free(IWTSVirtualChannelManager* pChannelMgr) { int i; + int count; IWTSPlugin* pPlugin; DVCMAN_LISTENER* listener; DVCMAN_CHANNEL* channel; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - while ((channel = (DVCMAN_CHANNEL*) list_dequeue(dvcman->channels)) != NULL) - dvcman_channel_free(channel); + ArrayList_Lock(dvcman->channels); - list_free(dvcman->channels); + count = ArrayList_Count(dvcman->channels); + + for (i = 0; i < count; i++) + { + channel = (DVCMAN_CHANNEL*) ArrayList_GetItem(dvcman->channels, i); + dvcman_channel_free(channel); + } + + ArrayList_Unlock(dvcman->channels); + + ArrayList_Free(dvcman->channels); for (i = 0; i < dvcman->num_listeners; i++) { @@ -326,8 +318,7 @@ static int dvcman_close_channel_iface(IWTSVirtualChannel* pChannel) DEBUG_DVC("id=%d", channel->channel_id); - if (list_remove(dvcman->channels, channel) == NULL) - DEBUG_WARN("channel not found"); + ArrayList_Remove(dvcman->channels, channel); dvcman_channel_free(channel); @@ -340,22 +331,25 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel int bAccept; DVCMAN_LISTENER* listener; DVCMAN_CHANNEL* channel; + DrdynvcClientContext* context; IWTSVirtualChannelCallback* pCallback; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; + channel = (DVCMAN_CHANNEL*) malloc(sizeof(DVCMAN_CHANNEL)); + ZeroMemory(channel, sizeof(DVCMAN_CHANNEL)); + + channel->dvcman = dvcman; + channel->channel_id = ChannelId; + channel->channel_name = _strdup(ChannelName); + for (i = 0; i < dvcman->num_listeners; i++) { listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; if (strcmp(listener->channel_name, ChannelName) == 0) { - channel = (DVCMAN_CHANNEL*) malloc(sizeof(DVCMAN_CHANNEL)); - ZeroMemory(channel, sizeof(DVCMAN_CHANNEL)); - channel->iface.Write = dvcman_write_channel; channel->iface.Close = dvcman_close_channel_iface; - channel->dvcman = dvcman; - channel->channel_id = ChannelId; channel->dvc_chan_mutex = CreateMutex(NULL, FALSE, NULL); bAccept = 1; @@ -366,20 +360,32 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel { DEBUG_DVC("listener %s created new channel %d", listener->channel_name, channel->channel_id); + + channel->status = 0; channel->channel_callback = pCallback; - list_add(dvcman->channels, channel); + channel->pInterface = listener->iface.pInterface; + + ArrayList_Add(dvcman->channels, channel); + + context = dvcman->drdynvc->context; + IFCALL(context->OnChannelConnected, context, ChannelName, listener->iface.pInterface); return 0; } else { DEBUG_WARN("channel rejected by plugin"); - dvcman_channel_free(channel); + + channel->status = 1; + ArrayList_Add(dvcman->channels, channel); return 1; } } } + channel->status = 1; + ArrayList_Add(dvcman->channels, channel); + return 1; } @@ -387,10 +393,12 @@ int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelI { DVCMAN_CHANNEL* channel; IWTSVirtualChannel* ichannel; + DrdynvcClientContext* context; + DVCMAN* dvcman = (DVCMAN*) pChannelMgr; channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); - if (channel == NULL) + if (!channel) { DEBUG_WARN("ChannelId %d not found!", ChannelId); return 1; @@ -398,13 +406,22 @@ int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelI if (channel->dvc_data) { - stream_free(channel->dvc_data); + Stream_Free(channel->dvc_data, TRUE); channel->dvc_data = NULL; } - DEBUG_DVC("dvcman_close_channel: channel %d closed", ChannelId); - ichannel = (IWTSVirtualChannel*) channel; - ichannel->Close(ichannel); + if (channel->status == 0) + { + context = dvcman->drdynvc->context; + + IFCALL(context->OnChannelDisconnected, context, channel->channel_name, channel->pInterface); + + DEBUG_DVC("dvcman_close_channel: channel %d closed", ChannelId); + ichannel = (IWTSVirtualChannel*) channel; + ichannel->Close(ichannel); + } + + free(channel->channel_name); return 0; } @@ -415,16 +432,16 @@ int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, UI channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); - if (channel == NULL) + if (!channel) { DEBUG_WARN("ChannelId %d not found!", ChannelId); return 1; } if (channel->dvc_data) - stream_free(channel->dvc_data); + Stream_Free(channel->dvc_data, TRUE); - channel->dvc_data = stream_new(length); + channel->dvc_data = Stream_New(NULL, length); return 0; } @@ -436,7 +453,7 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 C channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); - if (channel == NULL) + if (!channel) { DEBUG_WARN("ChannelId %d not found!", ChannelId); return 1; @@ -445,21 +462,21 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 C if (channel->dvc_data) { /* Fragmented data */ - if (stream_get_length(channel->dvc_data) + data_size > (UINT32) stream_get_size(channel->dvc_data)) + if (Stream_GetPosition(channel->dvc_data) + data_size > (UINT32) Stream_Capacity(channel->dvc_data)) { DEBUG_WARN("data exceeding declared length!"); - stream_free(channel->dvc_data); + Stream_Free(channel->dvc_data, TRUE); channel->dvc_data = NULL; return 1; } - stream_write(channel->dvc_data, data, data_size); + Stream_Write(channel->dvc_data, data, data_size); - if (stream_get_length(channel->dvc_data) >= stream_get_size(channel->dvc_data)) + if (Stream_GetPosition(channel->dvc_data) >= Stream_Capacity(channel->dvc_data)) { error = channel->channel_callback->OnDataReceived(channel->channel_callback, - stream_get_size(channel->dvc_data), stream_get_data(channel->dvc_data)); - stream_free(channel->dvc_data); + Stream_Capacity(channel->dvc_data), Stream_Buffer(channel->dvc_data)); + Stream_Free(channel->dvc_data, TRUE); channel->dvc_data = NULL; } } diff --git a/channels/drdynvc/client/dvcman.h b/channels/drdynvc/client/dvcman.h index c41835a0f..ca886f3af 100644 --- a/channels/drdynvc/client/dvcman.h +++ b/channels/drdynvc/client/dvcman.h @@ -23,8 +23,65 @@ #include #include +#include + #include "drdynvc_main.h" +#define MAX_PLUGINS 32 + +struct _DVCMAN +{ + IWTSVirtualChannelManager iface; + + drdynvcPlugin* drdynvc; + + const char* plugin_names[MAX_PLUGINS]; + IWTSPlugin* plugins[MAX_PLUGINS]; + int num_plugins; + + IWTSListener* listeners[MAX_PLUGINS]; + int num_listeners; + + wArrayList* channels; +}; +typedef struct _DVCMAN DVCMAN; + +struct _DVCMAN_LISTENER +{ + IWTSListener iface; + + DVCMAN* dvcman; + char* channel_name; + UINT32 flags; + IWTSListenerCallback* listener_callback; +}; +typedef struct _DVCMAN_LISTENER DVCMAN_LISTENER; + +struct _DVCMAN_ENTRY_POINTS +{ + IDRDYNVC_ENTRY_POINTS iface; + + DVCMAN* dvcman; + ADDIN_ARGV* args; +}; +typedef struct _DVCMAN_ENTRY_POINTS DVCMAN_ENTRY_POINTS; + +struct _DVCMAN_CHANNEL +{ + IWTSVirtualChannel iface; + + int status; + DVCMAN* dvcman; + void* pInterface; + UINT32 channel_id; + char* channel_name; + IWTSVirtualChannelCallback* channel_callback; + + wStream* dvc_data; + HANDLE dvc_chan_mutex; +}; +typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL; + IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin); int dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args); void dvcman_free(IWTSVirtualChannelManager* pChannelMgr); @@ -34,5 +91,7 @@ int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelI int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, UINT32 length); int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, BYTE* data, UINT32 data_size); +void* dvcman_get_channel_interface_by_name(IWTSVirtualChannelManager* pChannelMgr, const char* ChannelName); + #endif diff --git a/channels/drive/ChannelOptions.cmake b/channels/drive/ChannelOptions.cmake index 717764cf2..0792c1e47 100644 --- a/channels/drive/ChannelOptions.cmake +++ b/channels/drive/ChannelOptions.cmake @@ -3,11 +3,6 @@ set(OPTION_DEFAULT OFF) set(OPTION_CLIENT_DEFAULT ON) set(OPTION_SERVER_DEFAULT OFF) -if(ANDROID) - set(OPTION_CLIENT_DEFAULT OFF) - set(OPTION_SERVER_DEFAULT OFF) -endif() - define_channel_options(NAME "drive" TYPE "device" DESCRIPTION "Drive Redirection Virtual Channel Extension" SPECIFICATIONS "[MS-RDPEFS]" diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c index aa5a3d5f2..3a31c479c 100644 --- a/channels/drive/client/drive_file.c +++ b/channels/drive/client/drive_file.c @@ -382,7 +382,7 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w if (STAT(file->fullpath, &st) != 0) { - stream_write_UINT32(output, 0); /* Length */ + Stream_Write_UINT32(output, 0); /* Length */ return FALSE; } @@ -390,38 +390,38 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w { case FileBasicInformation: /* http://msdn.microsoft.com/en-us/library/cc232094.aspx */ - stream_write_UINT32(output, 36); /* Length */ - stream_check_size(output, 36); - 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 */ - stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ - stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ - stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ + Stream_Write_UINT32(output, 36); /* Length */ + Stream_EnsureRemainingCapacity(output, 36); + 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 */ + Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ + Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ + Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ /* Reserved(4), MUST NOT be added! */ break; case FileStandardInformation: /* http://msdn.microsoft.com/en-us/library/cc232088.aspx */ - stream_write_UINT32(output, 22); /* Length */ - stream_check_size(output, 22); - stream_write_UINT64(output, st.st_size); /* AllocationSize */ - stream_write_UINT64(output, st.st_size); /* EndOfFile */ - stream_write_UINT32(output, st.st_nlink); /* NumberOfLinks */ - stream_write_BYTE(output, file->delete_pending ? 1 : 0); /* DeletePending */ - stream_write_BYTE(output, file->is_dir ? 1 : 0); /* Directory */ + Stream_Write_UINT32(output, 22); /* Length */ + Stream_EnsureRemainingCapacity(output, 22); + Stream_Write_UINT64(output, st.st_size); /* AllocationSize */ + Stream_Write_UINT64(output, st.st_size); /* EndOfFile */ + Stream_Write_UINT32(output, st.st_nlink); /* NumberOfLinks */ + Stream_Write_UINT8(output, file->delete_pending ? 1 : 0); /* DeletePending */ + Stream_Write_UINT8(output, file->is_dir ? 1 : 0); /* Directory */ /* Reserved(2), MUST NOT be added! */ break; case FileAttributeTagInformation: /* http://msdn.microsoft.com/en-us/library/cc232093.aspx */ - stream_write_UINT32(output, 8); /* Length */ - stream_check_size(output, 8); - stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ - stream_write_UINT32(output, 0); /* ReparseTag */ + Stream_Write_UINT32(output, 8); /* Length */ + Stream_EnsureRemainingCapacity(output, 8); + Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ + Stream_Write_UINT32(output, 0); /* ReparseTag */ break; default: - stream_write_UINT32(output, 0); /* Length */ + Stream_Write_UINT32(output, 0); /* Length */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); return FALSE; } @@ -447,11 +447,11 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN { case FileBasicInformation: /* http://msdn.microsoft.com/en-us/library/cc232094.aspx */ - stream_seek_UINT64(input); /* CreationTime */ - stream_seek_UINT64(input); /* LastAccessTime */ - stream_read_UINT64(input, LastWriteTime); - stream_seek_UINT64(input); /* ChangeTime */ - stream_read_UINT32(input, FileAttributes); + Stream_Seek_UINT64(input); /* CreationTime */ + Stream_Seek_UINT64(input); /* LastAccessTime */ + Stream_Read_UINT64(input, LastWriteTime); + Stream_Seek_UINT64(input); /* ChangeTime */ + Stream_Read_UINT32(input, FileAttributes); if (FSTAT(file->fd, &st) != 0) return FALSE; @@ -462,7 +462,11 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN tv[1].tv_usec = 0; #ifndef WIN32 /* TODO on win32 */ - futimes(file->fd, tv); +#ifdef ANDROID + utimes(file->fullpath, tv); +#else + futimes(file->fd, tv); +#endif if (FileAttributes > 0) { @@ -481,7 +485,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN /* http://msdn.microsoft.com/en-us/library/cc232067.aspx */ case FileAllocationInformation: /* http://msdn.microsoft.com/en-us/library/cc232076.aspx */ - stream_read_UINT64(input, size); + Stream_Read_UINT64(input, size); if (ftruncate(file->fd, size) != 0) return FALSE; break; @@ -490,18 +494,18 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN /* http://msdn.microsoft.com/en-us/library/cc232098.aspx */ /* http://msdn.microsoft.com/en-us/library/cc241371.aspx */ if (Length) - stream_read_BYTE(input, file->delete_pending); + Stream_Read_UINT8(input, file->delete_pending); else file->delete_pending = 1; break; case FileRenameInformation: /* http://msdn.microsoft.com/en-us/library/cc232085.aspx */ - stream_seek_BYTE(input); /* ReplaceIfExists */ - stream_seek_BYTE(input); /* RootDirectory */ - stream_read_UINT32(input, FileNameLength); + Stream_Seek_UINT8(input); /* ReplaceIfExists */ + Stream_Seek_UINT8(input); /* RootDirectory */ + Stream_Read_UINT32(input, FileNameLength); - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(input), + status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(input), FileNameLength / 2, &s, 0, NULL, NULL); if (status < 1) @@ -546,8 +550,8 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT if (!file->dir) { - stream_write_UINT32(output, 0); /* Length */ - stream_write_BYTE(output, 0); /* Padding */ + Stream_Write_UINT32(output, 0); /* Length */ + Stream_Write_UINT8(output, 0); /* Padding */ return FALSE; } @@ -585,8 +589,8 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT if (ent == NULL) { DEBUG_SVC(" pattern %s not found.", file->pattern); - stream_write_UINT32(output, 0); /* Length */ - stream_write_BYTE(output, 0); /* Padding */ + Stream_Write_UINT32(output, 0); /* Length */ + Stream_Write_UINT8(output, 0); /* Padding */ return FALSE; } @@ -611,73 +615,73 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT { case FileDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232097.aspx */ - stream_write_UINT32(output, 64 + length); /* Length */ - stream_check_size(output, 64 + length); - stream_write_UINT32(output, 0); /* NextEntryOffset */ - stream_write_UINT32(output, 0); /* FileIndex */ - 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 */ - stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ - stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ - stream_write_UINT64(output, st.st_size); /* EndOfFile */ - stream_write_UINT64(output, st.st_size); /* AllocationSize */ - stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ - stream_write_UINT32(output, length); /* FileNameLength */ - stream_write(output, ent_path, length); + Stream_Write_UINT32(output, 64 + length); /* Length */ + Stream_EnsureRemainingCapacity(output, 64 + length); + Stream_Write_UINT32(output, 0); /* NextEntryOffset */ + Stream_Write_UINT32(output, 0); /* FileIndex */ + 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 */ + Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ + Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ + Stream_Write_UINT64(output, st.st_size); /* EndOfFile */ + Stream_Write_UINT64(output, st.st_size); /* AllocationSize */ + Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ + Stream_Write_UINT32(output, length); /* FileNameLength */ + Stream_Write(output, ent_path, length); break; case FileFullDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232068.aspx */ - stream_write_UINT32(output, 68 + length); /* Length */ - stream_check_size(output, 68 + length); - stream_write_UINT32(output, 0); /* NextEntryOffset */ - stream_write_UINT32(output, 0); /* FileIndex */ - 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 */ - stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ - stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ - stream_write_UINT64(output, st.st_size); /* EndOfFile */ - stream_write_UINT64(output, st.st_size); /* AllocationSize */ - stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ - stream_write_UINT32(output, length); /* FileNameLength */ - stream_write_UINT32(output, 0); /* EaSize */ - stream_write(output, ent_path, length); + Stream_Write_UINT32(output, 68 + length); /* Length */ + Stream_EnsureRemainingCapacity(output, 68 + length); + Stream_Write_UINT32(output, 0); /* NextEntryOffset */ + Stream_Write_UINT32(output, 0); /* FileIndex */ + 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 */ + Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ + Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ + Stream_Write_UINT64(output, st.st_size); /* EndOfFile */ + Stream_Write_UINT64(output, st.st_size); /* AllocationSize */ + Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ + Stream_Write_UINT32(output, length); /* FileNameLength */ + Stream_Write_UINT32(output, 0); /* EaSize */ + Stream_Write(output, ent_path, length); break; case FileBothDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232095.aspx */ - stream_write_UINT32(output, 93 + length); /* Length */ - stream_check_size(output, 93 + length); - stream_write_UINT32(output, 0); /* NextEntryOffset */ - stream_write_UINT32(output, 0); /* FileIndex */ - 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 */ - stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ - stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ - stream_write_UINT64(output, st.st_size); /* EndOfFile */ - stream_write_UINT64(output, st.st_size); /* AllocationSize */ - stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ - stream_write_UINT32(output, length); /* FileNameLength */ - stream_write_UINT32(output, 0); /* EaSize */ - stream_write_BYTE(output, 0); /* ShortNameLength */ + Stream_Write_UINT32(output, 93 + length); /* Length */ + Stream_EnsureRemainingCapacity(output, 93 + length); + Stream_Write_UINT32(output, 0); /* NextEntryOffset */ + Stream_Write_UINT32(output, 0); /* FileIndex */ + 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 */ + Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ + Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ + Stream_Write_UINT64(output, st.st_size); /* EndOfFile */ + Stream_Write_UINT64(output, st.st_size); /* AllocationSize */ + Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ + Stream_Write_UINT32(output, length); /* FileNameLength */ + Stream_Write_UINT32(output, 0); /* EaSize */ + Stream_Write_UINT8(output, 0); /* ShortNameLength */ /* Reserved(1), MUST NOT be added! */ - stream_write_zero(output, 24); /* ShortName */ - stream_write(output, ent_path, length); + Stream_Zero(output, 24); /* ShortName */ + Stream_Write(output, ent_path, length); break; case FileNamesInformation: /* http://msdn.microsoft.com/en-us/library/cc232077.aspx */ - stream_write_UINT32(output, 12 + length); /* Length */ - stream_check_size(output, 12 + length); - stream_write_UINT32(output, 0); /* NextEntryOffset */ - stream_write_UINT32(output, 0); /* FileIndex */ - stream_write_UINT32(output, length); /* FileNameLength */ - stream_write(output, ent_path, length); + Stream_Write_UINT32(output, 12 + length); /* Length */ + Stream_EnsureRemainingCapacity(output, 12 + length); + Stream_Write_UINT32(output, 0); /* NextEntryOffset */ + Stream_Write_UINT32(output, 0); /* FileIndex */ + Stream_Write_UINT32(output, length); /* FileNameLength */ + Stream_Write(output, ent_path, length); break; default: - stream_write_UINT32(output, 0); /* Length */ - stream_write_BYTE(output, 0); /* Padding */ + Stream_Write_UINT32(output, 0); /* Length */ + Stream_Write_UINT8(output, 0); /* Padding */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); ret = FALSE; break; diff --git a/channels/drive/client/drive_file.h b/channels/drive/client/drive_file.h index 60c8cb477..6d90a308a 100644 --- a/channels/drive/client/drive_file.h +++ b/channels/drive/client/drive_file.h @@ -63,6 +63,12 @@ typedef UINT32 mode_t; #define FSTAT fstat #define STATVFS statvfs #define O_LARGEFILE 0 +#elif defined(ANDROID) +#define STAT stat +#define OPEN open +#define LSEEK lseek +#define FSTAT fstat +#define STATVFS statfs #else #define STAT stat64 #define OPEN open64 diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index 8e7d1c8a1..d4baee68c 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -127,13 +127,13 @@ static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp) UINT32 CreateOptions; UINT32 PathLength; - stream_read_UINT32(irp->input, DesiredAccess); - stream_seek(irp->input, 16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */ - stream_read_UINT32(irp->input, CreateDisposition); - stream_read_UINT32(irp->input, CreateOptions); - stream_read_UINT32(irp->input, PathLength); + Stream_Read_UINT32(irp->input, DesiredAccess); + Stream_Seek(irp->input, 16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */ + Stream_Read_UINT32(irp->input, CreateDisposition); + Stream_Read_UINT32(irp->input, CreateOptions); + Stream_Read_UINT32(irp->input, PathLength); - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(irp->input), + status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input), PathLength / 2, &path, 0, NULL, NULL); if (status < 1) @@ -186,8 +186,8 @@ static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp) DEBUG_SVC("%s(%d) created.", file->fullpath, file->id); } - stream_write_UINT32(irp->output, FileId); - stream_write_BYTE(irp->output, Information); + Stream_Write_UINT32(irp->output, FileId); + Stream_Write_UINT8(irp->output, Information); free(path); @@ -214,7 +214,7 @@ static void drive_process_irp_close(DRIVE_DEVICE* disk, IRP* irp) drive_file_free(file); } - stream_write_zero(irp->output, 5); /* Padding(5) */ + Stream_Zero(irp->output, 5); /* Padding(5) */ irp->Complete(irp); } @@ -226,8 +226,8 @@ static void drive_process_irp_read(DRIVE_DEVICE* disk, IRP* irp) UINT64 Offset; BYTE* buffer = NULL; - stream_read_UINT32(irp->input, Length); - stream_read_UINT64(irp->input, Offset); + Stream_Read_UINT32(irp->input, Length); + Stream_Read_UINT64(irp->input, Offset); file = drive_get_file_by_id(disk, irp->FileId); @@ -263,12 +263,12 @@ static void drive_process_irp_read(DRIVE_DEVICE* disk, IRP* irp) } } - stream_write_UINT32(irp->output, Length); + Stream_Write_UINT32(irp->output, Length); if (Length > 0) { - stream_check_size(irp->output, (int) Length); - stream_write(irp->output, buffer, Length); + Stream_EnsureRemainingCapacity(irp->output, (int) Length); + Stream_Write(irp->output, buffer, Length); } free(buffer); @@ -282,9 +282,9 @@ static void drive_process_irp_write(DRIVE_DEVICE* disk, IRP* irp) UINT32 Length; UINT64 Offset; - stream_read_UINT32(irp->input, Length); - stream_read_UINT64(irp->input, Offset); - stream_seek(irp->input, 20); /* Padding */ + Stream_Read_UINT32(irp->input, Length); + Stream_Read_UINT64(irp->input, Offset); + Stream_Seek(irp->input, 20); /* Padding */ file = drive_get_file_by_id(disk, irp->FileId); @@ -302,7 +302,7 @@ static void drive_process_irp_write(DRIVE_DEVICE* disk, IRP* irp) DEBUG_WARN("seek %s(%d) failed.", file->fullpath, file->id); } - else if (!drive_file_write(file, stream_get_tail(irp->input), Length)) + else if (!drive_file_write(file, Stream_Pointer(irp->input), Length)) { irp->IoStatus = STATUS_UNSUCCESSFUL; Length = 0; @@ -314,8 +314,8 @@ static void drive_process_irp_write(DRIVE_DEVICE* disk, IRP* irp) DEBUG_SVC("write %llu-%llu to %s(%d).", Offset, Offset + Length, file->fullpath, file->id); } - stream_write_UINT32(irp->output, Length); - stream_write_BYTE(irp->output, 0); /* Padding */ + Stream_Write_UINT32(irp->output, Length); + Stream_Write_UINT8(irp->output, 0); /* Padding */ irp->Complete(irp); } @@ -325,7 +325,7 @@ static void drive_process_irp_query_information(DRIVE_DEVICE* disk, IRP* irp) DRIVE_FILE* file; UINT32 FsInformationClass; - stream_read_UINT32(irp->input, FsInformationClass); + Stream_Read_UINT32(irp->input, FsInformationClass); file = drive_get_file_by_id(disk, irp->FileId); @@ -355,9 +355,9 @@ static void drive_process_irp_set_information(DRIVE_DEVICE* disk, IRP* irp) UINT32 FsInformationClass; UINT32 Length; - stream_read_UINT32(irp->input, FsInformationClass); - stream_read_UINT32(irp->input, Length); - stream_seek(irp->input, 24); /* Padding */ + Stream_Read_UINT32(irp->input, FsInformationClass); + Stream_Read_UINT32(irp->input, Length); + Stream_Seek(irp->input, 24); /* Padding */ file = drive_get_file_by_id(disk, irp->FileId); @@ -378,7 +378,7 @@ static void drive_process_irp_set_information(DRIVE_DEVICE* disk, IRP* irp) DEBUG_SVC("FsInformationClass %d on %s(%d) ok.", FsInformationClass, file->fullpath, file->id); } - stream_write_UINT32(irp->output, Length); + Stream_Write_UINT32(irp->output, Length); irp->Complete(irp); } @@ -394,7 +394,7 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP* WCHAR* outStr = NULL; int length; - stream_read_UINT32(irp->input, FsInformationClass); + Stream_Read_UINT32(irp->input, FsInformationClass); STATVFS(disk->path, &svfst); STAT(disk->path, &st); @@ -404,64 +404,72 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP* case FileFsVolumeInformation: /* http://msdn.microsoft.com/en-us/library/cc232108.aspx */ length = ConvertToUnicode(CP_UTF8, 0, volumeLabel, -1, &outStr, 0) * 2; - stream_write_UINT32(output, 17 + length); /* Length */ - stream_check_size(output, 17 + length); - stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */ - stream_write_UINT32(output, svfst.f_fsid); /* VolumeSerialNumber */ - stream_write_UINT32(output, length); /* VolumeLabelLength */ - stream_write_BYTE(output, 0); /* SupportsObjects */ + Stream_Write_UINT32(output, 17 + length); /* Length */ + Stream_EnsureRemainingCapacity(output, 17 + length); + Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */ +#ifdef ANDROID + Stream_Write_UINT32(output, svfst.f_fsid.__val[0]); /* VolumeSerialNumber */ +#else + Stream_Write_UINT32(output, svfst.f_fsid); /* VolumeSerialNumber */ +#endif + Stream_Write_UINT32(output, length); /* VolumeLabelLength */ + Stream_Write_UINT8(output, 0); /* SupportsObjects */ /* Reserved(1), MUST NOT be added! */ - stream_write(output, outStr, length); /* VolumeLabel (Unicode) */ + Stream_Write(output, outStr, length); /* VolumeLabel (Unicode) */ free(outStr); break; case FileFsSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232107.aspx */ - stream_write_UINT32(output, 24); /* Length */ - stream_check_size(output, 24); - stream_write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ - stream_write_UINT64(output, svfst.f_bavail); /* AvailableAllocationUnits */ - stream_write_UINT32(output, 1); /* SectorsPerAllocationUnit */ - stream_write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ + Stream_Write_UINT32(output, 24); /* Length */ + Stream_EnsureRemainingCapacity(output, 24); + Stream_Write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ + Stream_Write_UINT64(output, svfst.f_bavail); /* AvailableAllocationUnits */ + Stream_Write_UINT32(output, 1); /* SectorsPerAllocationUnit */ + Stream_Write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ break; case FileFsAttributeInformation: /* http://msdn.microsoft.com/en-us/library/cc232101.aspx */ length = ConvertToUnicode(CP_UTF8, 0, diskType, -1, &outStr, 0) * 2; - stream_write_UINT32(output, 12 + length); /* Length */ - stream_check_size(output, 12 + length); - stream_write_UINT32(output, + Stream_Write_UINT32(output, 12 + length); /* Length */ + Stream_EnsureRemainingCapacity(output, 12 + length); + Stream_Write_UINT32(output, FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ - stream_write_UINT32(output, svfst.f_namemax/*510*/); /* MaximumComponentNameLength */ - stream_write_UINT32(output, length); /* FileSystemNameLength */ - stream_write(output, outStr, length); /* FileSystemName (Unicode) */ +#ifdef ANDROID + Stream_Write_UINT32(output, 255); /* MaximumComponentNameLength */ +#else + Stream_Write_UINT32(output, svfst.f_namemax/*510*/); /* MaximumComponentNameLength */ +#endif + Stream_Write_UINT32(output, length); /* FileSystemNameLength */ + Stream_Write(output, outStr, length); /* FileSystemName (Unicode) */ free(outStr); break; case FileFsFullSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232104.aspx */ - stream_write_UINT32(output, 32); /* Length */ - stream_check_size(output, 32); - stream_write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ - stream_write_UINT64(output, svfst.f_bavail); /* CallerAvailableAllocationUnits */ - stream_write_UINT64(output, svfst.f_bfree); /* AvailableAllocationUnits */ - stream_write_UINT32(output, 1); /* SectorsPerAllocationUnit */ - stream_write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ + Stream_Write_UINT32(output, 32); /* Length */ + Stream_EnsureRemainingCapacity(output, 32); + Stream_Write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ + Stream_Write_UINT64(output, svfst.f_bavail); /* CallerAvailableAllocationUnits */ + Stream_Write_UINT64(output, svfst.f_bfree); /* AvailableAllocationUnits */ + Stream_Write_UINT32(output, 1); /* SectorsPerAllocationUnit */ + Stream_Write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ break; case FileFsDeviceInformation: /* http://msdn.microsoft.com/en-us/library/cc232109.aspx */ - stream_write_UINT32(output, 8); /* Length */ - stream_check_size(output, 8); - stream_write_UINT32(output, FILE_DEVICE_DISK); /* DeviceType */ - stream_write_UINT32(output, 0); /* Characteristics */ + Stream_Write_UINT32(output, 8); /* Length */ + Stream_EnsureRemainingCapacity(output, 8); + Stream_Write_UINT32(output, FILE_DEVICE_DISK); /* DeviceType */ + Stream_Write_UINT32(output, 0); /* Characteristics */ break; default: irp->IoStatus = STATUS_UNSUCCESSFUL; - stream_write_UINT32(output, 0); /* Length */ + Stream_Write_UINT32(output, 0); /* Length */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); break; } @@ -476,10 +484,10 @@ static void drive_process_irp_silent_ignore(DRIVE_DEVICE* disk, IRP* irp) UINT32 FsInformationClass; wStream* output = irp->output; - stream_read_UINT32(irp->input, FsInformationClass); + Stream_Read_UINT32(irp->input, FsInformationClass); DEBUG_SVC("FsInformationClass %d in drive_process_irp_silent_ignore", FsInformationClass); - stream_write_UINT32(output, 0); /* Length */ + Stream_Write_UINT32(output, 0); /* Length */ irp->Complete(irp); } @@ -493,12 +501,12 @@ static void drive_process_irp_query_directory(DRIVE_DEVICE* disk, IRP* irp) UINT32 PathLength; UINT32 FsInformationClass; - stream_read_UINT32(irp->input, FsInformationClass); - stream_read_BYTE(irp->input, InitialQuery); - stream_read_UINT32(irp->input, PathLength); - stream_seek(irp->input, 23); /* Padding */ + Stream_Read_UINT32(irp->input, FsInformationClass); + Stream_Read_UINT8(irp->input, InitialQuery); + Stream_Read_UINT32(irp->input, PathLength); + Stream_Seek(irp->input, 23); /* Padding */ - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(irp->input), + status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input), PathLength / 2, &path, 0, NULL, NULL); if (status < 1) @@ -509,7 +517,7 @@ static void drive_process_irp_query_directory(DRIVE_DEVICE* disk, IRP* irp) if (file == NULL) { irp->IoStatus = STATUS_UNSUCCESSFUL; - stream_write_UINT32(irp->output, 0); /* Length */ + Stream_Write_UINT32(irp->output, 0); /* Length */ DEBUG_WARN("FileId %d not valid.", irp->FileId); } else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path, irp->output)) @@ -537,7 +545,7 @@ static void drive_process_irp_directory_control(DRIVE_DEVICE* disk, IRP* irp) default: DEBUG_WARN("MinorFunction 0x%X not supported", irp->MinorFunction); irp->IoStatus = STATUS_NOT_SUPPORTED; - stream_write_UINT32(irp->output, 0); /* Length */ + Stream_Write_UINT32(irp->output, 0); /* Length */ irp->Complete(irp); break; } @@ -545,7 +553,7 @@ static void drive_process_irp_directory_control(DRIVE_DEVICE* disk, IRP* irp) static void drive_process_irp_device_control(DRIVE_DEVICE* disk, IRP* irp) { - stream_write_UINT32(irp->output, 0); /* OutputBufferLength */ + Stream_Write_UINT32(irp->output, 0); /* OutputBufferLength */ irp->Complete(irp); } @@ -702,10 +710,10 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* disk->device.Free = drive_free; length = strlen(name); - disk->device.data = stream_new(length + 1); + disk->device.data = Stream_New(NULL, length + 1); for (i = 0; i <= length; i++) - stream_write_BYTE(disk->device.data, name[i] < 0 ? '_' : name[i]); + Stream_Write_UINT8(disk->device.data, name[i] < 0 ? '_' : name[i]); disk->path = path; disk->files = list_new(); diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index 4b210b1c5..6e35c1ee9 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -75,12 +75,12 @@ static void parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp) int status; UINT32 PathLength; - stream_seek(irp->input, 28); + Stream_Seek(irp->input, 28); /* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */ /* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */ - stream_read_UINT32(irp->input, PathLength); + Stream_Read_UINT32(irp->input, PathLength); - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(irp->input), + status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input), PathLength / 2, &path, 0, NULL, NULL); if (status < 1) @@ -105,8 +105,8 @@ static void parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp) DEBUG_SVC("%s(%d) created", parallel->path, parallel->file); } - stream_write_UINT32(irp->output, parallel->id); - stream_write_BYTE(irp->output, 0); + Stream_Write_UINT32(irp->output, parallel->id); + Stream_Write_UINT8(irp->output, 0); free(path); @@ -120,7 +120,7 @@ static void parallel_process_irp_close(PARALLEL_DEVICE* parallel, IRP* irp) else DEBUG_SVC("%s(%d) closed", parallel->path, parallel->id); - stream_write_zero(irp->output, 5); /* Padding(5) */ + Stream_Zero(irp->output, 5); /* Padding(5) */ irp->Complete(irp); } @@ -132,8 +132,8 @@ static void parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp) ssize_t status; BYTE* buffer = NULL; - stream_read_UINT32(irp->input, Length); - stream_read_UINT64(irp->input, Offset); + Stream_Read_UINT32(irp->input, Length); + Stream_Read_UINT64(irp->input, Offset); buffer = (BYTE*) malloc(Length); @@ -153,12 +153,12 @@ static void parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp) DEBUG_SVC("read %llu-%llu from %d", Offset, Offset + Length, parallel->id); } - stream_write_UINT32(irp->output, Length); + Stream_Write_UINT32(irp->output, Length); if (Length > 0) { - stream_check_size(irp->output, Length); - stream_write(irp->output, buffer, Length); + Stream_EnsureRemainingCapacity(irp->output, Length); + Stream_Write(irp->output, buffer, Length); } free(buffer); @@ -173,9 +173,9 @@ static void parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp) UINT64 Offset; ssize_t status; - stream_read_UINT32(irp->input, Length); - stream_read_UINT64(irp->input, Offset); - stream_seek(irp->input, 20); /* Padding */ + Stream_Read_UINT32(irp->input, Length); + Stream_Read_UINT64(irp->input, Offset); + Stream_Seek(irp->input, 20); /* Padding */ DEBUG_SVC("Length %u Offset %llu", Length, Offset); @@ -183,7 +183,7 @@ static void parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp) while (len > 0) { - status = write(parallel->file, stream_get_tail(irp->input), len); + status = write(parallel->file, Stream_Pointer(irp->input), len); if (status < 0) { @@ -194,12 +194,12 @@ static void parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp) break; } - stream_seek(irp->input, status); + Stream_Seek(irp->input, status); len -= status; } - stream_write_UINT32(irp->output, Length); - stream_write_BYTE(irp->output, 0); /* Padding */ + Stream_Write_UINT32(irp->output, Length); + Stream_Write_UINT8(irp->output, 0); /* Padding */ irp->Complete(irp); } @@ -207,7 +207,7 @@ static void parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp) static void parallel_process_irp_device_control(PARALLEL_DEVICE* parallel, IRP* irp) { DEBUG_SVC("in"); - stream_write_UINT32(irp->output, 0); /* OutputBufferLength */ + Stream_Write_UINT32(irp->output, 0); /* OutputBufferLength */ irp->Complete(irp); } @@ -319,10 +319,10 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) parallel->device.Free = parallel_free; length = strlen(name); - parallel->device.data = stream_new(length + 1); + parallel->device.data = Stream_New(NULL, length + 1); for (i = 0; i <= length; i++) - stream_write_BYTE(parallel->device.data, name[i] < 0 ? '_' : name[i]); + Stream_Write_UINT8(parallel->device.data, name[i] < 0 ? '_' : name[i]); parallel->path = path; diff --git a/channels/printer/client/printer_main.c b/channels/printer/client/printer_main.c index 57518219f..89e2ffb81 100644 --- a/channels/printer/client/printer_main.c +++ b/channels/printer/client/printer_main.c @@ -68,13 +68,13 @@ static void printer_process_irp_create(PRINTER_DEVICE* printer_dev, IRP* irp) if (printjob) { - stream_write_UINT32(irp->output, printjob->id); /* FileId */ + Stream_Write_UINT32(irp->output, printjob->id); /* FileId */ DEBUG_SVC("printjob id: %d", printjob->id); } else { - stream_write_UINT32(irp->output, 0); /* FileId */ + Stream_Write_UINT32(irp->output, 0); /* FileId */ irp->IoStatus = STATUS_PRINT_QUEUE_FULL; DEBUG_WARN("error creating print job."); @@ -103,7 +103,7 @@ static void printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp) DEBUG_SVC("printjob id %d closed.", irp->FileId); } - stream_write_zero(irp->output, 4); /* Padding(4) */ + Stream_Zero(irp->output, 4); /* Padding(4) */ irp->Complete(irp); } @@ -114,9 +114,9 @@ static void printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) UINT64 Offset; rdpPrintJob* printjob = NULL; - stream_read_UINT32(irp->input, Length); - stream_read_UINT64(irp->input, Offset); - stream_seek(irp->input, 20); /* Padding */ + Stream_Read_UINT32(irp->input, Length); + Stream_Read_UINT64(irp->input, Offset); + Stream_Seek(irp->input, 20); /* Padding */ if (printer_dev->printer) printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId); @@ -130,17 +130,23 @@ static void printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) } else { - printjob->Write(printjob, stream_get_tail(irp->input), Length); + printjob->Write(printjob, Stream_Pointer(irp->input), Length); DEBUG_SVC("printjob id %d written %d bytes.", irp->FileId, Length); } - stream_write_UINT32(irp->output, Length); - stream_write_BYTE(irp->output, 0); /* Padding */ + Stream_Write_UINT32(irp->output, Length); + Stream_Write_UINT8(irp->output, 0); /* Padding */ irp->Complete(irp); } +static void printer_process_irp_device_control(PRINTER_DEVICE* printer_dev, IRP* irp) +{ + Stream_Write_UINT32(irp->output, 0); /* OutputBufferLength */ + irp->Complete(irp); +} + static void printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp) { switch (irp->MajorFunction) @@ -157,6 +163,10 @@ static void printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp) printer_process_irp_write(printer_dev, irp); break; + case IRP_MJ_DEVICE_CONTROL: + printer_process_irp_device_control(printer_dev, irp); + break; + default: DEBUG_WARN("MajorFunction 0x%X not supported", irp->MajorFunction); irp->IoStatus = STATUS_NOT_SUPPORTED; @@ -259,22 +269,22 @@ void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri DriverNameLen = ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, &DriverName, 0) * 2; PrintNameLen = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &PrintName, 0) * 2; - printer_dev->device.data = stream_new(28 + DriverNameLen + PrintNameLen + CachedFieldsLen); + printer_dev->device.data = Stream_New(NULL, 28 + DriverNameLen + PrintNameLen + CachedFieldsLen); - stream_write_UINT32(printer_dev->device.data, Flags); - stream_write_UINT32(printer_dev->device.data, 0); /* CodePage, reserved */ - stream_write_UINT32(printer_dev->device.data, 0); /* PnPNameLen */ - stream_write_UINT32(printer_dev->device.data, DriverNameLen + 2); - stream_write_UINT32(printer_dev->device.data, PrintNameLen + 2); - stream_write_UINT32(printer_dev->device.data, CachedFieldsLen); - stream_write(printer_dev->device.data, DriverName, DriverNameLen); - stream_write_UINT16(printer_dev->device.data, 0); - stream_write(printer_dev->device.data, PrintName, PrintNameLen); - stream_write_UINT16(printer_dev->device.data, 0); + Stream_Write_UINT32(printer_dev->device.data, Flags); + Stream_Write_UINT32(printer_dev->device.data, 0); /* CodePage, reserved */ + Stream_Write_UINT32(printer_dev->device.data, 0); /* PnPNameLen */ + Stream_Write_UINT32(printer_dev->device.data, DriverNameLen + 2); + Stream_Write_UINT32(printer_dev->device.data, PrintNameLen + 2); + Stream_Write_UINT32(printer_dev->device.data, CachedFieldsLen); + Stream_Write(printer_dev->device.data, DriverName, DriverNameLen); + Stream_Write_UINT16(printer_dev->device.data, 0); + Stream_Write(printer_dev->device.data, PrintName, PrintNameLen); + Stream_Write_UINT16(printer_dev->device.data, 0); if (CachedFieldsLen > 0) { - stream_write(printer_dev->device.data, CachedPrinterConfigData, CachedFieldsLen); + Stream_Write(printer_dev->device.data, CachedPrinterConfigData, CachedFieldsLen); } free(DriverName); diff --git a/channels/rail/client/rail_main.c b/channels/rail/client/rail_main.c index f3477cfac..717cbabea 100644 --- a/channels/rail/client/rail_main.c +++ b/channels/rail/client/rail_main.c @@ -43,8 +43,8 @@ void rail_send_channel_data(void* rail_object, void* data, size_t length) wStream* s = NULL; railPlugin* plugin = (railPlugin*) rail_object; - s = stream_new(length); - stream_write(s, data, length); + s = Stream_New(NULL, length); + Stream_Write(s, data, length); svc_plugin_send((rdpSvcPlugin*) plugin, s); } @@ -89,7 +89,7 @@ static void rail_process_receive(rdpSvcPlugin* plugin, wStream* s) { railPlugin* rail = (railPlugin*) plugin; rail_order_recv(rail->rail_order, s); - stream_free(s); + Stream_Free(s, TRUE); } static void rail_process_addin_args(rdpRailOrder* rail_order, rdpSettings* settings) diff --git a/channels/rail/client/rail_orders.c b/channels/rail/client/rail_orders.c index 2533df326..e6bb690ec 100644 --- a/channels/rail/client/rail_orders.c +++ b/channels/rail/client/rail_orders.c @@ -90,24 +90,24 @@ void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, RAIL_ BOOL rail_read_pdu_header(wStream* s, UINT16* orderType, UINT16* orderLength) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT16(s, *orderType); /* orderType (2 bytes) */ - stream_read_UINT16(s, *orderLength); /* orderLength (2 bytes) */ + Stream_Read_UINT16(s, *orderType); /* orderType (2 bytes) */ + Stream_Read_UINT16(s, *orderLength); /* orderLength (2 bytes) */ return TRUE; } void rail_write_pdu_header(wStream* s, UINT16 orderType, UINT16 orderLength) { - stream_write_UINT16(s, orderType); /* orderType (2 bytes) */ - stream_write_UINT16(s, orderLength); /* orderLength (2 bytes) */ + Stream_Write_UINT16(s, orderType); /* orderType (2 bytes) */ + Stream_Write_UINT16(s, orderLength); /* orderLength (2 bytes) */ } wStream* rail_pdu_init(int length) { wStream* s; - s = stream_new(length + RAIL_PDU_HEADER_LENGTH); - stream_seek(s, RAIL_PDU_HEADER_LENGTH); + s = Stream_New(NULL, length + RAIL_PDU_HEADER_LENGTH); + Stream_Seek(s, RAIL_PDU_HEADER_LENGTH); return s; } @@ -115,43 +115,43 @@ void rail_send_pdu(rdpRailOrder* rail_order, wStream* s, UINT16 orderType) { UINT16 orderLength; - orderLength = stream_get_length(s); - stream_set_pos(s, 0); + orderLength = Stream_GetPosition(s); + Stream_SetPosition(s, 0); rail_write_pdu_header(s, orderType, orderLength); - stream_set_pos(s, orderLength); + Stream_SetPosition(s, orderLength); /* send */ DEBUG_RAIL("Sending %s PDU, length:%d", RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength); - rail_send_channel_data(rail_order->plugin, s->buffer, orderLength); + rail_send_channel_data(rail_order->plugin, Stream_Buffer(s), orderLength); } void rail_write_high_contrast(wStream* s, HIGH_CONTRAST* high_contrast) { high_contrast->colorSchemeLength = high_contrast->colorScheme.length + 2; - stream_write_UINT32(s, high_contrast->flags); /* flags (4 bytes) */ - stream_write_UINT32(s, high_contrast->colorSchemeLength); /* colorSchemeLength (4 bytes) */ + Stream_Write_UINT32(s, high_contrast->flags); /* flags (4 bytes) */ + Stream_Write_UINT32(s, high_contrast->colorSchemeLength); /* colorSchemeLength (4 bytes) */ rail_write_unicode_string(s, &high_contrast->colorScheme); /* colorScheme */ } BOOL rail_read_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, handshake->buildNumber); /* buildNumber (4 bytes) */ + Stream_Read_UINT32(s, handshake->buildNumber); /* buildNumber (4 bytes) */ return TRUE; } BOOL rail_read_server_exec_result_order(wStream* s, RAIL_EXEC_RESULT_ORDER* exec_result) { - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT16(s, exec_result->flags); /* flags (2 bytes) */ - stream_read_UINT16(s, exec_result->execResult); /* execResult (2 bytes) */ - stream_read_UINT32(s, exec_result->rawResult); /* rawResult (4 bytes) */ - stream_seek_UINT16(s); /* padding (2 bytes) */ + Stream_Read_UINT16(s, exec_result->flags); /* flags (2 bytes) */ + Stream_Read_UINT16(s, exec_result->execResult); /* execResult (2 bytes) */ + Stream_Read_UINT32(s, exec_result->rawResult); /* rawResult (4 bytes) */ + Stream_Seek_UINT16(s); /* padding (2 bytes) */ return rail_read_unicode_string(s, &exec_result->exeOrFile); /* exeOrFile */ } @@ -159,10 +159,10 @@ BOOL rail_read_server_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam) { BYTE body; - if (stream_get_left(s) < 5) + if (Stream_GetRemainingLength(s) < 5) return FALSE; - stream_read_UINT32(s, sysparam->param); /* systemParam (4 bytes) */ - stream_read_BYTE(s, body); /* body (1 byte) */ + Stream_Read_UINT32(s, sysparam->param); /* systemParam (4 bytes) */ + Stream_Read_UINT8(s, body); /* body (1 byte) */ switch (sysparam->param) { @@ -182,42 +182,42 @@ BOOL rail_read_server_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam) BOOL rail_read_server_minmaxinfo_order(wStream* s, RAIL_MINMAXINFO_ORDER* minmaxinfo) { - if (stream_get_left(s) < 20) + if (Stream_GetRemainingLength(s) < 20) return FALSE; - stream_read_UINT32(s, minmaxinfo->windowId); /* windowId (4 bytes) */ - stream_read_UINT16(s, minmaxinfo->maxWidth); /* maxWidth (2 bytes) */ - stream_read_UINT16(s, minmaxinfo->maxHeight); /* maxHeight (2 bytes) */ - stream_read_UINT16(s, minmaxinfo->maxPosX); /* maxPosX (2 bytes) */ - stream_read_UINT16(s, minmaxinfo->maxPosY); /* maxPosY (2 bytes) */ - stream_read_UINT16(s, minmaxinfo->minTrackWidth); /* minTrackWidth (2 bytes) */ - 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) */ + Stream_Read_UINT32(s, minmaxinfo->windowId); /* windowId (4 bytes) */ + Stream_Read_UINT16(s, minmaxinfo->maxWidth); /* maxWidth (2 bytes) */ + Stream_Read_UINT16(s, minmaxinfo->maxHeight); /* maxHeight (2 bytes) */ + Stream_Read_UINT16(s, minmaxinfo->maxPosX); /* maxPosX (2 bytes) */ + Stream_Read_UINT16(s, minmaxinfo->maxPosY); /* maxPosY (2 bytes) */ + Stream_Read_UINT16(s, minmaxinfo->minTrackWidth); /* minTrackWidth (2 bytes) */ + 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 TRUE; } BOOL rail_read_server_localmovesize_order(wStream* s, RAIL_LOCALMOVESIZE_ORDER* localmovesize) { UINT16 isMoveSizeStart; - if (stream_get_left(s) < 12) + if (Stream_GetRemainingLength(s) < 12) return FALSE; - stream_read_UINT32(s, localmovesize->windowId); /* windowId (4 bytes) */ + Stream_Read_UINT32(s, localmovesize->windowId); /* windowId (4 bytes) */ - stream_read_UINT16(s, isMoveSizeStart); /* isMoveSizeStart (2 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) */ + 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 TRUE; } BOOL rail_read_server_get_appid_resp_order(wStream* s, RAIL_GET_APPID_RESP_ORDER* get_appid_resp) { - if (stream_get_left(s) < 516) + if (Stream_GetRemainingLength(s) < 516) return FALSE; - stream_read_UINT32(s, get_appid_resp->windowId); /* windowId (4 bytes) */ - stream_read(s, &get_appid_resp->applicationIdBuffer[0], 512); /* applicationId (256 UNICODE chars) */ + Stream_Read_UINT32(s, get_appid_resp->windowId); /* windowId (4 bytes) */ + Stream_Read(s, &get_appid_resp->applicationIdBuffer[0], 512); /* applicationId (256 UNICODE chars) */ get_appid_resp->applicationId.length = 512; get_appid_resp->applicationId.string = &get_appid_resp->applicationIdBuffer[0]; @@ -226,28 +226,28 @@ BOOL rail_read_server_get_appid_resp_order(wStream* s, RAIL_GET_APPID_RESP_ORDER BOOL rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbar_info) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */ + Stream_Read_UINT32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */ return TRUE; } void rail_write_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake) { - stream_write_UINT32(s, handshake->buildNumber); /* buildNumber (4 bytes) */ + Stream_Write_UINT32(s, handshake->buildNumber); /* buildNumber (4 bytes) */ } void rail_write_client_status_order(wStream* s, RAIL_CLIENT_STATUS_ORDER* client_status) { - stream_write_UINT32(s, client_status->flags); /* flags (4 bytes) */ + Stream_Write_UINT32(s, client_status->flags); /* flags (4 bytes) */ } void rail_write_client_exec_order(wStream* s, RAIL_EXEC_ORDER* exec) { - stream_write_UINT16(s, exec->flags); /* flags (2 bytes) */ - 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) */ + Stream_Write_UINT16(s, exec->flags); /* flags (2 bytes) */ + 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) */ rail_write_unicode_string_value(s, &exec->exeOrFile); /* exeOrFile */ rail_write_unicode_string_value(s, &exec->workingDir); /* workingDir */ rail_write_unicode_string_value(s, &exec->arguments); /* arguments */ @@ -256,49 +256,49 @@ void rail_write_client_exec_order(wStream* s, RAIL_EXEC_ORDER* exec) void rail_write_client_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam) { BYTE body; - stream_write_UINT32(s, sysparam->param); /* systemParam (4 bytes) */ + Stream_Write_UINT32(s, sysparam->param); /* systemParam (4 bytes) */ switch (sysparam->param) { case SPI_SET_DRAG_FULL_WINDOWS: body = sysparam->dragFullWindows; - stream_write_BYTE(s, body); + Stream_Write_UINT8(s, body); break; case SPI_SET_KEYBOARD_CUES: body = sysparam->keyboardCues; - stream_write_BYTE(s, body); + Stream_Write_UINT8(s, body); break; case SPI_SET_KEYBOARD_PREF: body = sysparam->keyboardPref; - stream_write_BYTE(s, body); + Stream_Write_UINT8(s, body); break; case SPI_SET_MOUSE_BUTTON_SWAP: body = sysparam->mouseButtonSwap; - stream_write_BYTE(s, body); + Stream_Write_UINT8(s, body); break; case SPI_SET_WORK_AREA: - stream_write_UINT16(s, sysparam->workArea.left); /* left (2 bytes) */ - stream_write_UINT16(s, sysparam->workArea.top); /* top (2 bytes) */ - stream_write_UINT16(s, sysparam->workArea.right); /* right (2 bytes) */ - stream_write_UINT16(s, sysparam->workArea.bottom); /* bottom (2 bytes) */ + Stream_Write_UINT16(s, sysparam->workArea.left); /* left (2 bytes) */ + Stream_Write_UINT16(s, sysparam->workArea.top); /* top (2 bytes) */ + Stream_Write_UINT16(s, sysparam->workArea.right); /* right (2 bytes) */ + Stream_Write_UINT16(s, sysparam->workArea.bottom); /* bottom (2 bytes) */ break; case SPI_DISPLAY_CHANGE: - stream_write_UINT16(s, sysparam->displayChange.left); /* left (2 bytes) */ - stream_write_UINT16(s, sysparam->displayChange.top); /* top (2 bytes) */ - stream_write_UINT16(s, sysparam->displayChange.right); /* right (2 bytes) */ - stream_write_UINT16(s, sysparam->displayChange.bottom); /* bottom (2 bytes) */ + Stream_Write_UINT16(s, sysparam->displayChange.left); /* left (2 bytes) */ + Stream_Write_UINT16(s, sysparam->displayChange.top); /* top (2 bytes) */ + Stream_Write_UINT16(s, sysparam->displayChange.right); /* right (2 bytes) */ + Stream_Write_UINT16(s, sysparam->displayChange.bottom); /* bottom (2 bytes) */ break; case SPI_TASKBAR_POS: - stream_write_UINT16(s, sysparam->taskbarPos.left); /* left (2 bytes) */ - stream_write_UINT16(s, sysparam->taskbarPos.top); /* top (2 bytes) */ - stream_write_UINT16(s, sysparam->taskbarPos.right); /* right (2 bytes) */ - stream_write_UINT16(s, sysparam->taskbarPos.bottom); /* bottom (2 bytes) */ + Stream_Write_UINT16(s, sysparam->taskbarPos.left); /* left (2 bytes) */ + Stream_Write_UINT16(s, sysparam->taskbarPos.top); /* top (2 bytes) */ + Stream_Write_UINT16(s, sysparam->taskbarPos.right); /* right (2 bytes) */ + Stream_Write_UINT16(s, sysparam->taskbarPos.bottom); /* bottom (2 bytes) */ break; case SPI_SET_HIGH_CONTRAST: @@ -311,49 +311,49 @@ void rail_write_client_activate_order(wStream* s, RAIL_ACTIVATE_ORDER* activate) { BYTE enabled; - stream_write_UINT32(s, activate->windowId); /* windowId (4 bytes) */ + Stream_Write_UINT32(s, activate->windowId); /* windowId (4 bytes) */ enabled = activate->enabled; - stream_write_BYTE(s, enabled); /* enabled (1 byte) */ + Stream_Write_UINT8(s, enabled); /* enabled (1 byte) */ } void rail_write_client_sysmenu_order(wStream* s, RAIL_SYSMENU_ORDER* sysmenu) { - stream_write_UINT32(s, sysmenu->windowId); /* windowId (4 bytes) */ - stream_write_UINT16(s, sysmenu->left); /* left (2 bytes) */ - stream_write_UINT16(s, sysmenu->top); /* top (2 bytes) */ + Stream_Write_UINT32(s, sysmenu->windowId); /* windowId (4 bytes) */ + Stream_Write_UINT16(s, sysmenu->left); /* left (2 bytes) */ + Stream_Write_UINT16(s, sysmenu->top); /* top (2 bytes) */ } void rail_write_client_syscommand_order(wStream* s, RAIL_SYSCOMMAND_ORDER* syscommand) { - stream_write_UINT32(s, syscommand->windowId); /* windowId (4 bytes) */ - stream_write_UINT16(s, syscommand->command); /* command (2 bytes) */ + Stream_Write_UINT32(s, syscommand->windowId); /* windowId (4 bytes) */ + Stream_Write_UINT16(s, syscommand->command); /* command (2 bytes) */ } void rail_write_client_notify_event_order(wStream* s, RAIL_NOTIFY_EVENT_ORDER* notify_event) { - stream_write_UINT32(s, notify_event->windowId); /* windowId (4 bytes) */ - stream_write_UINT32(s, notify_event->notifyIconId); /* notifyIconId (4 bytes) */ - stream_write_UINT32(s, notify_event->message); /* notifyIconId (4 bytes) */ + Stream_Write_UINT32(s, notify_event->windowId); /* windowId (4 bytes) */ + Stream_Write_UINT32(s, notify_event->notifyIconId); /* notifyIconId (4 bytes) */ + Stream_Write_UINT32(s, notify_event->message); /* notifyIconId (4 bytes) */ } void rail_write_client_window_move_order(wStream* s, RAIL_WINDOW_MOVE_ORDER* window_move) { - stream_write_UINT32(s, window_move->windowId); /* windowId (4 bytes) */ - stream_write_UINT16(s, window_move->left); /* left (2 bytes) */ - stream_write_UINT16(s, window_move->top); /* top (2 bytes) */ - stream_write_UINT16(s, window_move->right); /* right (2 bytes) */ - stream_write_UINT16(s, window_move->bottom); /* bottom (2 bytes) */ + Stream_Write_UINT32(s, window_move->windowId); /* windowId (4 bytes) */ + Stream_Write_UINT16(s, window_move->left); /* left (2 bytes) */ + Stream_Write_UINT16(s, window_move->top); /* top (2 bytes) */ + Stream_Write_UINT16(s, window_move->right); /* right (2 bytes) */ + Stream_Write_UINT16(s, window_move->bottom); /* bottom (2 bytes) */ } void rail_write_client_get_appid_req_order(wStream* s, RAIL_GET_APPID_REQ_ORDER* get_appid_req) { - stream_write_UINT32(s, get_appid_req->windowId); /* windowId (4 bytes) */ + Stream_Write_UINT32(s, get_appid_req->windowId); /* windowId (4 bytes) */ } void rail_write_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbar_info) { - stream_write_UINT32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */ + Stream_Write_UINT32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */ } BOOL rail_recv_handshake_order(rdpRailOrder* rail_order, wStream* s) @@ -513,7 +513,7 @@ void rail_send_handshake_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_HANDSHAKE_ORDER_LENGTH); rail_write_handshake_order(s, &rail_order->handshake); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_HANDSHAKE); - stream_free(s) ; + Stream_Free(s, TRUE); } void rail_send_client_status_order(rdpRailOrder* rail_order) @@ -522,7 +522,7 @@ void rail_send_client_status_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_CLIENT_STATUS_ORDER_LENGTH); rail_write_client_status_order(s, &rail_order->client_status); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_CLIENT_STATUS); - stream_free(s) ; + Stream_Free(s, TRUE); } void rail_send_client_exec_order(rdpRailOrder* rail_order) @@ -538,7 +538,7 @@ void rail_send_client_exec_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_EXEC_ORDER_LENGTH); rail_write_client_exec_order(s, &rail_order->exec); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_EXEC); - stream_free(s) ; + Stream_Free(s, TRUE); } void rail_send_client_sysparam_order(rdpRailOrder* rail_order) @@ -571,7 +571,7 @@ void rail_send_client_sysparam_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8); rail_write_client_sysparam_order(s, &rail_order->sysparam); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_SYSPARAM); - stream_free(s) ; + Stream_Free(s, TRUE); } void rail_send_client_sysparams_order(rdpRailOrder* rail_order) @@ -625,7 +625,7 @@ void rail_send_client_activate_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_ACTIVATE_ORDER_LENGTH); rail_write_client_activate_order(s, &rail_order->activate); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_ACTIVATE); - stream_free(s) ; + Stream_Free(s, TRUE); } void rail_send_client_sysmenu_order(rdpRailOrder* rail_order) @@ -634,7 +634,7 @@ void rail_send_client_sysmenu_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_SYSMENU_ORDER_LENGTH); rail_write_client_sysmenu_order(s, &rail_order->sysmenu); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_SYSMENU); - stream_free(s) ; + Stream_Free(s, TRUE); } void rail_send_client_syscommand_order(rdpRailOrder* rail_order) @@ -643,7 +643,7 @@ void rail_send_client_syscommand_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_SYSCOMMAND_ORDER_LENGTH); rail_write_client_syscommand_order(s, &rail_order->syscommand); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_SYSCOMMAND); - stream_free(s) ; + Stream_Free(s, TRUE); } void rail_send_client_notify_event_order(rdpRailOrder* rail_order) @@ -652,7 +652,7 @@ void rail_send_client_notify_event_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_NOTIFY_EVENT_ORDER_LENGTH); rail_write_client_notify_event_order(s, &rail_order->notify_event); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_NOTIFY_EVENT); - stream_free(s) ; + Stream_Free(s, TRUE); } void rail_send_client_window_move_order(rdpRailOrder* rail_order) @@ -661,7 +661,7 @@ void rail_send_client_window_move_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_WINDOW_MOVE_ORDER_LENGTH); rail_write_client_window_move_order(s, &rail_order->window_move); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_WINDOW_MOVE); - stream_free(s) ; + Stream_Free(s, TRUE); } void rail_send_client_get_appid_req_order(rdpRailOrder* rail_order) @@ -670,7 +670,7 @@ void rail_send_client_get_appid_req_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_GET_APPID_REQ_ORDER_LENGTH); rail_write_client_get_appid_req_order(s, &rail_order->get_appid_req); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_GET_APPID_REQ); - stream_free(s) ; + Stream_Free(s, TRUE); } void rail_send_client_langbar_info_order(rdpRailOrder* rail_order) @@ -679,7 +679,7 @@ void rail_send_client_langbar_info_order(rdpRailOrder* rail_order) s = rail_pdu_init(RAIL_LANGBAR_INFO_ORDER_LENGTH); rail_write_langbar_info_order(s, &rail_order->langbar_info); rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_LANGBAR_INFO); - stream_free(s); + Stream_Free(s, TRUE); } rdpRailOrder* rail_order_new() diff --git a/channels/rdpdr/client/irp.c b/channels/rdpdr/client/irp.c index 19e83879e..e2cdd6a98 100644 --- a/channels/rdpdr/client/irp.c +++ b/channels/rdpdr/client/irp.c @@ -39,8 +39,8 @@ static void irp_free(IRP* irp) { DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId); - stream_free(irp->input); - stream_free(irp->output); + Stream_Free(irp->input, TRUE); + Stream_Free(irp->output, TRUE); _aligned_free(irp); } @@ -51,10 +51,10 @@ static void irp_complete(IRP* irp) DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId); - pos = stream_get_pos(irp->output); - stream_set_pos(irp->output, 12); - stream_write_UINT32(irp->output, irp->IoStatus); - stream_set_pos(irp->output, pos); + pos = Stream_GetPosition(irp->output); + Stream_SetPosition(irp->output, 12); + Stream_Write_UINT32(irp->output, irp->IoStatus); + Stream_SetPosition(irp->output, pos); svc_plugin_send(irp->devman->plugin, irp->output); irp->output = NULL; @@ -68,7 +68,7 @@ IRP* irp_new(DEVMAN* devman, wStream* data_in) UINT32 DeviceId; DEVICE* device; - stream_read_UINT32(data_in, DeviceId); + Stream_Read_UINT32(data_in, DeviceId); device = devman_get_device_by_id(devman, DeviceId); if (device == NULL) @@ -82,18 +82,18 @@ IRP* irp_new(DEVMAN* devman, wStream* data_in) irp->device = device; irp->devman = devman; - stream_read_UINT32(data_in, irp->FileId); - stream_read_UINT32(data_in, irp->CompletionId); - stream_read_UINT32(data_in, irp->MajorFunction); - stream_read_UINT32(data_in, irp->MinorFunction); + Stream_Read_UINT32(data_in, irp->FileId); + Stream_Read_UINT32(data_in, irp->CompletionId); + Stream_Read_UINT32(data_in, irp->MajorFunction); + Stream_Read_UINT32(data_in, irp->MinorFunction); irp->input = data_in; - irp->output = stream_new(256); - stream_write_UINT16(irp->output, RDPDR_CTYP_CORE); - stream_write_UINT16(irp->output, PAKID_CORE_DEVICE_IOCOMPLETION); - stream_write_UINT32(irp->output, DeviceId); - stream_write_UINT32(irp->output, irp->CompletionId); - stream_seek_UINT32(irp->output); /* IoStatus */ + irp->output = Stream_New(NULL, 256); + Stream_Write_UINT16(irp->output, RDPDR_CTYP_CORE); + Stream_Write_UINT16(irp->output, PAKID_CORE_DEVICE_IOCOMPLETION); + Stream_Write_UINT32(irp->output, DeviceId); + Stream_Write_UINT32(irp->output, irp->CompletionId); + Stream_Seek_UINT32(irp->output); /* IoStatus */ irp->Complete = irp_complete; irp->Discard = irp_free; diff --git a/channels/rdpdr/client/rdpdr_capabilities.c b/channels/rdpdr/client/rdpdr_capabilities.c index 081f035cd..025977c92 100644 --- a/channels/rdpdr/client/rdpdr_capabilities.c +++ b/channels/rdpdr/client/rdpdr_capabilities.c @@ -35,9 +35,9 @@ /* Output device redirection capability set header */ static void rdpdr_write_capset_header(wStream* data_out, UINT16 capabilityType, UINT16 capabilityLength, UINT32 version) { - stream_write_UINT16(data_out, capabilityType); - stream_write_UINT16(data_out, capabilityLength); - stream_write_UINT32(data_out, version); + Stream_Write_UINT16(data_out, capabilityType); + Stream_Write_UINT16(data_out, capabilityLength); + Stream_Write_UINT32(data_out, version); } /* Output device direction general capability set */ @@ -45,16 +45,16 @@ static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, wStream* data_out) { rdpdr_write_capset_header(data_out, CAP_GENERAL_TYPE, 44, GENERAL_CAPABILITY_VERSION_02); - stream_write_UINT32(data_out, 0); /* osType, ignored on receipt */ - stream_write_UINT32(data_out, 0); /* osVersion, unused and must be set to zero */ - stream_write_UINT16(data_out, 1); /* protocolMajorVersion, must be set to 1 */ - stream_write_UINT16(data_out, RDPDR_MINOR_RDP_VERSION_5_2); /* protocolMinorVersion */ - stream_write_UINT32(data_out, 0x0000FFFF); /* ioCode1 */ - stream_write_UINT32(data_out, 0); /* ioCode2, must be set to zero, reserved for future use */ - stream_write_UINT32(data_out, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU | RDPDR_USER_LOGGEDON_PDU); /* extendedPDU */ - stream_write_UINT32(data_out, ENABLE_ASYNCIO); /* extraFlags1 */ - stream_write_UINT32(data_out, 0); /* extraFlags2, must be set to zero, reserved for future use */ - stream_write_UINT32(data_out, 0); /* SpecialTypeDeviceCap, number of special devices to be redirected before logon */ + Stream_Write_UINT32(data_out, 0); /* osType, ignored on receipt */ + Stream_Write_UINT32(data_out, 0); /* osVersion, unused and must be set to zero */ + Stream_Write_UINT16(data_out, 1); /* protocolMajorVersion, must be set to 1 */ + Stream_Write_UINT16(data_out, RDPDR_MINOR_RDP_VERSION_5_2); /* protocolMinorVersion */ + Stream_Write_UINT32(data_out, 0x0000FFFF); /* ioCode1 */ + Stream_Write_UINT32(data_out, 0); /* ioCode2, must be set to zero, reserved for future use */ + Stream_Write_UINT32(data_out, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU | RDPDR_USER_LOGGEDON_PDU); /* extendedPDU */ + Stream_Write_UINT32(data_out, ENABLE_ASYNCIO); /* extraFlags1 */ + Stream_Write_UINT32(data_out, 0); /* extraFlags2, must be set to zero, reserved for future use */ + Stream_Write_UINT32(data_out, 0); /* SpecialTypeDeviceCap, number of special devices to be redirected before logon */ } /* Process device direction general capability set */ @@ -62,8 +62,8 @@ static void rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* data_in) { UINT16 capabilityLength; - stream_read_UINT16(data_in, capabilityLength); - stream_seek(data_in, capabilityLength - 4); + Stream_Read_UINT16(data_in, capabilityLength); + Stream_Seek(data_in, capabilityLength - 4); } /* Output printer direction capability set */ @@ -77,8 +77,8 @@ static void rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* data_in) { UINT16 capabilityLength; - stream_read_UINT16(data_in, capabilityLength); - stream_seek(data_in, capabilityLength - 4); + Stream_Read_UINT16(data_in, capabilityLength); + Stream_Seek(data_in, capabilityLength - 4); } /* Output port redirection capability set */ @@ -92,8 +92,8 @@ static void rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* data_in) { UINT16 capabilityLength; - stream_read_UINT16(data_in, capabilityLength); - stream_seek(data_in, capabilityLength - 4); + Stream_Read_UINT16(data_in, capabilityLength); + Stream_Seek(data_in, capabilityLength - 4); } /* Output drive redirection capability set */ @@ -107,8 +107,8 @@ static void rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* data_in) { UINT16 capabilityLength; - stream_read_UINT16(data_in, capabilityLength); - stream_seek(data_in, capabilityLength - 4); + Stream_Read_UINT16(data_in, capabilityLength); + Stream_Seek(data_in, capabilityLength - 4); } /* Output smart card redirection capability set */ @@ -122,8 +122,8 @@ static void rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* data_in) { UINT16 capabilityLength; - stream_read_UINT16(data_in, capabilityLength); - stream_seek(data_in, capabilityLength - 4); + Stream_Read_UINT16(data_in, capabilityLength); + Stream_Seek(data_in, capabilityLength - 4); } void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* data_in) @@ -132,12 +132,12 @@ void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* data_in) UINT16 numCapabilities; UINT16 capabilityType; - stream_read_UINT16(data_in, numCapabilities); - stream_seek(data_in, 2); /* pad (2 bytes) */ + Stream_Read_UINT16(data_in, numCapabilities); + Stream_Seek(data_in, 2); /* pad (2 bytes) */ for(i = 0; i < numCapabilities; i++) { - stream_read_UINT16(data_in, capabilityType); + Stream_Read_UINT16(data_in, capabilityType); switch (capabilityType) { @@ -172,13 +172,13 @@ void rdpdr_send_capability_response(rdpdrPlugin* rdpdr) { wStream* data_out; - data_out = stream_new(256); + data_out = Stream_New(NULL, 256); - stream_write_UINT16(data_out, RDPDR_CTYP_CORE); - stream_write_UINT16(data_out, PAKID_CORE_CLIENT_CAPABILITY); + Stream_Write_UINT16(data_out, RDPDR_CTYP_CORE); + Stream_Write_UINT16(data_out, PAKID_CORE_CLIENT_CAPABILITY); - stream_write_UINT16(data_out, 5); /* numCapabilities */ - stream_write_UINT16(data_out, 0); /* pad */ + Stream_Write_UINT16(data_out, 5); /* numCapabilities */ + Stream_Write_UINT16(data_out, 0); /* pad */ rdpdr_write_general_capset(rdpdr, data_out); rdpdr_write_printer_capset(rdpdr, data_out); diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index 110701103..bcf19df82 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -66,9 +66,9 @@ static void rdpdr_process_connect(rdpSvcPlugin* plugin) static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* data_in) { - stream_read_UINT16(data_in, rdpdr->versionMajor); - stream_read_UINT16(data_in, rdpdr->versionMinor); - stream_read_UINT32(data_in, rdpdr->clientID); + Stream_Read_UINT16(data_in, rdpdr->versionMajor); + Stream_Read_UINT16(data_in, rdpdr->versionMinor); + Stream_Read_UINT32(data_in, rdpdr->clientID); DEBUG_SVC("version %d.%d clientID %d", rdpdr->versionMajor, rdpdr->versionMinor, rdpdr->clientID); } @@ -77,14 +77,14 @@ static void rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr) { wStream* data_out; - data_out = stream_new(12); + data_out = Stream_New(NULL, 12); - stream_write_UINT16(data_out, RDPDR_CTYP_CORE); - stream_write_UINT16(data_out, PAKID_CORE_CLIENTID_CONFIRM); + Stream_Write_UINT16(data_out, RDPDR_CTYP_CORE); + Stream_Write_UINT16(data_out, PAKID_CORE_CLIENTID_CONFIRM); - stream_write_UINT16(data_out, rdpdr->versionMajor); - stream_write_UINT16(data_out, rdpdr->versionMinor); - stream_write_UINT32(data_out, (UINT32) rdpdr->clientID); + Stream_Write_UINT16(data_out, rdpdr->versionMajor); + Stream_Write_UINT16(data_out, rdpdr->versionMinor); + Stream_Write_UINT32(data_out, (UINT32) rdpdr->clientID); svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out); } @@ -100,16 +100,16 @@ static void rdpdr_send_client_name_request(rdpdrPlugin* rdpdr) computerNameLenW = ConvertToUnicode(CP_UTF8, 0, rdpdr->computerName, -1, &computerNameW, 0) * 2; - data_out = stream_new(16 + computerNameLenW + 2); + data_out = Stream_New(NULL, 16 + computerNameLenW + 2); - stream_write_UINT16(data_out, RDPDR_CTYP_CORE); - stream_write_UINT16(data_out, PAKID_CORE_CLIENT_NAME); + Stream_Write_UINT16(data_out, RDPDR_CTYP_CORE); + Stream_Write_UINT16(data_out, PAKID_CORE_CLIENT_NAME); - stream_write_UINT32(data_out, 1); /* unicodeFlag, 0 for ASCII and 1 for Unicode */ - stream_write_UINT32(data_out, 0); /* codePage, must be set to zero */ - stream_write_UINT32(data_out, computerNameLenW + 2); /* computerNameLen, including null terminator */ - stream_write(data_out, computerNameW, computerNameLenW); - stream_write_UINT16(data_out, 0); /* null terminator */ + Stream_Write_UINT32(data_out, 1); /* unicodeFlag, 0 for ASCII and 1 for Unicode */ + Stream_Write_UINT32(data_out, 0); /* codePage, must be set to zero */ + Stream_Write_UINT32(data_out, computerNameLenW + 2); /* computerNameLen, including null terminator */ + Stream_Write(data_out, computerNameW, computerNameLenW); + Stream_Write_UINT16(data_out, 0); /* null terminator */ free(computerNameW); @@ -122,9 +122,9 @@ static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* d UINT16 versionMinor; UINT32 clientID; - stream_read_UINT16(data_in, versionMajor); - stream_read_UINT16(data_in, versionMinor); - stream_read_UINT32(data_in, clientID); + Stream_Read_UINT16(data_in, versionMajor); + Stream_Read_UINT16(data_in, versionMinor); + Stream_Read_UINT32(data_in, clientID); if (versionMajor != rdpdr->versionMajor || versionMinor != rdpdr->versionMinor) { @@ -152,14 +152,14 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use DEVICE* device; LIST_ITEM* item; - data_out = stream_new(256); + data_out = Stream_New(NULL, 256); - stream_write_UINT16(data_out, RDPDR_CTYP_CORE); - stream_write_UINT16(data_out, PAKID_CORE_DEVICELIST_ANNOUNCE); + Stream_Write_UINT16(data_out, RDPDR_CTYP_CORE); + Stream_Write_UINT16(data_out, PAKID_CORE_DEVICELIST_ANNOUNCE); - count_pos = stream_get_pos(data_out); + count_pos = Stream_GetPosition(data_out); count = 0; - stream_seek_UINT32(data_out); /* deviceCount */ + Stream_Seek_UINT32(data_out); /* deviceCount */ for (item = rdpdr->devman->devices->head; item; item = item->next) { @@ -175,27 +175,27 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use if ((rdpdr->versionMinor == 0x0005) || (device->type == RDPDR_DTYP_SMARTCARD) || user_loggedon) { - data_len = (device->data == NULL ? 0 : stream_get_length(device->data)); - stream_check_size(data_out, 20 + data_len); + data_len = (device->data == NULL ? 0 : Stream_GetPosition(device->data)); + Stream_EnsureRemainingCapacity(data_out, 20 + data_len); - stream_write_UINT32(data_out, device->type); /* deviceType */ - stream_write_UINT32(data_out, device->id); /* deviceID */ - strncpy((char*) stream_get_tail(data_out), device->name, 8); + Stream_Write_UINT32(data_out, device->type); /* deviceType */ + Stream_Write_UINT32(data_out, device->id); /* deviceID */ + strncpy((char*) Stream_Pointer(data_out), device->name, 8); for (i = 0; i < 8; i++) { - stream_peek_BYTE(data_out, c); + Stream_Peek_UINT8(data_out, c); if (c > 0x7F) - stream_write_BYTE(data_out, '_'); + Stream_Write_UINT8(data_out, '_'); else - stream_seek_BYTE(data_out); + Stream_Seek_UINT8(data_out); } - stream_write_UINT32(data_out, data_len); + Stream_Write_UINT32(data_out, data_len); if (data_len > 0) - stream_write(data_out, stream_get_data(device->data), data_len); + Stream_Write(data_out, Stream_Buffer(device->data), data_len); count++; @@ -204,11 +204,11 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use } } - pos = stream_get_pos(data_out); - stream_set_pos(data_out, count_pos); - stream_write_UINT32(data_out, count); - stream_set_pos(data_out, pos); - stream_seal(data_out); + pos = Stream_GetPosition(data_out); + Stream_SetPosition(data_out, count_pos); + Stream_Write_UINT32(data_out, count); + Stream_SetPosition(data_out, pos); + Stream_SealLength(data_out); svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out); } @@ -235,8 +235,8 @@ static void rdpdr_process_receive(rdpSvcPlugin* plugin, wStream* data_in) UINT32 status; rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin; - stream_read_UINT16(data_in, component); - stream_read_UINT16(data_in, packetID); + Stream_Read_UINT16(data_in, component); + Stream_Read_UINT16(data_in, packetID); if (component == RDPDR_CTYP_CORE) { @@ -268,8 +268,8 @@ static void rdpdr_process_receive(rdpSvcPlugin* plugin, wStream* data_in) case PAKID_CORE_DEVICE_REPLY: /* connect to a specific resource */ - stream_read_UINT32(data_in, deviceID); - stream_read_UINT32(data_in, status); + Stream_Read_UINT32(data_in, deviceID); + Stream_Read_UINT32(data_in, status); DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_DEVICE_REPLY (deviceID=%d status=0x%08X)", deviceID, status); break; @@ -294,7 +294,7 @@ static void rdpdr_process_receive(rdpSvcPlugin* plugin, wStream* data_in) DEBUG_WARN("RDPDR component: 0x%02X packetID: 0x%02X", component, packetID); } - stream_free(data_in); + Stream_Free(data_in, TRUE); } static void rdpdr_process_event(rdpSvcPlugin* plugin, wMessage* event) diff --git a/channels/rdpei/client/CMakeLists.txt b/channels/rdpei/client/CMakeLists.txt index 8ad191ccc..b96082550 100644 --- a/channels/rdpei/client/CMakeLists.txt +++ b/channels/rdpei/client/CMakeLists.txt @@ -1,7 +1,7 @@ # FreeRDP: A Remote Desktop Protocol Implementation # FreeRDP cmake build script # -# Copyright 2012 Marc-Andre Moreau +# Copyright 2013 Marc-Andre Moreau # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,7 +19,9 @@ define_channel_client("rdpei") set(${MODULE_PREFIX}_SRCS rdpei_main.c - rdpei_main.h) + rdpei_main.h + rdpei_common.c + rdpei_common.h) include_directories(..) @@ -31,6 +33,11 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE freerdp MODULES freerdp-common freerdp-utils) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-sysinfo) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) diff --git a/channels/rdpei/client/rdpei_common.c b/channels/rdpei/client/rdpei_common.c new file mode 100644 index 000000000..3f6b3d819 --- /dev/null +++ b/channels/rdpei/client/rdpei_common.c @@ -0,0 +1,589 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Input Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "rdpei_common.h" + +BOOL rdpei_read_2byte_unsigned(wStream* s, UINT32* value) +{ + BYTE byte; + + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, byte); + + if (byte & 0x80) + { + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + *value = (byte & 0x7F) << 8; + Stream_Read_UINT8(s, byte); + *value |= byte; + } + else + { + *value = (byte & 0x7F); + } + + return TRUE; +} + +BOOL rdpei_write_2byte_unsigned(wStream* s, UINT32 value) +{ + BYTE byte; + + if (value > 0x7FFF) + return FALSE; + + if (value >= 0x7F) + { + byte = ((value & 0x7F00) >> 8); + Stream_Write_UINT8(s, byte | 0x80); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else + { + byte = (value & 0x7F); + Stream_Write_UINT8(s, byte); + } + + return TRUE; +} + +BOOL rdpei_read_2byte_signed(wStream* s, INT32* value) +{ + BYTE byte; + BOOL negative; + + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, byte); + + negative = (byte & 0x40) ? TRUE : FALSE; + + *value = (byte & 0x3F); + + if (byte & 0x80) + { + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, byte); + *value = (*value << 8) | byte; + } + + if (negative) + *value *= -1; + + return TRUE; +} + +BOOL rdpei_write_2byte_signed(wStream* s, INT32 value) +{ + BYTE byte; + BOOL negative = FALSE; + + if (value < 0) + { + negative = TRUE; + value *= -1; + } + + if (value > 0x3FFF) + return FALSE; + + if (value >= 0x3F) + { + byte = ((value & 0x3F00) >> 8); + + if (negative) + byte |= 0x40; + + Stream_Write_UINT8(s, byte | 0x80); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else + { + byte = (value & 0x3F); + + if (negative) + byte |= 0x40; + + Stream_Write_UINT8(s, byte); + } + + return TRUE; +} + +BOOL rdpei_read_4byte_unsigned(wStream* s, UINT32* value) +{ + BYTE byte; + BYTE count; + + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, byte); + + count = (byte & 0xC0) >> 6; + + if (Stream_GetRemainingLength(s) < count) + return FALSE; + + switch (count) + { + case 0: + *value = (byte & 0x3F); + break; + + case 1: + *value = (byte & 0x3F) << 8; + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + case 2: + *value = (byte & 0x3F) << 16; + Stream_Read_UINT8(s, byte); + *value |= (byte << 8); + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + case 3: + *value = (byte & 0x3F) << 24; + Stream_Read_UINT8(s, byte); + *value |= (byte << 16); + Stream_Read_UINT8(s, byte); + *value |= (byte << 8); + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + default: + break; + } + + return TRUE; +} + +BOOL rdpei_write_4byte_unsigned(wStream* s, UINT32 value) +{ + BYTE byte; + + if (value <= 0x3F) + { + Stream_Write_UINT8(s, value); + } + else if (value <= 0x3FFF) + { + byte = (value >> 8) & 0x3F; + Stream_Write_UINT8(s, byte | 0x40); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x3FFFFF) + { + byte = (value >> 16) & 0x3F; + Stream_Write_UINT8(s, byte | 0x80); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x3FFFFF) + { + byte = (value >> 24) & 0x3F; + Stream_Write_UINT8(s, byte | 0xC0); + byte = (value >> 16) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else + { + return FALSE; + } + + return TRUE; +} + +BOOL rdpei_read_4byte_signed(wStream* s, INT32* value) +{ + BYTE byte; + BYTE count; + BOOL negative; + + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, byte); + + count = (byte & 0xC0) >> 6; + negative = (byte & 0x20); + + if (Stream_GetRemainingLength(s) < count) + return FALSE; + + switch (count) + { + case 0: + *value = (byte & 0x1F); + break; + + case 1: + *value = (byte & 0x1F) << 8; + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + case 2: + *value = (byte & 0x1F) << 16; + Stream_Read_UINT8(s, byte); + *value |= (byte << 8); + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + case 3: + *value = (byte & 0x1F) << 24; + Stream_Read_UINT8(s, byte); + *value |= (byte << 16); + Stream_Read_UINT8(s, byte); + *value |= (byte << 8); + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + default: + break; + } + + if (negative) + *value *= -1; + + return TRUE; +} + +BOOL rdpei_write_4byte_signed(wStream* s, INT32 value) +{ + BYTE byte; + BOOL negative = FALSE; + + if (value < 0) + { + negative = TRUE; + value *= -1; + } + + if (value <= 0x1F) + { + byte = value & 0x1F; + + if (negative) + byte |= 0x20; + + Stream_Write_UINT8(s, value); + } + else if (value <= 0x1FFF) + { + byte = (value >> 8) & 0x1F; + + if (negative) + byte |= 0x20; + + Stream_Write_UINT8(s, byte | 0x40); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x1FFFFF) + { + byte = (value >> 16) & 0x1F; + + if (negative) + byte |= 0x20; + + Stream_Write_UINT8(s, byte | 0x80); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x1FFFFF) + { + byte = (value >> 24) & 0x1F; + + if (negative) + byte |= 0x20; + + Stream_Write_UINT8(s, byte | 0xC0); + byte = (value >> 16) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else + { + return FALSE; + } + + return TRUE; +} + +BOOL rdpei_read_8byte_unsigned(wStream* s, UINT64* value) +{ + BYTE byte; + BYTE count; + + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, byte); + + count = (byte & 0xE0) >> 5; + + if (Stream_GetRemainingLength(s) < count) + return FALSE; + + switch (count) + { + case 0: + *value = (byte & 0x1F); + break; + + case 1: + *value = (byte & 0x1F) << 8; + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + case 2: + *value = (byte & 0x1F) << 16; + Stream_Read_UINT8(s, byte); + *value |= (byte << 8); + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + case 3: + *value = (byte & 0x1F) << 24; + Stream_Read_UINT8(s, byte); + *value |= (byte << 16); + Stream_Read_UINT8(s, byte); + *value |= (byte << 8); + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + case 4: + *value = ((UINT64) (byte & 0x1F)) << 32; + Stream_Read_UINT8(s, byte); + *value |= (byte << 24); + Stream_Read_UINT8(s, byte); + *value |= (byte << 16); + Stream_Read_UINT8(s, byte); + *value |= (byte << 8); + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + case 5: + *value = ((UINT64) (byte & 0x1F)) << 40; + Stream_Read_UINT8(s, byte); + *value |= (((UINT64) byte) << 32); + Stream_Read_UINT8(s, byte); + *value |= (byte << 24); + Stream_Read_UINT8(s, byte); + *value |= (byte << 16); + Stream_Read_UINT8(s, byte); + *value |= (byte << 8); + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + case 6: + *value = ((UINT64) (byte & 0x1F)) << 48; + Stream_Read_UINT8(s, byte); + *value |= (((UINT64) byte) << 40); + Stream_Read_UINT8(s, byte); + *value |= (((UINT64) byte) << 32); + Stream_Read_UINT8(s, byte); + *value |= (byte << 24); + Stream_Read_UINT8(s, byte); + *value |= (byte << 16); + Stream_Read_UINT8(s, byte); + *value |= (byte << 8); + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + case 7: + *value = ((UINT64) (byte & 0x1F)) << 56; + Stream_Read_UINT8(s, byte); + *value |= (((UINT64) byte) << 48); + Stream_Read_UINT8(s, byte); + *value |= (((UINT64) byte) << 40); + Stream_Read_UINT8(s, byte); + *value |= (((UINT64) byte) << 32); + Stream_Read_UINT8(s, byte); + *value |= (byte << 24); + Stream_Read_UINT8(s, byte); + *value |= (byte << 16); + Stream_Read_UINT8(s, byte); + *value |= (byte << 8); + Stream_Read_UINT8(s, byte); + *value |= byte; + break; + + default: + break; + } + + return TRUE; +} + +BOOL rdpei_write_8byte_unsigned(wStream* s, UINT64 value) +{ + BYTE byte; + + if (value <= 0x1F) + { + byte = value & 0x1F; + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x1FFF) + { + byte = (value >> 8) & 0x1F; + byte |= (1 << 5); + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x1FFFFF) + { + byte = (value >> 16) & 0x1F; + byte |= (2 << 5); + Stream_Write_UINT8(s, byte); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x1FFFFF) + { + byte = (value >> 24) & 0x1F; + byte |= (3 << 5); + Stream_Write_UINT8(s, byte); + byte = (value >> 16) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x1FFFFFFF) + { + byte = (value >> 32) & 0x1F; + byte |= (4 << 5); + Stream_Write_UINT8(s, byte); + byte = (value >> 24) & 0x1F; + Stream_Write_UINT8(s, byte); + byte = (value >> 16) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x1FFFFFFFFF) + { + byte = (value >> 40) & 0x1F; + byte |= (5 << 5); + Stream_Write_UINT8(s, byte); + byte = (value >> 32) & 0x1F; + Stream_Write_UINT8(s, byte); + byte = (value >> 24) & 0x1F; + Stream_Write_UINT8(s, byte); + byte = (value >> 16) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x1FFFFFFFFFFF) + { + byte = (value >> 48) & 0x1F; + byte |= (6 << 5); + Stream_Write_UINT8(s, byte); + byte = (value >> 40) & 0x1F; + Stream_Write_UINT8(s, byte); + byte = (value >> 32) & 0x1F; + Stream_Write_UINT8(s, byte); + byte = (value >> 24) & 0x1F; + Stream_Write_UINT8(s, byte); + byte = (value >> 16) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x1FFFFFFFFFFFFF) + { + byte = (value >> 56) & 0x1F; + byte |= (7 << 5); + Stream_Write_UINT8(s, byte); + byte = (value >> 48) & 0x1F; + Stream_Write_UINT8(s, byte); + byte = (value >> 40) & 0x1F; + Stream_Write_UINT8(s, byte); + byte = (value >> 32) & 0x1F; + Stream_Write_UINT8(s, byte); + byte = (value >> 24) & 0x1F; + Stream_Write_UINT8(s, byte); + byte = (value >> 16) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else + { + return FALSE; + } + + return TRUE; +} diff --git a/channels/rdpei/client/rdpei_common.h b/channels/rdpei/client/rdpei_common.h new file mode 100644 index 000000000..293919f67 --- /dev/null +++ b/channels/rdpei/client/rdpei_common.h @@ -0,0 +1,38 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Input Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_RDPEI_CLIENT_COMMON_H +#define FREERDP_CHANNEL_RDPEI_CLIENT_COMMON_H + +#include +#include + +BOOL rdpei_read_2byte_unsigned(wStream* s, UINT32* value); +BOOL rdpei_write_2byte_unsigned(wStream* s, UINT32 value); +BOOL rdpei_read_2byte_signed(wStream* s, INT32* value); +BOOL rdpei_write_2byte_signed(wStream* s, INT32 value); +BOOL rdpei_read_4byte_unsigned(wStream* s, UINT32* value); +BOOL rdpei_write_4byte_unsigned(wStream* s, UINT32 value); +BOOL rdpei_read_4byte_signed(wStream* s, INT32* value); +BOOL rdpei_write_4byte_signed(wStream* s, INT32 value); +BOOL rdpei_read_8byte_unsigned(wStream* s, UINT64* value); +BOOL rdpei_write_8byte_unsigned(wStream* s, UINT64 value); + +#endif /* FREERDP_CHANNEL_RDPEI_CLIENT_COMMON_H */ + diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index 2f866d7ab..1147fa816 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -26,24 +26,38 @@ #include #include +#include +#include #include #include -#include +#include "rdpei_common.h" #include "rdpei_main.h" -typedef struct _RDPEI_LISTENER_CALLBACK RDPEI_LISTENER_CALLBACK; -struct _RDPEI_LISTENER_CALLBACK -{ - IWTSListenerCallback iface; +/** + * Touch Input + * http://msdn.microsoft.com/en-us/library/windows/desktop/dd562197/ + * + * Windows Touch Input + * http://msdn.microsoft.com/en-us/library/windows/desktop/dd317321/ + * + * Input: Touch injection sample + * http://code.msdn.microsoft.com/windowsdesktop/Touch-Injection-Sample-444d9bf7 + * + * Pointer Input Message Reference + * http://msdn.microsoft.com/en-us/library/hh454916/ + * + * POINTER_INFO Structure + * http://msdn.microsoft.com/en-us/library/hh454907/ + * + * POINTER_TOUCH_INFO Structure + * http://msdn.microsoft.com/en-us/library/hh454910/ + */ - IWTSPlugin* plugin; - IWTSVirtualChannelManager* channel_mgr; -}; +#define MAX_CONTACTS 512 -typedef struct _RDPEI_CHANNEL_CALLBACK RDPEI_CHANNEL_CALLBACK; struct _RDPEI_CHANNEL_CALLBACK { IWTSVirtualChannelCallback iface; @@ -52,19 +66,273 @@ struct _RDPEI_CHANNEL_CALLBACK IWTSVirtualChannelManager* channel_mgr; IWTSVirtualChannel* channel; }; +typedef struct _RDPEI_CHANNEL_CALLBACK RDPEI_CHANNEL_CALLBACK; + +struct _RDPEI_LISTENER_CALLBACK +{ + IWTSListenerCallback iface; + + IWTSPlugin* plugin; + IWTSVirtualChannelManager* channel_mgr; + RDPEI_CHANNEL_CALLBACK* channel_callback; +}; +typedef struct _RDPEI_LISTENER_CALLBACK RDPEI_LISTENER_CALLBACK; -typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN; struct _RDPEI_PLUGIN { IWTSPlugin iface; + IWTSListener* listener; RDPEI_LISTENER_CALLBACK* listener_callback; + + int version; + UINT16 maxTouchContacts; + UINT64 currentFrameTime; + UINT64 previousFrameTime; + RDPINPUT_TOUCH_FRAME frame; + RDPINPUT_CONTACT_DATA contacts[MAX_CONTACTS]; + RDPINPUT_CONTACT_POINT* contactPoints; }; +typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN; + +const char* RDPEI_EVENTID_STRINGS[] = +{ + "", + "EVENTID_SC_READY", + "EVENTID_CS_READY", + "EVENTID_TOUCH", + "EVENTID_SUSPEND_TOUCH", + "EVENTID_RESUME_TOUCH", + "EVENTID_DISMISS_HOVERING_CONTACT" +}; + +int rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId, UINT32 pduLength) +{ + int status; + + Stream_SetPosition(s, 0); + Stream_Write_UINT16(s, eventId); /* eventId (2 bytes) */ + Stream_Write_UINT32(s, pduLength); /* pduLength (4 bytes) */ + Stream_SetPosition(s, Stream_Length(s)); + + status = callback->channel->Write(callback->channel, Stream_Length(s), Stream_Buffer(s), NULL); + +#ifdef WITH_DEBUG_RDPEI + printf("rdpei_send_pdu: eventId: %d (%s) length: %d status: %d\n", + eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength, status); +#endif + + return status; +} + +int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback) +{ + int status; + wStream* s; + UINT32 flags; + UINT32 pduLength; + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) callback->plugin; + + flags = 0; + flags |= READY_FLAGS_SHOW_TOUCH_VISUALS; + //flags |= READY_FLAGS_DISABLE_TIMESTAMP_INJECTION; + + pduLength = RDPINPUT_HEADER_LENGTH + 10; + s = Stream_New(NULL, pduLength); + Stream_Seek(s, RDPINPUT_HEADER_LENGTH); + + Stream_Write_UINT32(s, flags); /* flags (4 bytes) */ + Stream_Write_UINT32(s, RDPINPUT_PROTOCOL_V1); /* protocolVersion (4 bytes) */ + Stream_Write_UINT16(s, rdpei->maxTouchContacts); /* maxTouchContacts (2 bytes) */ + + Stream_SealLength(s); + + status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength); + Stream_Free(s, TRUE); + + return status; +} + +void rdpei_print_contact_flags(UINT32 contactFlags) +{ + if (contactFlags & CONTACT_FLAG_DOWN) + printf(" CONTACT_FLAG_DOWN"); + if (contactFlags & CONTACT_FLAG_UPDATE) + printf(" CONTACT_FLAG_UPDATE"); + if (contactFlags & CONTACT_FLAG_UP) + printf(" CONTACT_FLAG_UP"); + if (contactFlags & CONTACT_FLAG_INRANGE) + printf(" CONTACT_FLAG_INRANGE"); + if (contactFlags & CONTACT_FLAG_INCONTACT) + printf(" CONTACT_FLAG_INCONTACT"); + if (contactFlags & CONTACT_FLAG_CANCELED) + printf(" CONTACT_FLAG_CANCELED"); +} + +int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) +{ + int index; + RDPINPUT_CONTACT_DATA* contact; + +#ifdef WITH_DEBUG_RDPEI + printf("contactCount: %d\n", frame->contactCount); + printf("frameOffset: 0x%08X\n", (UINT32) frame->frameOffset); +#endif + + rdpei_write_2byte_unsigned(s, frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */ + rdpei_write_8byte_unsigned(s, frame->frameOffset); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */ + + Stream_EnsureRemainingCapacity(s, frame->contactCount * 32); + + for (index = 0; index < frame->contactCount; index++) + { + contact = &frame->contacts[index]; + +#ifdef WITH_DEBUG_RDPEI + printf("contact[%d].contactId: %d\n", index, contact->contactId); + printf("contact[%d].fieldsPresent: %d\n", index, contact->fieldsPresent); + printf("contact[%d].x: %d\n", index, contact->x); + printf("contact[%d].y: %d\n", index, contact->y); + printf("contact[%d].contactFlags: 0x%04X", index, contact->contactFlags); + rdpei_print_contact_flags(contact->contactFlags); + printf("\n"); +#endif + + Stream_Write_UINT8(s, contact->contactId); /* contactId (1 byte) */ + + /* fieldsPresent (TWO_BYTE_UNSIGNED_INTEGER) */ + rdpei_write_2byte_unsigned(s, contact->fieldsPresent); + + rdpei_write_4byte_signed(s, contact->x); /* x (FOUR_BYTE_SIGNED_INTEGER) */ + rdpei_write_4byte_signed(s, contact->y); /* y (FOUR_BYTE_SIGNED_INTEGER) */ + + /* contactFlags (FOUR_BYTE_UNSIGNED_INTEGER) */ + rdpei_write_4byte_unsigned(s, contact->contactFlags); + + if (contact->fieldsPresent & CONTACT_DATA_CONTACTRECT_PRESENT) + { + /* contactRectLeft (TWO_BYTE_SIGNED_INTEGER) */ + rdpei_write_2byte_signed(s, contact->contactRectLeft); + /* contactRectTop (TWO_BYTE_SIGNED_INTEGER) */ + rdpei_write_2byte_signed(s, contact->contactRectTop); + /* contactRectRight (TWO_BYTE_SIGNED_INTEGER) */ + rdpei_write_2byte_signed(s, contact->contactRectRight); + /* contactRectBottom (TWO_BYTE_SIGNED_INTEGER) */ + rdpei_write_2byte_signed(s, contact->contactRectBottom); + } + + if (contact->fieldsPresent & CONTACT_DATA_ORIENTATION_PRESENT) + { + /* orientation (FOUR_BYTE_UNSIGNED_INTEGER) */ + rdpei_write_4byte_unsigned(s, contact->orientation); + } + + if (contact->fieldsPresent & CONTACT_DATA_PRESSURE_PRESENT) + { + /* pressure (FOUR_BYTE_UNSIGNED_INTEGER) */ + rdpei_write_4byte_unsigned(s, contact->pressure); + } + } + + return 0; +} + +int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_FRAME* frame) +{ + int status; + wStream* s; + UINT32 pduLength; + + pduLength = 64 + (frame->contactCount * 32); + + s = Stream_New(NULL, pduLength); + Stream_Seek(s, RDPINPUT_HEADER_LENGTH); + + rdpei_write_4byte_unsigned(s, frame->frameOffset); /* FOUR_BYTE_UNSIGNED_INTEGER */ + rdpei_write_2byte_unsigned(s, 1); /* TWO_BYTE_UNSIGNED_INTEGER */ + + rdpei_write_touch_frame(s, frame); + + Stream_SealLength(s); + pduLength = Stream_Length(s); + + status = rdpei_send_pdu(callback, s, EVENTID_TOUCH, pduLength); + Stream_Free(s, TRUE); + + return status; +} + +int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) +{ + UINT32 protocolVersion; + + Stream_Read_UINT32(s, protocolVersion); /* protocolVersion (4 bytes) */ + + if (protocolVersion != RDPINPUT_PROTOCOL_V1) + { + printf("Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion); + return -1; + } + + return 0; +} + +int rdpei_recv_suspend_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) +{ + return 0; +} + +int rdpei_recv_resume_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) +{ + return 0; +} + +int rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) +{ + UINT16 eventId; + UINT32 pduLength; + + Stream_Read_UINT16(s, eventId); /* eventId (2 bytes) */ + Stream_Read_UINT32(s, pduLength); /* pduLength (4 bytes) */ + +#ifdef WITH_DEBUG_RDPEI + printf("rdpei_recv_pdu: eventId: %d (%s) length: %d\n", + eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength); +#endif + + switch (eventId) + { + case EVENTID_SC_READY: + rdpei_recv_sc_ready_pdu(callback, s); + rdpei_send_cs_ready_pdu(callback); + break; + + case EVENTID_SUSPEND_TOUCH: + rdpei_recv_suspend_touch_pdu(callback, s); + break; + + case EVENTID_RESUME_TOUCH: + rdpei_recv_resume_touch_pdu(callback, s); + break; + + default: + break; + } + + return 0; +} static int rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, UINT32 cbSize, BYTE* pBuffer) { + wStream* s; int status = 0; - //RDPEI_CHANNEL_CALLBACK* callback = (RDPEI_CHANNEL_CALLBACK*) pChannelCallback; + RDPEI_CHANNEL_CALLBACK* callback = (RDPEI_CHANNEL_CALLBACK*) pChannelCallback; + + s = Stream_New(pBuffer, cbSize); + + status = rdpei_recv_pdu(callback, s); + + Stream_Free(s, FALSE); return status; } @@ -97,6 +365,7 @@ static int rdpei_on_new_channel_connection(IWTSListenerCallback* pListenerCallba callback->plugin = listener_callback->plugin; callback->channel_mgr = listener_callback->channel_mgr; callback->channel = pChannel; + listener_callback->channel_callback = callback; *ppCallback = (IWTSVirtualChannelCallback*) callback; @@ -105,32 +374,160 @@ static int rdpei_on_new_channel_connection(IWTSListenerCallback* pListenerCallba static int rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr) { - RDPEI_PLUGIN* echo = (RDPEI_PLUGIN*) pPlugin; + int status; + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) pPlugin; DEBUG_DVC(""); - echo->listener_callback = (RDPEI_LISTENER_CALLBACK*) malloc(sizeof(RDPEI_LISTENER_CALLBACK)); - ZeroMemory(echo->listener_callback, sizeof(RDPEI_LISTENER_CALLBACK)); + rdpei->listener_callback = (RDPEI_LISTENER_CALLBACK*) malloc(sizeof(RDPEI_LISTENER_CALLBACK)); + ZeroMemory(rdpei->listener_callback, sizeof(RDPEI_LISTENER_CALLBACK)); - echo->listener_callback->iface.OnNewChannelConnection = rdpei_on_new_channel_connection; - echo->listener_callback->plugin = pPlugin; - echo->listener_callback->channel_mgr = pChannelMgr; + rdpei->listener_callback->iface.OnNewChannelConnection = rdpei_on_new_channel_connection; + rdpei->listener_callback->plugin = pPlugin; + rdpei->listener_callback->channel_mgr = pChannelMgr; - return pChannelMgr->CreateListener(pChannelMgr, "Microsoft::Windows::RDS::Input", 0, - (IWTSListenerCallback*) echo->listener_callback, NULL); + status = pChannelMgr->CreateListener(pChannelMgr, RDPEI_DVC_CHANNEL_NAME, 0, + (IWTSListenerCallback*) rdpei->listener_callback, &(rdpei->listener)); + + rdpei->listener->pInterface = rdpei->iface.pInterface; + + return status; } static int rdpei_plugin_terminated(IWTSPlugin* pPlugin) { - RDPEI_PLUGIN* echo = (RDPEI_PLUGIN*) pPlugin; + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) pPlugin; DEBUG_DVC(""); - free(echo); + free(rdpei); return 0; } +/** + * Channel Client Interface + */ + +int rdpei_get_version(RdpeiClientContext* context) +{ + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; + return rdpei->version; +} + +int rdpei_send_frame(RdpeiClientContext* context) +{ + UINT64 currentTime; + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; + RDPEI_CHANNEL_CALLBACK* callback = rdpei->listener_callback->channel_callback; + + currentTime = GetTickCount64(); + + if (!rdpei->previousFrameTime && !rdpei->currentFrameTime) + { + rdpei->currentFrameTime = currentTime; + rdpei->frame.frameOffset = 0; + } + else + { + rdpei->currentFrameTime = currentTime; + rdpei->frame.frameOffset = rdpei->currentFrameTime - rdpei->previousFrameTime; + } + + rdpei_send_touch_event_pdu(callback, &rdpei->frame); + rdpei->previousFrameTime = rdpei->currentFrameTime; + rdpei->frame.contactCount = 0; + + return 1; +} + +int rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact) +{ + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; + + if (rdpei->frame.contactCount < MAX_CONTACTS) + { + CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA)); + rdpei->frame.contactCount++; + } + + rdpei_send_frame(context); + + return 1; +} + +int rdpei_contact_begin(RdpeiClientContext* context, int externalId) +{ + int i; + int contactId = -1; + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; + + /* Create a new contact point in an empty slot */ + + for (i = 0; i < rdpei->maxTouchContacts; i++) + { + if (!rdpei->contactPoints[i].flags) + { + rdpei->contactPoints[i].flags = 1; + rdpei->contactPoints[i].contactId = i; + + if (!rdpei->contactPoints[i].externalId) + { + rdpei->contactPoints[i].externalId = externalId; + contactId = rdpei->contactPoints[i].contactId; + break; + } + } + } + + return contactId; +} + +int rdpei_contact_update(RdpeiClientContext* context, int externalId) +{ + int i; + int contactId = -1; + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; + + for (i = 0; i < rdpei->maxTouchContacts; i++) + { + if (!rdpei->contactPoints[i].flags) + continue; + + if (rdpei->contactPoints[i].externalId == externalId) + { + contactId = rdpei->contactPoints[i].contactId; + break; + } + } + + return contactId; +} + +int rdpei_contact_end(RdpeiClientContext* context, int externalId) +{ + int i; + int contactId = -1; + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; + + for (i = 0; i < rdpei->maxTouchContacts; i++) + { + if (!rdpei->contactPoints[i].flags) + continue; + + if (rdpei->contactPoints[i].externalId == externalId) + { + contactId = rdpei->contactPoints[i].contactId; + rdpei->contactPoints[i].externalId = 0; + rdpei->contactPoints[i].flags = 0; + rdpei->contactPoints[i].contactId = 0; + break; + } + } + + return contactId; +} + #ifdef STATIC_CHANNELS #define DVCPluginEntry rdpei_DVCPluginEntry #endif @@ -139,11 +536,14 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { int error = 0; RDPEI_PLUGIN* rdpei; + RdpeiClientContext* context; rdpei = (RDPEI_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "rdpei"); if (rdpei == NULL) { + size_t size; + rdpei = (RDPEI_PLUGIN*) malloc(sizeof(RDPEI_PLUGIN)); ZeroMemory(rdpei, sizeof(RDPEI_PLUGIN)); @@ -152,6 +552,28 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) rdpei->iface.Disconnected = NULL; rdpei->iface.Terminated = rdpei_plugin_terminated; + rdpei->version = 1; + rdpei->currentFrameTime = 0; + rdpei->previousFrameTime = 0; + rdpei->frame.contacts = (RDPINPUT_CONTACT_DATA*) rdpei->contacts; + + rdpei->maxTouchContacts = 10; + size = rdpei->maxTouchContacts * sizeof(RDPINPUT_CONTACT_POINT); + rdpei->contactPoints = (RDPINPUT_CONTACT_POINT*) malloc(size); + ZeroMemory(rdpei->contactPoints, size); + + context = (RdpeiClientContext*) malloc(sizeof(RdpeiClientContext)); + + context->handle = (void*) rdpei; + context->GetVersion = rdpei_get_version; + context->AddContact = rdpei_add_contact; + + context->ContactBegin = rdpei_contact_begin; + context->ContactUpdate = rdpei_contact_update; + context->ContactEnd = rdpei_contact_end; + + rdpei->iface.pInterface = (void*) context; + error = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpei", (IWTSPlugin*) rdpei); } diff --git a/channels/rdpei/client/rdpei_main.h b/channels/rdpei/client/rdpei_main.h index ca233b3a8..8c0137ce4 100644 --- a/channels/rdpei/client/rdpei_main.h +++ b/channels/rdpei/client/rdpei_main.h @@ -29,6 +29,36 @@ #include #include +#include + +#define RDPINPUT_HEADER_LENGTH 6 + +/* Protocol Version */ + +#define RDPINPUT_PROTOCOL_V1 0x00010000 + +/* Client Ready Flags */ + +#define READY_FLAGS_SHOW_TOUCH_VISUALS 0x00000001 +#define READY_FLAGS_DISABLE_TIMESTAMP_INJECTION 0x00000002 + +/* Input Event Ids */ + +#define EVENTID_SC_READY 0x0001 +#define EVENTID_CS_READY 0x0002 +#define EVENTID_TOUCH 0x0003 +#define EVENTID_SUSPEND_TOUCH 0x0004 +#define EVENTID_RESUME_TOUCH 0x0005 +#define EVENTID_DISMISS_HOVERING_CONTACT 0x0006 + +struct _RDPINPUT_CONTACT_POINT +{ + UINT32 flags; + UINT32 contactId; + int externalId; +}; +typedef struct _RDPINPUT_CONTACT_POINT RDPINPUT_CONTACT_POINT; + #ifdef WITH_DEBUG_DVC #define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__) #else diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 8e54f15e2..35ba973d7 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -126,12 +126,12 @@ void rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd) { wStream* pdu; - pdu = stream_new(8); - stream_write_BYTE(pdu, SNDC_QUALITYMODE); /* msgType */ - stream_write_BYTE(pdu, 0); /* bPad */ - stream_write_UINT16(pdu, 4); /* BodySize */ - stream_write_UINT16(pdu, HIGH_QUALITY); /* wQualityMode */ - stream_write_UINT16(pdu, 0); /* Reserved */ + pdu = Stream_New(NULL, 8); + Stream_Write_UINT8(pdu, SNDC_QUALITYMODE); /* msgType */ + Stream_Write_UINT8(pdu, 0); /* bPad */ + Stream_Write_UINT16(pdu, 4); /* BodySize */ + Stream_Write_UINT16(pdu, HIGH_QUALITY); /* wQualityMode */ + Stream_Write_UINT16(pdu, 0); /* Reserved */ svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu); } @@ -199,15 +199,14 @@ void rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) UINT16 wNumberOfFormats; AUDIO_FORMAT* clientFormat; - if (rdpsnd->device->GetVolume) + dwVolumeLeft = ((50 * 0xFFFF) / 100); /* 50% */ + dwVolumeRight = ((50 * 0xFFFF) / 100); /* 50% */ + dwVolume = (dwVolumeLeft << 16) | dwVolumeRight; + + if (rdpsnd->device) { - dwVolume = rdpsnd->device->GetVolume(rdpsnd->device); - } - else - { - dwVolumeLeft = ((50 * 0xFFFF) / 100); /* 50% */ - dwVolumeRight = ((50 * 0xFFFF) / 100); /* 50% */ - dwVolume = (dwVolumeLeft << 16) | dwVolumeRight; + if (rdpsnd->device->GetVolume) + dwVolume = rdpsnd->device->GetVolume(rdpsnd->device); } wNumberOfFormats = rdpsnd->NumberOfClientFormats; @@ -217,35 +216,35 @@ void rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) for (index = 0; index < (int) wNumberOfFormats; index++) length += (18 + rdpsnd->ClientFormats[index].cbSize); - pdu = stream_new(length); + pdu = Stream_New(NULL, length); - stream_write_BYTE(pdu, SNDC_FORMATS); /* msgType */ - stream_write_BYTE(pdu, 0); /* bPad */ - stream_write_UINT16(pdu, length - 4); /* BodySize */ + Stream_Write_UINT8(pdu, SNDC_FORMATS); /* msgType */ + Stream_Write_UINT8(pdu, 0); /* bPad */ + Stream_Write_UINT16(pdu, length - 4); /* BodySize */ - stream_write_UINT32(pdu, TSSNDCAPS_ALIVE | TSSNDCAPS_VOLUME); /* dwFlags */ - stream_write_UINT32(pdu, dwVolume); /* dwVolume */ - stream_write_UINT32(pdu, 0); /* dwPitch */ - stream_write_UINT16(pdu, 0); /* wDGramPort */ - stream_write_UINT16(pdu, wNumberOfFormats); /* wNumberOfFormats */ - stream_write_BYTE(pdu, 0); /* cLastBlockConfirmed */ - stream_write_UINT16(pdu, 6); /* wVersion */ - stream_write_BYTE(pdu, 0); /* bPad */ + Stream_Write_UINT32(pdu, TSSNDCAPS_ALIVE | TSSNDCAPS_VOLUME); /* dwFlags */ + Stream_Write_UINT32(pdu, dwVolume); /* dwVolume */ + Stream_Write_UINT32(pdu, 0); /* dwPitch */ + Stream_Write_UINT16(pdu, 0); /* wDGramPort */ + Stream_Write_UINT16(pdu, wNumberOfFormats); /* wNumberOfFormats */ + Stream_Write_UINT8(pdu, 0); /* cLastBlockConfirmed */ + Stream_Write_UINT16(pdu, 6); /* wVersion */ + Stream_Write_UINT8(pdu, 0); /* bPad */ for (index = 0; index < (int) wNumberOfFormats; index++) { clientFormat = &rdpsnd->ClientFormats[index]; - stream_write_UINT16(pdu, clientFormat->wFormatTag); - stream_write_UINT16(pdu, clientFormat->nChannels); - stream_write_UINT32(pdu, clientFormat->nSamplesPerSec); - stream_write_UINT32(pdu, clientFormat->nAvgBytesPerSec); - stream_write_UINT16(pdu, clientFormat->nBlockAlign); - stream_write_UINT16(pdu, clientFormat->wBitsPerSample); - stream_write_UINT16(pdu, clientFormat->cbSize); + Stream_Write_UINT16(pdu, clientFormat->wFormatTag); + Stream_Write_UINT16(pdu, clientFormat->nChannels); + Stream_Write_UINT32(pdu, clientFormat->nSamplesPerSec); + Stream_Write_UINT32(pdu, clientFormat->nAvgBytesPerSec); + Stream_Write_UINT16(pdu, clientFormat->nBlockAlign); + Stream_Write_UINT16(pdu, clientFormat->wBitsPerSample); + Stream_Write_UINT16(pdu, clientFormat->cbSize); if (clientFormat->cbSize > 0) - stream_write(pdu, clientFormat->data, clientFormat->cbSize); + Stream_Write(pdu, clientFormat->data, clientFormat->cbSize); } svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu); @@ -262,14 +261,14 @@ void rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) rdpsnd->NumberOfServerFormats = 0; rdpsnd->ServerFormats = NULL; - stream_seek_UINT32(s); /* dwFlags */ - stream_seek_UINT32(s); /* dwVolume */ - stream_seek_UINT32(s); /* dwPitch */ - stream_seek_UINT16(s); /* wDGramPort */ - stream_read_UINT16(s, wNumberOfFormats); - stream_read_BYTE(s, rdpsnd->cBlockNo); /* cLastBlockConfirmed */ - stream_read_UINT16(s, wVersion); /* wVersion */ - stream_seek_BYTE(s); /* bPad */ + Stream_Seek_UINT32(s); /* dwFlags */ + Stream_Seek_UINT32(s); /* dwVolume */ + Stream_Seek_UINT32(s); /* dwPitch */ + Stream_Seek_UINT16(s); /* wDGramPort */ + Stream_Read_UINT16(s, wNumberOfFormats); + Stream_Read_UINT8(s, rdpsnd->cBlockNo); /* cLastBlockConfirmed */ + Stream_Read_UINT16(s, wVersion); /* wVersion */ + Stream_Seek_UINT8(s); /* bPad */ rdpsnd->NumberOfServerFormats = wNumberOfFormats; rdpsnd->ServerFormats = (AUDIO_FORMAT*) malloc(sizeof(AUDIO_FORMAT) * wNumberOfFormats); @@ -278,16 +277,16 @@ void rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) { format = &rdpsnd->ServerFormats[index]; - stream_read_UINT16(s, format->wFormatTag); /* wFormatTag */ - stream_read_UINT16(s, format->nChannels); /* nChannels */ - stream_read_UINT32(s, format->nSamplesPerSec); /* nSamplesPerSec */ - stream_read_UINT32(s, format->nAvgBytesPerSec); /* nAvgBytesPerSec */ - stream_read_UINT16(s, format->nBlockAlign); /* nBlockAlign */ - stream_read_UINT16(s, format->wBitsPerSample); /* wBitsPerSample */ - stream_read_UINT16(s, format->cbSize); /* cbSize */ + Stream_Read_UINT16(s, format->wFormatTag); /* wFormatTag */ + Stream_Read_UINT16(s, format->nChannels); /* nChannels */ + Stream_Read_UINT32(s, format->nSamplesPerSec); /* nSamplesPerSec */ + Stream_Read_UINT32(s, format->nAvgBytesPerSec); /* nAvgBytesPerSec */ + Stream_Read_UINT16(s, format->nBlockAlign); /* nBlockAlign */ + Stream_Read_UINT16(s, format->wBitsPerSample); /* wBitsPerSample */ + Stream_Read_UINT16(s, format->cbSize); /* cbSize */ format->data = (BYTE*) malloc(format->cbSize); - stream_read(s, format->data, format->cbSize); + Stream_Read(s, format->data, format->cbSize); } rdpsnd_select_supported_audio_formats(rdpsnd); @@ -302,12 +301,12 @@ void rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, U { wStream* pdu; - pdu = stream_new(8); - stream_write_BYTE(pdu, SNDC_TRAINING); /* msgType */ - stream_write_BYTE(pdu, 0); /* bPad */ - stream_write_UINT16(pdu, 4); /* BodySize */ - stream_write_UINT16(pdu, wTimeStamp); - stream_write_UINT16(pdu, wPackSize); + pdu = Stream_New(NULL, 8); + Stream_Write_UINT8(pdu, SNDC_TRAINING); /* msgType */ + Stream_Write_UINT8(pdu, 0); /* bPad */ + Stream_Write_UINT16(pdu, 4); /* BodySize */ + Stream_Write_UINT16(pdu, wTimeStamp); + Stream_Write_UINT16(pdu, wPackSize); svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu); } @@ -317,8 +316,8 @@ static void rdpsnd_recv_training_pdu(rdpsndPlugin* rdpsnd, wStream* s) UINT16 wTimeStamp; UINT16 wPackSize; - stream_read_UINT16(s, wTimeStamp); - stream_read_UINT16(s, wPackSize); + Stream_Read_UINT16(s, wTimeStamp); + Stream_Read_UINT16(s, wPackSize); rdpsnd_send_training_confirm_pdu(rdpsnd, wTimeStamp, wPackSize); } @@ -330,11 +329,11 @@ static void rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B rdpsnd->expectingWave = TRUE; - stream_read_UINT16(s, rdpsnd->wTimeStamp); - stream_read_UINT16(s, wFormatNo); - stream_read_BYTE(s, rdpsnd->cBlockNo); - stream_seek(s, 3); /* bPad */ - stream_read(s, rdpsnd->waveData, 4); + Stream_Read_UINT16(s, rdpsnd->wTimeStamp); + Stream_Read_UINT16(s, wFormatNo); + Stream_Read_UINT8(s, rdpsnd->cBlockNo); + Stream_Seek(s, 3); /* bPad */ + Stream_Read(s, rdpsnd->waveData, 4); rdpsnd->waveDataSize = BodySize - 8; @@ -367,13 +366,13 @@ void rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE { wStream* pdu; - pdu = stream_new(8); - stream_write_BYTE(pdu, SNDC_WAVECONFIRM); - stream_write_BYTE(pdu, 0); - stream_write_UINT16(pdu, 4); - stream_write_UINT16(pdu, wTimeStamp); - stream_write_BYTE(pdu, cConfirmedBlockNo); /* cConfirmedBlockNo */ - stream_write_BYTE(pdu, 0); /* bPad */ + pdu = Stream_New(NULL, 8); + Stream_Write_UINT8(pdu, SNDC_WAVECONFIRM); + Stream_Write_UINT8(pdu, 0); + Stream_Write_UINT16(pdu, 4); + Stream_Write_UINT16(pdu, wTimeStamp); + Stream_Write_UINT8(pdu, cConfirmedBlockNo); /* cConfirmedBlockNo */ + Stream_Write_UINT8(pdu, 0); /* bPad */ svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu); } @@ -399,10 +398,10 @@ static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) * part of the preceding Wave Info PDU. */ - CopyMemory(stream_get_head(s), rdpsnd->waveData, 4); + CopyMemory(Stream_Buffer(s), rdpsnd->waveData, 4); - data = stream_get_head(s); - size = stream_get_size(s); + data = Stream_Buffer(s); + size = Stream_Capacity(s); wave = (RDPSND_WAVE*) malloc(sizeof(RDPSND_WAVE)); @@ -458,7 +457,7 @@ static void rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s) { UINT32 dwVolume; - stream_read_UINT32(s, dwVolume); + Stream_Read_UINT32(s, dwVolume); DEBUG_SVC("dwVolume 0x%X", dwVolume); if (rdpsnd->device) @@ -476,13 +475,13 @@ static void rdpsnd_recv_pdu(rdpSvcPlugin* plugin, wStream* s) if (rdpsnd->expectingWave) { rdpsnd_recv_wave_pdu(rdpsnd, s); - stream_free(s); + Stream_Free(s, TRUE); return; } - stream_read_BYTE(s, msgType); /* msgType */ - stream_seek_BYTE(s); /* bPad */ - stream_read_UINT16(s, BodySize); + Stream_Read_UINT8(s, msgType); /* msgType */ + Stream_Seek_UINT8(s); /* bPad */ + Stream_Read_UINT16(s, BodySize); //fprintf(stderr, "msgType %d BodySize %d\n", msgType, BodySize); @@ -513,7 +512,7 @@ static void rdpsnd_recv_pdu(rdpSvcPlugin* plugin, wStream* s) break; } - stream_free(s); + Stream_Free(s, TRUE); } static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlugin* device) diff --git a/channels/rdpsnd/server/rdpsnd.c b/channels/rdpsnd/server/rdpsnd.c index 75e4af02a..57a9593a2 100644 --- a/channels/rdpsnd/server/rdpsnd.c +++ b/channels/rdpsnd/server/rdpsnd.c @@ -61,45 +61,45 @@ static BOOL rdpsnd_server_send_formats(rdpsnd_server* rdpsnd, wStream* s) UINT16 i; BOOL status; - stream_write_BYTE(s, SNDC_FORMATS); - stream_write_BYTE(s, 0); - stream_seek_UINT16(s); + Stream_Write_UINT8(s, SNDC_FORMATS); + Stream_Write_UINT8(s, 0); + Stream_Seek_UINT16(s); - stream_write_UINT32(s, 0); /* dwFlags */ - stream_write_UINT32(s, 0); /* dwVolume */ - stream_write_UINT32(s, 0); /* dwPitch */ - stream_write_UINT16(s, 0); /* wDGramPort */ - stream_write_UINT16(s, rdpsnd->context.num_server_formats); /* wNumberOfFormats */ - stream_write_BYTE(s, rdpsnd->context.block_no); /* cLastBlockConfirmed */ - stream_write_UINT16(s, 0x06); /* wVersion */ - stream_write_BYTE(s, 0); /* bPad */ + Stream_Write_UINT32(s, 0); /* dwFlags */ + Stream_Write_UINT32(s, 0); /* dwVolume */ + Stream_Write_UINT32(s, 0); /* dwPitch */ + Stream_Write_UINT16(s, 0); /* wDGramPort */ + Stream_Write_UINT16(s, rdpsnd->context.num_server_formats); /* wNumberOfFormats */ + Stream_Write_UINT8(s, rdpsnd->context.block_no); /* cLastBlockConfirmed */ + Stream_Write_UINT16(s, 0x06); /* wVersion */ + Stream_Write_UINT8(s, 0); /* bPad */ for (i = 0; i < rdpsnd->context.num_server_formats; i++) { - stream_write_UINT16(s, rdpsnd->context.server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */ - stream_write_UINT16(s, rdpsnd->context.server_formats[i].nChannels); /* nChannels */ - stream_write_UINT32(s, rdpsnd->context.server_formats[i].nSamplesPerSec); /* nSamplesPerSec */ + Stream_Write_UINT16(s, rdpsnd->context.server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */ + Stream_Write_UINT16(s, rdpsnd->context.server_formats[i].nChannels); /* nChannels */ + Stream_Write_UINT32(s, rdpsnd->context.server_formats[i].nSamplesPerSec); /* nSamplesPerSec */ - stream_write_UINT32(s, rdpsnd->context.server_formats[i].nSamplesPerSec * + Stream_Write_UINT32(s, rdpsnd->context.server_formats[i].nSamplesPerSec * rdpsnd->context.server_formats[i].nChannels * rdpsnd->context.server_formats[i].wBitsPerSample / 8); /* nAvgBytesPerSec */ - stream_write_UINT16(s, rdpsnd->context.server_formats[i].nBlockAlign); /* nBlockAlign */ - stream_write_UINT16(s, rdpsnd->context.server_formats[i].wBitsPerSample); /* wBitsPerSample */ - stream_write_UINT16(s, rdpsnd->context.server_formats[i].cbSize); /* cbSize */ + Stream_Write_UINT16(s, rdpsnd->context.server_formats[i].nBlockAlign); /* nBlockAlign */ + Stream_Write_UINT16(s, rdpsnd->context.server_formats[i].wBitsPerSample); /* wBitsPerSample */ + Stream_Write_UINT16(s, rdpsnd->context.server_formats[i].cbSize); /* cbSize */ if (rdpsnd->context.server_formats[i].cbSize > 0) { - stream_write(s, rdpsnd->context.server_formats[i].data, rdpsnd->context.server_formats[i].cbSize); + Stream_Write(s, rdpsnd->context.server_formats[i].data, rdpsnd->context.server_formats[i].cbSize); } } - pos = stream_get_pos(s); - stream_set_pos(s, 2); - stream_write_UINT16(s, pos - 4); - stream_set_pos(s, pos); - status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, stream_get_head(s), stream_get_length(s), NULL); - stream_set_pos(s, 0); + pos = Stream_GetPosition(s); + Stream_SetPosition(s, 2); + Stream_Write_UINT16(s, pos - 4); + Stream_SetPosition(s, pos); + status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_SetPosition(s, 0); return status; } @@ -110,9 +110,9 @@ static void rdpsnd_server_recv_waveconfirm(rdpsnd_server* rdpsnd, wStream* s) UINT16 timestamp = 0; BYTE confirmBlockNum = 0; - stream_read_UINT16(s, timestamp); - stream_read_BYTE(s, confirmBlockNum); - stream_seek_BYTE(s); // padding + Stream_Read_UINT16(s, timestamp); + Stream_Read_UINT8(s, confirmBlockNum); + Stream_Seek_UINT8(s); // padding } static void rdpsnd_server_recv_quality_mode(rdpsnd_server* rdpsnd, wStream* s) @@ -120,8 +120,8 @@ static void rdpsnd_server_recv_quality_mode(rdpsnd_server* rdpsnd, wStream* s) //unhandled for now UINT16 quality; - stream_read_UINT16(s, quality); - stream_seek_UINT16(s); // reserved + Stream_Read_UINT16(s, quality); + Stream_Seek_UINT16(s); // reserved fprintf(stderr, "Client requested sound quality: %#0X\n", quality); } @@ -134,14 +134,14 @@ static BOOL rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, wStream* s) BYTE lastblock; - stream_read_UINT32(s, flags); /* dwFlags */ - stream_read_UINT32(s, vol); /* dwVolume */ - stream_read_UINT32(s, pitch); /* dwPitch */ - stream_read_UINT16(s, udpPort); /* wDGramPort */ - stream_read_UINT16(s, rdpsnd->context.num_client_formats); /* wNumberOfFormats */ - stream_read_BYTE(s, lastblock); /* cLastBlockConfirmed */ - stream_read_UINT16(s, version); /* wVersion */ - stream_seek_BYTE(s); /* bPad */ + Stream_Read_UINT32(s, flags); /* dwFlags */ + Stream_Read_UINT32(s, vol); /* dwVolume */ + Stream_Read_UINT32(s, pitch); /* dwPitch */ + Stream_Read_UINT16(s, udpPort); /* wDGramPort */ + Stream_Read_UINT16(s, rdpsnd->context.num_client_formats); /* wNumberOfFormats */ + Stream_Read_UINT8(s, lastblock); /* cLastBlockConfirmed */ + Stream_Read_UINT16(s, version); /* wVersion */ + Stream_Seek_UINT8(s); /* bPad */ if (rdpsnd->context.num_client_formats > 0) { @@ -150,17 +150,17 @@ static BOOL rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, wStream* s) for (i = 0; i < rdpsnd->context.num_client_formats; i++) { - stream_read_UINT16(s, rdpsnd->context.client_formats[i].wFormatTag); - stream_read_UINT16(s, rdpsnd->context.client_formats[i].nChannels); - stream_read_UINT32(s, rdpsnd->context.client_formats[i].nSamplesPerSec); - stream_read_UINT32(s, rdpsnd->context.client_formats[i].nAvgBytesPerSec); - stream_read_UINT16(s, rdpsnd->context.client_formats[i].nBlockAlign); - stream_read_UINT16(s, rdpsnd->context.client_formats[i].wBitsPerSample); - stream_read_UINT16(s, rdpsnd->context.client_formats[i].cbSize); + Stream_Read_UINT16(s, rdpsnd->context.client_formats[i].wFormatTag); + Stream_Read_UINT16(s, rdpsnd->context.client_formats[i].nChannels); + Stream_Read_UINT32(s, rdpsnd->context.client_formats[i].nSamplesPerSec); + Stream_Read_UINT32(s, rdpsnd->context.client_formats[i].nAvgBytesPerSec); + Stream_Read_UINT16(s, rdpsnd->context.client_formats[i].nBlockAlign); + Stream_Read_UINT16(s, rdpsnd->context.client_formats[i].wBitsPerSample); + Stream_Read_UINT16(s, rdpsnd->context.client_formats[i].cbSize); if (rdpsnd->context.client_formats[i].cbSize > 0) { - stream_seek(s, rdpsnd->context.client_formats[i].cbSize); + Stream_Seek(s, rdpsnd->context.client_formats[i].cbSize); } if (rdpsnd->context.client_formats[i].wFormatTag != 0) @@ -203,7 +203,7 @@ static void* rdpsnd_server_thread_func(void* arg) events[1] = CreateWaitObjectEvent(NULL, TRUE, FALSE, fd); } - s = stream_new(4096); + s = Stream_New(NULL, 4096); rdpsnd_server_send_formats(rdpsnd, s); @@ -216,24 +216,24 @@ static void* rdpsnd_server_thread_func(void* arg) break; } - stream_set_pos(s, 0); + Stream_SetPosition(s, 0); - if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s), - stream_get_size(s), &bytes_returned) == FALSE) + if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, Stream_Buffer(s), + Stream_Capacity(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; - stream_check_size(s, (int) bytes_returned); + Stream_EnsureRemainingCapacity(s, (int) bytes_returned); - if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s), - stream_get_size(s), &bytes_returned) == FALSE) + if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, Stream_Buffer(s), + Stream_Capacity(s), &bytes_returned) == FALSE) break; } - stream_read_BYTE(s, msgType); - stream_seek_BYTE(s); /* bPad */ - stream_read_UINT16(s, BodySize); + Stream_Read_UINT8(s, msgType); + Stream_Seek_UINT8(s); /* bPad */ + Stream_Read_UINT16(s, BodySize); switch (msgType) { @@ -256,7 +256,7 @@ static void* rdpsnd_server_thread_func(void* arg) } } - stream_free(s); + Stream_Free(s, TRUE); return NULL; } @@ -269,7 +269,7 @@ static BOOL rdpsnd_server_initialize(rdpsnd_server_context* context) if (rdpsnd->rdpsnd_channel != NULL) { - rdpsnd->rdpsnd_pdu = stream_new(4096); + rdpsnd->rdpsnd_pdu = Stream_New(NULL, 4096); rdpsnd->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -399,30 +399,30 @@ static BOOL rdpsnd_server_send_audio_pdu(rdpsnd_server* rdpsnd) } /* WaveInfo PDU */ - stream_set_pos(s, 0); - stream_write_BYTE(s, SNDC_WAVE); /* msgType */ - stream_write_BYTE(s, 0); /* bPad */ - stream_write_UINT16(s, size + fill_size + 8); /* BodySize */ + Stream_SetPosition(s, 0); + Stream_Write_UINT8(s, SNDC_WAVE); /* msgType */ + Stream_Write_UINT8(s, 0); /* bPad */ + Stream_Write_UINT16(s, size + fill_size + 8); /* BodySize */ - stream_write_UINT16(s, 0); /* wTimeStamp */ - stream_write_UINT16(s, rdpsnd->context.selected_client_format); /* wFormatNo */ - stream_write_BYTE(s, rdpsnd->context.block_no); /* cBlockNo */ - stream_seek(s, 3); /* bPad */ - stream_write(s, src, 4); + Stream_Write_UINT16(s, 0); /* wTimeStamp */ + Stream_Write_UINT16(s, rdpsnd->context.selected_client_format); /* wFormatNo */ + Stream_Write_UINT8(s, rdpsnd->context.block_no); /* cBlockNo */ + Stream_Seek(s, 3); /* bPad */ + Stream_Write(s, src, 4); - WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, stream_get_head(s), stream_get_length(s), NULL); - stream_set_pos(s, 0); + WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_SetPosition(s, 0); /* Wave PDU */ - stream_check_size(s, size + fill_size); - stream_write_UINT32(s, 0); /* bPad */ - stream_write(s, src + 4, size - 4); + Stream_EnsureRemainingCapacity(s, size + fill_size); + Stream_Write_UINT32(s, 0); /* bPad */ + Stream_Write(s, src + 4, size - 4); if (fill_size > 0) - stream_write_zero(s, fill_size); + Stream_Zero(s, fill_size); - status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, stream_get_head(s), stream_get_length(s), NULL); - stream_set_pos(s, 0); + status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_SetPosition(s, 0); rdpsnd->out_pending_frames = 0; @@ -465,19 +465,19 @@ static BOOL rdpsnd_server_set_volume(rdpsnd_server_context* context, int left, i rdpsnd_server* rdpsnd = (rdpsnd_server*) context; wStream* s = rdpsnd->rdpsnd_pdu; - stream_write_BYTE(s, SNDC_SETVOLUME); - stream_write_BYTE(s, 0); - stream_seek_UINT16(s); + Stream_Write_UINT8(s, SNDC_SETVOLUME); + Stream_Write_UINT8(s, 0); + Stream_Seek_UINT16(s); - stream_write_UINT16(s, left); - stream_write_UINT16(s, right); + Stream_Write_UINT16(s, left); + Stream_Write_UINT16(s, right); - pos = stream_get_pos(s); - stream_set_pos(s, 2); - stream_write_UINT16(s, pos - 4); - stream_set_pos(s, pos); - status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, stream_get_head(s), stream_get_length(s), NULL); - stream_set_pos(s, 0); + pos = Stream_GetPosition(s); + Stream_SetPosition(s, 2); + Stream_Write_UINT16(s, pos - 4); + Stream_SetPosition(s, pos); + status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_SetPosition(s, 0); return status; } @@ -500,16 +500,16 @@ static BOOL rdpsnd_server_close(rdpsnd_server_context* context) rdpsnd->context.selected_client_format = -1; - stream_write_BYTE(s, SNDC_CLOSE); - stream_write_BYTE(s, 0); - stream_seek_UINT16(s); + Stream_Write_UINT8(s, SNDC_CLOSE); + Stream_Write_UINT8(s, 0); + Stream_Seek_UINT16(s); - pos = stream_get_pos(s); - stream_set_pos(s, 2); - stream_write_UINT16(s, pos - 4); - stream_set_pos(s, pos); - status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, stream_get_head(s), stream_get_length(s), NULL); - stream_set_pos(s, 0); + pos = Stream_GetPosition(s); + Stream_SetPosition(s, 2); + Stream_Write_UINT16(s, pos - 4); + Stream_SetPosition(s, pos); + status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_SetPosition(s, 0); return status; } @@ -545,7 +545,7 @@ void rdpsnd_server_context_free(rdpsnd_server_context* context) WTSVirtualChannelClose(rdpsnd->rdpsnd_channel); if (rdpsnd->rdpsnd_pdu) - stream_free(rdpsnd->rdpsnd_pdu); + Stream_Free(rdpsnd->rdpsnd_pdu, TRUE); if (rdpsnd->out_buffer) free(rdpsnd->out_buffer); diff --git a/channels/sample/client/sample_main.c b/channels/sample/client/sample_main.c index b36a07f8b..92024693f 100644 --- a/channels/sample/client/sample_main.c +++ b/channels/sample/client/sample_main.c @@ -64,23 +64,23 @@ static void sample_process_receive(rdpSvcPlugin* plugin, wStream* data_in) /* process data in (from server) here */ /* here we just send the same data back */ - bytes = stream_get_size(data_in); + bytes = Stream_Capacity(data_in); fprintf(stderr, "sample_process_receive: got bytes %d\n", bytes); if (bytes > 0) { - data_out = stream_new(bytes); - stream_copy(data_out, data_in, bytes); + data_out = Stream_New(NULL, bytes); + Stream_Copy(data_out, data_in, bytes); /* svc_plugin_send takes ownership of data_out, that is why we do not free it */ - bytes = stream_get_length(data_in); + bytes = Stream_GetPosition(data_in); fprintf(stderr, "sample_process_receive: sending bytes %d\n", bytes); svc_plugin_send(plugin, data_out); } - stream_free(data_in); + Stream_Free(data_in, TRUE); } static void sample_process_connect(rdpSvcPlugin* plugin) diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index f505c2c00..df4700e9f 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -90,11 +90,11 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) UINT32 PathLength; UINT32 FileId; - stream_seek(irp->input, 28); /* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */ + Stream_Seek(irp->input, 28); /* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */ /* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */ - stream_read_UINT32(irp->input, PathLength); + Stream_Read_UINT32(irp->input, PathLength); - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(irp->input), + status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input), PathLength / 2, &path, 0, NULL, NULL); if (status < 1) @@ -117,8 +117,8 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) DEBUG_SVC("%s(%d) created.", serial->path, FileId); } - stream_write_UINT32(irp->output, FileId); - stream_write_BYTE(irp->output, 0); + Stream_Write_UINT32(irp->output, FileId); + Stream_Write_UINT8(irp->output, 0); free(path); @@ -144,7 +144,7 @@ static void serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp) serial->tty = NULL; } - stream_write_zero(irp->output, 5); /* Padding(5) */ + Stream_Zero(irp->output, 5); /* Padding(5) */ irp->Complete(irp); } @@ -156,8 +156,8 @@ static void serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp) UINT64 Offset; BYTE* buffer = NULL; - stream_read_UINT32(irp->input, Length); - stream_read_UINT64(irp->input, Offset); + Stream_Read_UINT32(irp->input, Length); + Stream_Read_UINT64(irp->input, Offset); DEBUG_SVC("length %u offset %llu", Length, Offset); @@ -189,12 +189,12 @@ static void serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp) } } - stream_write_UINT32(irp->output, Length); + Stream_Write_UINT32(irp->output, Length); if (Length > 0) { - stream_check_size(irp->output, Length); - stream_write(irp->output, buffer, Length); + Stream_EnsureRemainingCapacity(irp->output, Length); + Stream_Write(irp->output, buffer, Length); } free(buffer); @@ -208,9 +208,9 @@ static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp) UINT32 Length; UINT64 Offset; - stream_read_UINT32(irp->input, Length); - stream_read_UINT64(irp->input, Offset); - stream_seek(irp->input, 20); /* Padding */ + Stream_Read_UINT32(irp->input, Length); + Stream_Read_UINT64(irp->input, Offset); + Stream_Seek(irp->input, 20); /* Padding */ DEBUG_SVC("length %u offset %llu", Length, Offset); @@ -223,7 +223,7 @@ static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp) DEBUG_WARN("tty not valid."); } - else if (!serial_tty_write(tty, stream_get_tail(irp->input), Length)) + else if (!serial_tty_write(tty, Stream_Pointer(irp->input), Length)) { irp->IoStatus = STATUS_UNSUCCESSFUL; Length = 0; @@ -235,8 +235,8 @@ static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp) DEBUG_SVC("write %llu-%llu to %s(%d).", Offset, Offset + Length, serial->path, tty->id); } - stream_write_UINT32(irp->output, Length); - stream_write_BYTE(irp->output, 0); /* Padding */ + Stream_Write_UINT32(irp->output, Length); + Stream_Write_UINT8(irp->output, 0); /* Padding */ irp->Complete(irp); } @@ -251,10 +251,10 @@ static void serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); - stream_read_UINT32(irp->input, InputBufferLength); - stream_read_UINT32(irp->input, OutputBufferLength); - stream_read_UINT32(irp->input, IoControlCode); - stream_seek(irp->input, 20); /* Padding */ + Stream_Read_UINT32(irp->input, InputBufferLength); + Stream_Read_UINT32(irp->input, OutputBufferLength); + Stream_Read_UINT32(irp->input, IoControlCode); + Stream_Seek(irp->input, 20); /* Padding */ tty = serial->tty; @@ -420,7 +420,7 @@ static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32 /* Process a SINGLE FileId and MajorFunction */ list_remove(serial->pending_irps, irp); irp->IoStatus = io_status; - stream_write_UINT32(irp->output, 0); + Stream_Write_UINT32(irp->output, 0); irp->Complete(irp); SetEvent(serial->in_event); @@ -454,7 +454,7 @@ static void serial_check_for_events(SERIAL_DEVICE* serial) DEBUG_SVC("got event result %u", result); irp->IoStatus = STATUS_SUCCESS; - stream_write_UINT32(irp->output, result); + Stream_Write_UINT32(irp->output, result); irp->Complete(irp); prev = irp; @@ -478,9 +478,9 @@ void serial_get_timeouts(SERIAL_DEVICE* serial, IRP* irp, UINT32* timeout, UINT3 UINT32 Length; UINT32 pos; - pos = stream_get_pos(irp->input); - stream_read_UINT32(irp->input, Length); - stream_set_pos(irp->input, pos); + pos = Stream_GetPosition(irp->input); + Stream_Read_UINT32(irp->input, Length); + Stream_SetPosition(irp->input, pos); DEBUG_SVC("length read %u", Length); @@ -584,7 +584,7 @@ static void __serial_check_fds(SERIAL_DEVICE* serial) DEBUG_SVC("got event result %u", result); irp->IoStatus = STATUS_SUCCESS; - stream_write_UINT32(irp->output, result); + Stream_Write_UINT32(irp->output, result); irp->Complete(irp); irp_completed = TRUE; } @@ -703,10 +703,10 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) serial->device.Free = serial_free; len = strlen(name); - serial->device.data = stream_new(len + 1); + serial->device.data = Stream_New(NULL, len + 1); for (i = 0; i <= len; i++) - stream_write_BYTE(serial->device.data, name[i] < 0 ? '_' : name[i]); + Stream_Write_UINT8(serial->device.data, name[i] < 0 ? '_' : name[i]); serial->path = path; serial->queue = Queue_New(TRUE, -1, -1); diff --git a/channels/serial/client/serial_tty.c b/channels/serial/client/serial_tty.c index 74b2d09ef..23445b2ca 100644 --- a/channels/serial/client/serial_tty.c +++ b/channels/serial/client/serial_tty.c @@ -90,32 +90,32 @@ UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, wStream* input, DEBUG_SVC("in"); - stream_seek(output, sizeof(UINT32)); + Stream_Seek(output, sizeof(UINT32)); switch (IoControlCode) { case IOCTL_SERIAL_SET_BAUD_RATE: - stream_read_UINT32(input, tty->baud_rate); + Stream_Read_UINT32(input, tty->baud_rate); tty_set_termios(tty); DEBUG_SVC("SERIAL_SET_BAUD_RATE %d", tty->baud_rate); break; case IOCTL_SERIAL_GET_BAUD_RATE: length = 4; - stream_write_UINT32(output, tty->baud_rate); + Stream_Write_UINT32(output, tty->baud_rate); DEBUG_SVC("SERIAL_GET_BAUD_RATE %d", tty->baud_rate); break; case IOCTL_SERIAL_SET_QUEUE_SIZE: - stream_read_UINT32(input, tty->queue_in_size); - stream_read_UINT32(input, tty->queue_out_size); + Stream_Read_UINT32(input, tty->queue_in_size); + Stream_Read_UINT32(input, tty->queue_out_size); DEBUG_SVC("SERIAL_SET_QUEUE_SIZE in %d out %d", tty->queue_in_size, tty->queue_out_size); break; case IOCTL_SERIAL_SET_LINE_CONTROL: - stream_read_BYTE(input, tty->stop_bits); - stream_read_BYTE(input, tty->parity); - stream_read_BYTE(input, tty->word_length); + Stream_Read_UINT8(input, tty->stop_bits); + Stream_Read_UINT8(input, tty->parity); + Stream_Read_UINT8(input, tty->word_length); tty_set_termios(tty); DEBUG_SVC("SERIAL_SET_LINE_CONTROL stop %d parity %d word %d", tty->stop_bits, tty->parity, tty->word_length); @@ -124,62 +124,62 @@ UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, wStream* input, case IOCTL_SERIAL_GET_LINE_CONTROL: DEBUG_SVC("SERIAL_GET_LINE_CONTROL"); length = 3; - stream_write_BYTE(output, tty->stop_bits); - stream_write_BYTE(output, tty->parity); - stream_write_BYTE(output, tty->word_length); + Stream_Write_UINT8(output, tty->stop_bits); + Stream_Write_UINT8(output, tty->parity); + Stream_Write_UINT8(output, tty->word_length); break; case IOCTL_SERIAL_IMMEDIATE_CHAR: DEBUG_SVC("SERIAL_IMMEDIATE_CHAR"); - stream_read_BYTE(input, immediate); + Stream_Read_UINT8(input, immediate); tty_write_data(tty, &immediate, 1); break; case IOCTL_SERIAL_CONFIG_SIZE: DEBUG_SVC("SERIAL_CONFIG_SIZE"); length = 4; - stream_write_UINT32(output, 0); + Stream_Write_UINT32(output, 0); break; case IOCTL_SERIAL_GET_CHARS: DEBUG_SVC("SERIAL_GET_CHARS"); length = 6; - stream_write(output, tty->chars, 6); + Stream_Write(output, tty->chars, 6); break; case IOCTL_SERIAL_SET_CHARS: DEBUG_SVC("SERIAL_SET_CHARS"); - stream_read(input, tty->chars, 6); + Stream_Read(input, tty->chars, 6); tty_set_termios(tty); break; case IOCTL_SERIAL_GET_HANDFLOW: length = 16; tty_get_termios(tty); - stream_write_UINT32(output, tty->control); - stream_write_UINT32(output, tty->xonoff); - stream_write_UINT32(output, tty->onlimit); - stream_write_UINT32(output, tty->offlimit); + Stream_Write_UINT32(output, tty->control); + Stream_Write_UINT32(output, tty->xonoff); + Stream_Write_UINT32(output, tty->onlimit); + Stream_Write_UINT32(output, tty->offlimit); DEBUG_SVC("IOCTL_SERIAL_GET_HANDFLOW %X %X %X %X", tty->control, tty->xonoff, tty->onlimit, tty->offlimit); break; case IOCTL_SERIAL_SET_HANDFLOW: - stream_read_UINT32(input, tty->control); - stream_read_UINT32(input, tty->xonoff); - stream_read_UINT32(input, tty->onlimit); - stream_read_UINT32(input, tty->offlimit); + Stream_Read_UINT32(input, tty->control); + Stream_Read_UINT32(input, tty->xonoff); + Stream_Read_UINT32(input, tty->onlimit); + Stream_Read_UINT32(input, tty->offlimit); DEBUG_SVC("IOCTL_SERIAL_SET_HANDFLOW %X %X %X %X", tty->control, tty->xonoff, tty->onlimit, tty->offlimit); tty_set_termios(tty); break; case IOCTL_SERIAL_SET_TIMEOUTS: - stream_read_UINT32(input, tty->read_interval_timeout); - stream_read_UINT32(input, tty->read_total_timeout_multiplier); - stream_read_UINT32(input, tty->read_total_timeout_constant); - stream_read_UINT32(input, tty->write_total_timeout_multiplier); - stream_read_UINT32(input, tty->write_total_timeout_constant); + Stream_Read_UINT32(input, tty->read_interval_timeout); + Stream_Read_UINT32(input, tty->read_total_timeout_multiplier); + Stream_Read_UINT32(input, tty->read_total_timeout_constant); + Stream_Read_UINT32(input, tty->write_total_timeout_multiplier); + Stream_Read_UINT32(input, tty->write_total_timeout_constant); /* http://www.codeproject.com/KB/system/chaiyasit_t.aspx, see 'ReadIntervalTimeout' section http://msdn.microsoft.com/en-us/library/ms885171.aspx */ @@ -201,21 +201,21 @@ UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, wStream* input, tty->read_total_timeout_multiplier, tty->read_total_timeout_constant); length = 20; - stream_write_UINT32(output, tty->read_interval_timeout); - stream_write_UINT32(output, tty->read_total_timeout_multiplier); - stream_write_UINT32(output, tty->read_total_timeout_constant); - stream_write_UINT32(output, tty->write_total_timeout_multiplier); - stream_write_UINT32(output, tty->write_total_timeout_constant); + Stream_Write_UINT32(output, tty->read_interval_timeout); + Stream_Write_UINT32(output, tty->read_total_timeout_multiplier); + Stream_Write_UINT32(output, tty->read_total_timeout_constant); + Stream_Write_UINT32(output, tty->write_total_timeout_multiplier); + Stream_Write_UINT32(output, tty->write_total_timeout_constant); break; case IOCTL_SERIAL_GET_WAIT_MASK: DEBUG_SVC("SERIAL_GET_WAIT_MASK %X", tty->wait_mask); length = 4; - stream_write_UINT32(output, tty->wait_mask); + Stream_Write_UINT32(output, tty->wait_mask); break; case IOCTL_SERIAL_SET_WAIT_MASK: - stream_read_UINT32(input, tty->wait_mask); + Stream_Read_UINT32(input, tty->wait_mask); DEBUG_SVC("SERIAL_SET_WAIT_MASK %X", tty->wait_mask); break; @@ -270,19 +270,19 @@ UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, wStream* input, #endif DEBUG_SVC("SERIAL_GET_MODEMSTATUS %X", modemstate); length = 4; - stream_write_UINT32(output, modemstate); + Stream_Write_UINT32(output, modemstate); break; case IOCTL_SERIAL_GET_COMMSTATUS: length = 18; - stream_write_UINT32(output, 0); /* Errors */ - stream_write_UINT32(output, 0); /* Hold reasons */ + Stream_Write_UINT32(output, 0); /* Errors */ + Stream_Write_UINT32(output, 0); /* Hold reasons */ result = 0; #ifdef TIOCINQ ioctl(tty->fd, TIOCINQ, &result); #endif - stream_write_UINT32(output, result); /* Amount in in queue */ + Stream_Write_UINT32(output, result); /* Amount in in queue */ if (result) DEBUG_SVC("SERIAL_GET_COMMSTATUS in queue %d", result); @@ -290,15 +290,15 @@ UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, wStream* input, #ifdef TIOCOUTQ ioctl(tty->fd, TIOCOUTQ, &result); #endif - stream_write_UINT32(output, result); /* Amount in out queue */ + Stream_Write_UINT32(output, result); /* Amount in out queue */ DEBUG_SVC("SERIAL_GET_COMMSTATUS out queue %d", result); - stream_write_BYTE(output, 0); /* EofReceived */ - stream_write_BYTE(output, 0); /* WaitForImmediate */ + Stream_Write_UINT8(output, 0); /* EofReceived */ + Stream_Write_UINT8(output, 0); /* WaitForImmediate */ break; case IOCTL_SERIAL_PURGE: - stream_read_UINT32(input, purge_mask); + Stream_Read_UINT32(input, purge_mask); DEBUG_SVC("SERIAL_PURGE purge_mask %X", purge_mask); /* See http://msdn.microsoft.com/en-us/library/ms901431.aspx @@ -327,7 +327,7 @@ UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, wStream* input, if (serial_tty_get_event(tty, &result)) { DEBUG_SVC("WAIT end event = %X", result); - stream_write_UINT32(output, result); + Stream_Write_UINT32(output, result); break; } ret = STATUS_PENDING; @@ -361,10 +361,10 @@ UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, wStream* input, } /* Write OutputBufferLength */ - pos = stream_get_pos(output); - stream_set_pos(output, 16); - stream_write_UINT32(output, length); - stream_set_pos(output, pos); + pos = Stream_GetPosition(output); + Stream_SetPosition(output, 16); + Stream_Write_UINT32(output, length); + Stream_SetPosition(output, pos); return ret; } diff --git a/channels/server/channels.c b/channels/server/channels.c index d7fc26c13..18facafd5 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -31,6 +31,7 @@ #include #include +#include #include "channels.h" @@ -133,21 +134,21 @@ static int wts_read_variable_uint(wStream* s, int cbLen, UINT32* val) switch (cbLen) { case 0: - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return 0; - stream_read_BYTE(s, *val); + Stream_Read_UINT8(s, *val); return 1; case 1: - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return 0; - stream_read_UINT16(s, *val); + Stream_Read_UINT16(s, *val); return 2; default: - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return 0; - stream_read_UINT32(s, *val); + Stream_Read_UINT32(s, *val); return 4; } } @@ -159,8 +160,8 @@ static void wts_read_drdynvc_capabilities_response(rdpPeerChannel* channel, UINT if (length < 3) return; - stream_seek_BYTE(channel->receive_data); /* Pad (1 byte) */ - stream_read_UINT16(channel->receive_data, Version); + Stream_Seek_UINT8(channel->receive_data); /* Pad (1 byte) */ + Stream_Read_UINT16(channel->receive_data, Version); DEBUG_DVC("Version: %d", Version); @@ -174,7 +175,7 @@ static void wts_read_drdynvc_create_response(rdpPeerChannel* channel, wStream* s if (length < 4) return; - stream_read_UINT32(s, CreationStatus); + Stream_Read_UINT32(s, CreationStatus); if ((INT32) CreationStatus < 0) { @@ -204,33 +205,33 @@ static void wts_read_drdynvc_data_first(rdpPeerChannel* channel, wStream* s, int if (length > channel->dvc_total_length) return; - stream_set_pos(channel->receive_data, 0); - stream_check_size(channel->receive_data, (int) channel->dvc_total_length); - stream_write(channel->receive_data, stream_get_tail(s), length); + Stream_SetPosition(channel->receive_data, 0); + Stream_EnsureRemainingCapacity(channel->receive_data, (int) channel->dvc_total_length); + Stream_Write(channel->receive_data, Stream_Pointer(s), length); } static void wts_read_drdynvc_data(rdpPeerChannel* channel, wStream* s, UINT32 length) { if (channel->dvc_total_length > 0) { - if (stream_get_length(channel->receive_data) + length > channel->dvc_total_length) + if (Stream_GetPosition(channel->receive_data) + length > channel->dvc_total_length) { channel->dvc_total_length = 0; fprintf(stderr, "wts_read_drdynvc_data: incorrect fragment data, discarded.\n"); return; } - stream_write(channel->receive_data, stream_get_tail(s), length); + Stream_Write(channel->receive_data, Stream_Pointer(s), length); - if (stream_get_length(channel->receive_data) >= (int) channel->dvc_total_length) + if (Stream_GetPosition(channel->receive_data) >= (int) channel->dvc_total_length) { - wts_queue_receive_data(channel, stream_get_head(channel->receive_data), channel->dvc_total_length); + wts_queue_receive_data(channel, Stream_Buffer(channel->receive_data), channel->dvc_total_length); channel->dvc_total_length = 0; } } else { - wts_queue_receive_data(channel, stream_get_tail(s), length); + wts_queue_receive_data(channel, Stream_Pointer(s), length); } } @@ -250,13 +251,13 @@ static void wts_read_drdynvc_pdu(rdpPeerChannel* channel) UINT32 ChannelId; rdpPeerChannel* dvc; - length = stream_get_pos(channel->receive_data); + length = Stream_GetPosition(channel->receive_data); if (length < 1) return; - stream_set_pos(channel->receive_data, 0); - stream_read_BYTE(channel->receive_data, value); + Stream_SetPosition(channel->receive_data, 0); + Stream_Read_UINT8(channel->receive_data, value); length--; Cmd = (value & 0xf0) >> 4; @@ -322,17 +323,17 @@ static int wts_write_variable_uint(wStream* stream, UINT32 val) if (val <= 0xFF) { cb = 0; - stream_write_BYTE(stream, val); + Stream_Write_UINT8(stream, val); } else if (val <= 0xFFFF) { cb = 1; - stream_write_UINT16(stream, val); + Stream_Write_UINT16(stream, val); } else { cb = 3; - stream_write_UINT32(stream, val); + Stream_Write_UINT32(stream, val); } return cb; @@ -343,8 +344,8 @@ static void wts_write_drdynvc_header(wStream *s, BYTE Cmd, UINT32 ChannelId) BYTE* bm; int cbChId; - stream_get_mark(s, bm); - stream_seek_BYTE(s); + Stream_GetPointer(s, bm); + Stream_Seek_UINT8(s); cbChId = wts_write_variable_uint(s, ChannelId); *bm = ((Cmd & 0x0F) << 4) | cbChId; } @@ -355,23 +356,23 @@ static void wts_write_drdynvc_create_request(wStream *s, UINT32 ChannelId, const wts_write_drdynvc_header(s, CREATE_REQUEST_PDU, ChannelId); len = strlen(ChannelName) + 1; - stream_check_size(s, (int) len); - stream_write(s, ChannelName, len); + Stream_EnsureRemainingCapacity(s, (int) len); + Stream_Write(s, ChannelName, len); } static void WTSProcessChannelData(rdpPeerChannel* channel, int channelId, BYTE* data, int size, int flags, int total_size) { if (flags & CHANNEL_FLAG_FIRST) { - stream_set_pos(channel->receive_data, 0); + Stream_SetPosition(channel->receive_data, 0); } - stream_check_size(channel->receive_data, size); - stream_write(channel->receive_data, data, size); + Stream_EnsureRemainingCapacity(channel->receive_data, size); + Stream_Write(channel->receive_data, data, size); if (flags & CHANNEL_FLAG_LAST) { - if (stream_get_length(channel->receive_data) != total_size) + if (Stream_GetPosition(channel->receive_data) != total_size) { fprintf(stderr, "WTSProcessChannelData: read error\n"); } @@ -381,9 +382,9 @@ static void WTSProcessChannelData(rdpPeerChannel* channel, int channelId, BYTE* } else { - wts_queue_receive_data(channel, stream_get_head(channel->receive_data), stream_get_length(channel->receive_data)); + wts_queue_receive_data(channel, Stream_Buffer(channel->receive_data), Stream_GetPosition(channel->receive_data)); } - stream_set_pos(channel->receive_data, 0); + Stream_SetPosition(channel->receive_data, 0); } } @@ -563,7 +564,7 @@ void* WTSVirtualChannelOpenEx( channel->vcm = vcm; channel->client = client; channel->channel_type = RDP_PEER_CHANNEL_TYPE_DVC; - channel->receive_data = stream_new(client->settings->VirtualChannelChunkSize); + channel->receive_data = Stream_New(NULL, client->settings->VirtualChannelChunkSize); channel->receive_event = CreateEvent(NULL, TRUE, FALSE, NULL); channel->receive_queue = list_new(); channel->mutex = CreateMutex(NULL, FALSE, NULL); @@ -573,10 +574,10 @@ void* WTSVirtualChannelOpenEx( list_enqueue(vcm->dvc_channel_list, channel); ReleaseMutex(vcm->mutex); - s = stream_new(64); + s = Stream_New(NULL, 64); wts_write_drdynvc_create_request(s, channel->channel_id, pVirtualName); - WTSVirtualChannelWrite(vcm->drdynvc_channel, stream_get_head(s), stream_get_length(s), NULL); - stream_free(s); + WTSVirtualChannelWrite(vcm->drdynvc_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_Free(s, TRUE); DEBUG_DVC("ChannelId %d.%s (total %d)", channel->channel_id, pVirtualName, list_size(vcm->dvc_channel_list)); } @@ -611,7 +612,7 @@ void* WTSVirtualChannelOpenEx( channel->channel_id = client->settings->ChannelDefArray[i].ChannelId; channel->index = i; channel->channel_type = RDP_PEER_CHANNEL_TYPE_SVC; - channel->receive_data = stream_new(client->settings->VirtualChannelChunkSize); + channel->receive_data = Stream_New(NULL, client->settings->VirtualChannelChunkSize); channel->receive_event = CreateEvent(NULL, TRUE, FALSE, NULL); channel->receive_queue = list_new(); channel->mutex = CreateMutex(NULL, FALSE, NULL); @@ -772,7 +773,6 @@ BOOL WTSVirtualChannelWrite( } else { - s = stream_new(0); first = TRUE; while (Length > 0) @@ -780,13 +780,13 @@ BOOL WTSVirtualChannelWrite( item = (wts_data_item*) malloc(sizeof(wts_data_item)); ZeroMemory(item, sizeof(wts_data_item)); - item->buffer = malloc(channel->client->settings->VirtualChannelChunkSize); - stream_attach(s, item->buffer, channel->client->settings->VirtualChannelChunkSize); + s = Stream_New(NULL, channel->client->settings->VirtualChannelChunkSize); + item->buffer = Stream_Buffer(s); - stream_seek_BYTE(s); + Stream_Seek_UINT8(s); cbChId = wts_write_variable_uint(s, channel->channel_id); - if (first && (Length > (UINT32) stream_get_left(s))) + if (first && (Length > (UINT32) Stream_GetRemainingLength(s))) { cbLen = wts_write_variable_uint(s, Length); item->buffer[0] = (DATA_FIRST_PDU << 4) | (cbLen << 2) | cbChId; @@ -797,25 +797,25 @@ BOOL WTSVirtualChannelWrite( } first = FALSE; - written = stream_get_left(s); + written = Stream_GetRemainingLength(s); if (written > Length) written = Length; - stream_write(s, Buffer, written); - item->length = stream_get_length(s); - stream_detach(s); + Stream_Write(s, Buffer, written); + item->length = Stream_GetPosition(s); + Stream_Free(s, FALSE); + Length -= written; Buffer += written; wts_queue_send_item(channel->vcm->drdynvc_channel, item); } - - stream_free(s); } if (pBytesWritten != NULL) *pBytesWritten = Length; + return TRUE; } @@ -844,15 +844,15 @@ BOOL WTSVirtualChannelClose( if (channel->dvc_open_state == DVC_OPEN_STATE_SUCCEEDED) { - s = stream_new(8); + s = Stream_New(NULL, 8); wts_write_drdynvc_header(s, CLOSE_REQUEST_PDU, channel->channel_id); - WTSVirtualChannelWrite(vcm->drdynvc_channel, stream_get_head(s), stream_get_length(s), NULL); - stream_free(s); + WTSVirtualChannelWrite(vcm->drdynvc_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_Free(s, TRUE); } } if (channel->receive_data) - stream_free(channel->receive_data); + Stream_Free(channel->receive_data, TRUE); if (channel->receive_event) CloseHandle(channel->receive_event); diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index d241e4a0e..fa4dd0b3d 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -220,10 +220,10 @@ static void smartcard_irp_complete(IRP* irp) DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId); - pos = stream_get_pos(irp->output); - stream_set_pos(irp->output, 12); - stream_write_UINT32(irp->output, irp->IoStatus); - stream_set_pos(irp->output, pos); + pos = Stream_GetPosition(irp->output); + Stream_SetPosition(irp->output, 12); + Stream_Write_UINT32(irp->output, irp->IoStatus); + Stream_SetPosition(irp->output, pos); /* Begin TS Client defect workaround. */ WaitForSingleObject(smartcard->CompletionIdsMutex, INFINITE); @@ -325,10 +325,10 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) smartcard->device.Free = smartcard_free; length = strlen(smartcard->device.name); - smartcard->device.data = stream_new(length + 1); + smartcard->device.data = Stream_New(NULL, length + 1); for (i = 0; i <= length; i++) - stream_write_BYTE(smartcard->device.data, name[i] < 0 ? '_' : name[i]); + Stream_Write_UINT8(smartcard->device.data, name[i] < 0 ? '_' : name[i]); smartcard->path = path; diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 2c4b595b9..d75b1d3d9 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -89,7 +89,7 @@ static UINT32 smartcard_output_string(IRP* irp, char* src, BOOL wide) BYTE* p; UINT32 len; - p = stream_get_tail(irp->output); + p = Stream_Pointer(irp->output); len = strlen(src) + 1; if (wide) @@ -109,7 +109,7 @@ static UINT32 smartcard_output_string(IRP* irp, char* src, BOOL wide) memcpy(p, src, len); } - stream_seek(irp->output, len); + Stream_Seek(irp->output, len); return len; } @@ -120,11 +120,11 @@ static void smartcard_output_alignment(IRP* irp, UINT32 seed) * CompletionID, and IoStatus * of Section 2.2.1.5.5 of MS-RDPEFS. */ - UINT32 size = stream_get_length(irp->output) - field_lengths; + UINT32 size = Stream_GetPosition(irp->output) - field_lengths; UINT32 add = (seed - (size % seed)) % seed; if (add > 0) - stream_write_zero(irp->output, add); + Stream_Zero(irp->output, add); } static void smartcard_output_repos(IRP* irp, UINT32 written) @@ -132,12 +132,12 @@ static void smartcard_output_repos(IRP* irp, UINT32 written) UINT32 add = (4 - (written % 4)) % 4; if (add > 0) - stream_write_zero(irp->output, add); + Stream_Zero(irp->output, add); } static UINT32 smartcard_output_return(IRP* irp, UINT32 status) { - stream_write_zero(irp->output, 256); + Stream_Zero(irp->output, 256); return status; } @@ -145,18 +145,18 @@ static void smartcard_output_buffer_limit(IRP* irp, char* buffer, unsigned int l { int header = (length < 0) ? (0) : ((length > highLimit) ? (highLimit) : (length)); - stream_write_UINT32(irp->output, header); + Stream_Write_UINT32(irp->output, header); if (length <= 0) { - stream_write_UINT32(irp->output, 0); + Stream_Write_UINT32(irp->output, 0); } else { if (header < length) length = header; - stream_write(irp->output, buffer, length); + Stream_Write(irp->output, buffer, length); smartcard_output_repos(irp, length); } } @@ -170,8 +170,8 @@ static void smartcard_output_buffer_start_limit(IRP* irp, int length, int highLi { int header = (length < 0) ? (0) : ((length > highLimit) ? (highLimit) : (length)); - stream_write_UINT32(irp->output, header); - stream_write_UINT32(irp->output, 0x00000001); /* Magic DWORD - any non zero */ + Stream_Write_UINT32(irp->output, header); + Stream_Write_UINT32(irp->output, 0x00000001); /* Magic DWORD - any non zero */ } static void smartcard_output_buffer_start(IRP* irp, int length) @@ -187,7 +187,7 @@ static UINT32 smartcard_input_string(IRP* irp, char** dest, UINT32 dataLength, B bufferSize = wide ? (2 * dataLength) : dataLength; buffer = malloc(bufferSize + 2); /* reserve 2 bytes for the '\0' */ - stream_read(irp->input, buffer, bufferSize); + Stream_Read(irp->input, buffer, bufferSize); if (wide) { @@ -212,15 +212,15 @@ static void smartcard_input_repos(IRP* irp, UINT32 read) UINT32 add = 4 - (read % 4); if (add < 4 && add > 0) - stream_seek(irp->input, add); + Stream_Seek(irp->input, add); } static void smartcard_input_reader_name(IRP* irp, char** dest, BOOL wide) { UINT32 dataLength; - stream_seek(irp->input, 8); - stream_read_UINT32(irp->input, dataLength); + Stream_Seek(irp->input, 8); + Stream_Read_UINT32(irp->input, dataLength); DEBUG_SCARD("datalength %d", dataLength); smartcard_input_repos(irp, smartcard_input_string(irp, dest, dataLength, wide)); @@ -229,11 +229,11 @@ static void smartcard_input_reader_name(IRP* irp, char** dest, BOOL wide) static void smartcard_input_skip_linked(IRP* irp) { UINT32 len; - stream_read_UINT32(irp->input, len); + Stream_Read_UINT32(irp->input, len); if (len > 0) { - stream_seek(irp->input, len); + Stream_Seek(irp->input, len); smartcard_input_repos(irp, len); } } @@ -267,22 +267,22 @@ static UINT32 handle_EstablishContext(IRP* irp) UINT32 scope; SCARDCONTEXT hContext = -1; - stream_seek(irp->input, 8); - stream_read_UINT32(irp->input, len); + Stream_Seek(irp->input, 8); + Stream_Read_UINT32(irp->input, len); if (len != 8) return SCARD_F_INTERNAL_ERROR; - stream_seek_UINT32(irp->input); - stream_read_UINT32(irp->input, scope); + Stream_Seek_UINT32(irp->input); + Stream_Read_UINT32(irp->input, scope); status = SCardEstablishContext(scope, NULL, NULL, &hContext); - stream_write_UINT32(irp->output, 4); // cbContext - stream_write_UINT32(irp->output, -1); // ReferentID + Stream_Write_UINT32(irp->output, 4); // cbContext + Stream_Write_UINT32(irp->output, -1); // ReferentID - stream_write_UINT32(irp->output, 4); - stream_write_UINT32(irp->output, hContext); + Stream_Write_UINT32(irp->output, 4); + Stream_Write_UINT32(irp->output, hContext); /* TODO: store hContext in allowed context list */ @@ -295,11 +295,11 @@ static UINT32 handle_ReleaseContext(IRP* irp) UINT32 len, status; SCARDCONTEXT hContext = -1; - stream_seek(irp->input, 8); - stream_read_UINT32(irp->input, len); + Stream_Seek(irp->input, 8); + Stream_Read_UINT32(irp->input, len); - stream_seek(irp->input, 0x10); - stream_read_UINT32(irp->input, hContext); + Stream_Seek(irp->input, 0x10); + Stream_Read_UINT32(irp->input, hContext); status = SCardReleaseContext(hContext); @@ -318,8 +318,8 @@ static UINT32 handle_IsValidContext(IRP* irp) UINT32 status; SCARDCONTEXT hContext; - stream_seek(irp->input, 0x1C); - stream_read_UINT32(irp->input, hContext); + Stream_Seek(irp->input, 0x1C); + Stream_Read_UINT32(irp->input, hContext); status = SCardIsValidContext(hContext); @@ -342,16 +342,16 @@ static UINT32 handle_ListReaders(IRP* irp, BOOL wide) int elemLength, dataLength; int pos, poslen1, poslen2; - stream_seek(irp->input, 8); - stream_read_UINT32(irp->input, len); + Stream_Seek(irp->input, 8); + Stream_Read_UINT32(irp->input, len); - stream_seek(irp->input, 0x1c); - stream_read_UINT32(irp->input, len); + Stream_Seek(irp->input, 0x1c); + Stream_Read_UINT32(irp->input, len); if (len != 4) return SCARD_F_INTERNAL_ERROR; - stream_read_UINT32(irp->input, hContext); + Stream_Read_UINT32(irp->input, hContext); /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ @@ -373,13 +373,13 @@ static UINT32 handle_ListReaders(IRP* irp, BOOL wide) /* DEBUG_SCARD("Success 0x%08x %d %d", (unsigned) hContext, (unsigned) cchReaders, (int) strlen(readerList));*/ - poslen1 = stream_get_pos(irp->output); - stream_seek_UINT32(irp->output); + poslen1 = Stream_GetPosition(irp->output); + Stream_Seek_UINT32(irp->output); - stream_write_UINT32(irp->output, 0x01760650); + Stream_Write_UINT32(irp->output, 0x01760650); - poslen2 = stream_get_pos(irp->output); - stream_seek_UINT32(irp->output); + poslen2 = Stream_GetPosition(irp->output); + Stream_Seek_UINT32(irp->output); walker = readerList; dataLength = 0; @@ -397,14 +397,14 @@ static UINT32 handle_ListReaders(IRP* irp, BOOL wide) dataLength += smartcard_output_string(irp, "\0", wide); - pos = stream_get_pos(irp->output); + pos = Stream_GetPosition(irp->output); - stream_set_pos(irp->output, poslen1); - stream_write_UINT32(irp->output, dataLength); - stream_set_pos(irp->output, poslen2); - stream_write_UINT32(irp->output, dataLength); + Stream_SetPosition(irp->output, poslen1); + Stream_Write_UINT32(irp->output, dataLength); + Stream_SetPosition(irp->output, poslen2); + Stream_Write_UINT32(irp->output, dataLength); - stream_set_pos(irp->output, pos); + Stream_SetPosition(irp->output, pos); smartcard_output_repos(irp, dataLength); smartcard_output_alignment(irp, 8); @@ -427,15 +427,15 @@ static UINT32 handle_GetStatusChange(IRP* irp, BOOL wide) DWORD readerCount = 0; SCARD_READERSTATE *readerStates, *cur; - stream_seek(irp->input, 0x18); - stream_read_UINT32(irp->input, dwTimeout); - stream_read_UINT32(irp->input, readerCount); + Stream_Seek(irp->input, 0x18); + Stream_Read_UINT32(irp->input, dwTimeout); + Stream_Read_UINT32(irp->input, readerCount); - stream_seek(irp->input, 8); + Stream_Seek(irp->input, 8); - stream_read_UINT32(irp->input, hContext); + Stream_Read_UINT32(irp->input, hContext); - stream_seek(irp->input, 4); + Stream_Seek(irp->input, 4); DEBUG_SCARD("context: 0x%08x, timeout: 0x%08x, count: %d", (unsigned) hContext, (unsigned) dwTimeout, (int) readerCount); @@ -452,19 +452,19 @@ static UINT32 handle_GetStatusChange(IRP* irp, BOOL wide) { cur = &readerStates[i]; - stream_seek(irp->input, 4); + Stream_Seek(irp->input, 4); /* * TODO: on-wire is little endian; need to either * convert to host endian or fix the headers to * request the order we want */ - stream_read_UINT32(irp->input, cur->dwCurrentState); - stream_read_UINT32(irp->input, cur->dwEventState); - stream_read_UINT32(irp->input, cur->cbAtr); - stream_read(irp->input, cur->rgbAtr, 32); + Stream_Read_UINT32(irp->input, cur->dwCurrentState); + Stream_Read_UINT32(irp->input, cur->dwEventState); + Stream_Read_UINT32(irp->input, cur->cbAtr); + Stream_Read(irp->input, cur->rgbAtr, 32); - stream_seek(irp->input, 4); + Stream_Seek(irp->input, 4); /* reset high bytes? */ cur->dwCurrentState &= 0x0000FFFF; @@ -476,8 +476,8 @@ static UINT32 handle_GetStatusChange(IRP* irp, BOOL wide) cur = &readerStates[i]; UINT32 dataLength; - stream_seek(irp->input, 8); - stream_read_UINT32(irp->input, dataLength); + Stream_Seek(irp->input, 8); + Stream_Read_UINT32(irp->input, dataLength); smartcard_input_repos(irp, smartcard_input_string(irp, (char **) &cur->szReader, dataLength, wide)); DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); @@ -501,9 +501,9 @@ static UINT32 handle_GetStatusChange(IRP* irp, BOOL wide) else DEBUG_SCARD("Success"); - stream_write_UINT32(irp->output, readerCount); - stream_write_UINT32(irp->output, 0x00084dd8); - stream_write_UINT32(irp->output, readerCount); + Stream_Write_UINT32(irp->output, readerCount); + Stream_Write_UINT32(irp->output, 0x00084dd8); + Stream_Write_UINT32(irp->output, readerCount); for (i = 0; i < readerCount; i++) { @@ -515,12 +515,12 @@ static UINT32 handle_GetStatusChange(IRP* irp, BOOL wide) (unsigned) cur->dwEventState); /* TODO: do byte conversions if necessary */ - stream_write_UINT32(irp->output, cur->dwCurrentState); - stream_write_UINT32(irp->output, cur->dwEventState); - stream_write_UINT32(irp->output, cur->cbAtr); - stream_write(irp->output, cur->rgbAtr, 32); + Stream_Write_UINT32(irp->output, cur->dwCurrentState); + Stream_Write_UINT32(irp->output, cur->dwEventState); + Stream_Write_UINT32(irp->output, cur->cbAtr); + Stream_Write(irp->output, cur->rgbAtr, 32); - stream_write_zero(irp->output, 4); + Stream_Zero(irp->output, 4); free((void *)cur->szReader); } @@ -536,8 +536,8 @@ static UINT32 handle_Cancel(IRP *irp) LONG status; SCARDCONTEXT hContext; - stream_seek(irp->input, 0x1C); - stream_read_UINT32(irp->input, hContext); + Stream_Seek(irp->input, 0x1C); + Stream_Read_UINT32(irp->input, hContext); status = SCardCancel(hContext); @@ -561,14 +561,14 @@ static UINT32 handle_Connect(IRP* irp, BOOL wide) DWORD dwActiveProtocol = 0; SCARDHANDLE hCard; - stream_seek(irp->input, 0x1c); - stream_read_UINT32(irp->input, dwShareMode); - stream_read_UINT32(irp->input, dwPreferredProtocol); + Stream_Seek(irp->input, 0x1c); + Stream_Read_UINT32(irp->input, dwShareMode); + Stream_Read_UINT32(irp->input, dwPreferredProtocol); smartcard_input_reader_name(irp, &readerName, wide); - stream_seek(irp->input, 4); - stream_read_UINT32(irp->input, hContext); + Stream_Seek(irp->input, 4); + Stream_Read_UINT32(irp->input, hContext); DEBUG_SCARD("(context: 0x%08x, share: 0x%08x, proto: 0x%08x, reader: \"%s\")", (unsigned) hContext, (unsigned) dwShareMode, @@ -582,13 +582,13 @@ static UINT32 handle_Connect(IRP* irp, BOOL wide) else DEBUG_SCARD("Success 0x%08x", (unsigned) hCard); - stream_write_UINT32(irp->output, 0x00000000); - stream_write_UINT32(irp->output, 0x00000000); - stream_write_UINT32(irp->output, 0x00000004); - stream_write_UINT32(irp->output, 0x016Cff34); - stream_write_UINT32(irp->output, dwActiveProtocol); - stream_write_UINT32(irp->output, 0x00000004); - stream_write_UINT32(irp->output, hCard); + Stream_Write_UINT32(irp->output, 0x00000000); + Stream_Write_UINT32(irp->output, 0x00000000); + Stream_Write_UINT32(irp->output, 0x00000004); + Stream_Write_UINT32(irp->output, 0x016Cff34); + Stream_Write_UINT32(irp->output, dwActiveProtocol); + Stream_Write_UINT32(irp->output, 0x00000004); + Stream_Write_UINT32(irp->output, hCard); smartcard_output_alignment(irp, 8); @@ -606,15 +606,15 @@ static UINT32 handle_Reconnect(IRP* irp) DWORD dwInitialization = 0; DWORD dwActiveProtocol = 0; - stream_seek(irp->input, 0x20); - stream_read_UINT32(irp->input, dwShareMode); - stream_read_UINT32(irp->input, dwPreferredProtocol); - stream_read_UINT32(irp->input, dwInitialization); + Stream_Seek(irp->input, 0x20); + Stream_Read_UINT32(irp->input, dwShareMode); + Stream_Read_UINT32(irp->input, dwPreferredProtocol); + Stream_Read_UINT32(irp->input, dwInitialization); - stream_seek(irp->input, 0x4); - stream_read_UINT32(irp->input, hContext); - stream_seek(irp->input, 0x4); - stream_read_UINT32(irp->input, hCard); + Stream_Seek(irp->input, 0x4); + Stream_Read_UINT32(irp->input, hContext); + Stream_Seek(irp->input, 0x4); + Stream_Read_UINT32(irp->input, hCard); DEBUG_SCARD("(context: 0x%08x, hcard: 0x%08x, share: 0x%08x, proto: 0x%08x, init: 0x%08x)", (unsigned) hContext, (unsigned) hCard, @@ -628,7 +628,7 @@ static UINT32 handle_Reconnect(IRP* irp) else DEBUG_SCARD("Success (proto: 0x%08x)", (unsigned) dwActiveProtocol); - stream_write_UINT32(irp->output, dwActiveProtocol); + Stream_Write_UINT32(irp->output, dwActiveProtocol); smartcard_output_alignment(irp, 8); return status; @@ -641,12 +641,12 @@ static UINT32 handle_Disconnect(IRP* irp) SCARDHANDLE hCard; DWORD dwDisposition = 0; - stream_seek(irp->input, 0x20); - stream_read_UINT32(irp->input, dwDisposition); - stream_seek(irp->input, 4); - stream_read_UINT32(irp->input, hContext); - stream_seek(irp->input, 4); - stream_read_UINT32(irp->input, hCard); + Stream_Seek(irp->input, 0x20); + Stream_Read_UINT32(irp->input, dwDisposition); + Stream_Seek(irp->input, 4); + Stream_Read_UINT32(irp->input, hContext); + Stream_Seek(irp->input, 4); + Stream_Read_UINT32(irp->input, hCard); DEBUG_SCARD("(context: 0x%08x, hcard: 0x%08x, disposition: 0x%08x)", (unsigned) hContext, (unsigned) hCard, (unsigned) dwDisposition); @@ -668,8 +668,8 @@ static UINT32 handle_BeginTransaction(IRP* irp) LONG status; SCARDCONTEXT hCard; - stream_seek(irp->input, 0x30); - stream_read_UINT32(irp->input, hCard); + Stream_Seek(irp->input, 0x30); + Stream_Read_UINT32(irp->input, hCard); status = SCardBeginTransaction(hCard); @@ -689,11 +689,11 @@ static UINT32 handle_EndTransaction(IRP* irp) SCARDCONTEXT hCard; DWORD dwDisposition = 0; - stream_seek(irp->input, 0x20); - stream_read_UINT32(irp->input, dwDisposition); + Stream_Seek(irp->input, 0x20); + Stream_Read_UINT32(irp->input, dwDisposition); - stream_seek(irp->input, 0x0C); - stream_read_UINT32(irp->input, hCard); + Stream_Seek(irp->input, 0x0C); + Stream_Read_UINT32(irp->input, hCard); status = SCardEndTransaction(hCard, dwDisposition); @@ -721,12 +721,12 @@ static UINT32 handle_State(IRP* irp) int i; #endif - stream_seek(irp->input, 0x24); - stream_seek_UINT32(irp->input); /* atrLen */ + Stream_Seek(irp->input, 0x24); + Stream_Seek_UINT32(irp->input); /* atrLen */ - stream_seek(irp->input, 0x0c); - stream_read_UINT32(irp->input, hCard); - stream_seek(irp->input, 0x04); + Stream_Seek(irp->input, 0x0c); + Stream_Read_UINT32(irp->input, hCard); + Stream_Seek(irp->input, 0x04); #ifdef SCARD_AUTOALLOCATE readerLen = SCARD_AUTOALLOCATE; @@ -757,12 +757,12 @@ static UINT32 handle_State(IRP* irp) state = smartcard_map_state(state); - stream_write_UINT32(irp->output, state); - stream_write_UINT32(irp->output, protocol); - stream_write_UINT32(irp->output, atrLen); - stream_write_UINT32(irp->output, 0x00000001); - stream_write_UINT32(irp->output, atrLen); - stream_write(irp->output, pbAtr, atrLen); + Stream_Write_UINT32(irp->output, state); + Stream_Write_UINT32(irp->output, protocol); + Stream_Write_UINT32(irp->output, atrLen); + Stream_Write_UINT32(irp->output, 0x00000001); + Stream_Write_UINT32(irp->output, atrLen); + Stream_Write(irp->output, pbAtr, atrLen); smartcard_output_repos(irp, atrLen); smartcard_output_alignment(irp, 8); @@ -792,12 +792,12 @@ static DWORD handle_Status(IRP *irp, BOOL wide) int i; #endif - stream_seek(irp->input, 0x24); - stream_read_UINT32(irp->input, readerLen); - stream_read_UINT32(irp->input, atrLen); - stream_seek(irp->input, 0x0c); - stream_read_UINT32(irp->input, hCard); - stream_seek(irp->input, 0x4); + Stream_Seek(irp->input, 0x24); + Stream_Read_UINT32(irp->input, readerLen); + Stream_Read_UINT32(irp->input, atrLen); + Stream_Seek(irp->input, 0x0c); + Stream_Read_UINT32(irp->input, hCard); + Stream_Seek(irp->input, 0x4); atrLen = MAX_ATR_SIZE; @@ -830,30 +830,30 @@ static DWORD handle_Status(IRP *irp, BOOL wide) state = smartcard_map_state(state); - poslen1 = stream_get_pos(irp->output); - stream_write_UINT32(irp->output, readerLen); - stream_write_UINT32(irp->output, 0x00020000); - stream_write_UINT32(irp->output, state); - stream_write_UINT32(irp->output, protocol); - stream_write(irp->output, pbAtr, atrLen); + poslen1 = Stream_GetPosition(irp->output); + Stream_Write_UINT32(irp->output, readerLen); + Stream_Write_UINT32(irp->output, 0x00020000); + Stream_Write_UINT32(irp->output, state); + Stream_Write_UINT32(irp->output, protocol); + Stream_Write(irp->output, pbAtr, atrLen); if (atrLen < 32) - stream_write_zero(irp->output, 32 - atrLen); - stream_write_UINT32(irp->output, atrLen); + Stream_Zero(irp->output, 32 - atrLen); + Stream_Write_UINT32(irp->output, atrLen); - poslen2 = stream_get_pos(irp->output); - stream_write_UINT32(irp->output, readerLen); + poslen2 = Stream_GetPosition(irp->output); + Stream_Write_UINT32(irp->output, readerLen); dataLength = smartcard_output_string(irp, readerName, wide); dataLength += smartcard_output_string(irp, "\0", wide); smartcard_output_repos(irp, dataLength); - pos = stream_get_pos(irp->output); - stream_set_pos(irp->output, poslen1); - stream_write_UINT32(irp->output,dataLength); - stream_set_pos(irp->output, poslen2); - stream_write_UINT32(irp->output,dataLength); - stream_set_pos(irp->output, pos); + pos = Stream_GetPosition(irp->output); + Stream_SetPosition(irp->output, poslen1); + Stream_Write_UINT32(irp->output,dataLength); + Stream_SetPosition(irp->output, poslen2); + Stream_Write_UINT32(irp->output,dataLength); + Stream_SetPosition(irp->output, pos); smartcard_output_alignment(irp, 8); @@ -876,34 +876,34 @@ static UINT32 handle_Transmit(IRP* irp) DWORD cbSendLength = 0, cbRecvLength = 0; BYTE *sendBuf = NULL, *recvBuf = NULL; - stream_seek(irp->input, 0x14); - stream_read_UINT32(irp->input, map[0]); - stream_seek(irp->input, 0x4); - stream_read_UINT32(irp->input, map[1]); + Stream_Seek(irp->input, 0x14); + Stream_Read_UINT32(irp->input, map[0]); + Stream_Seek(irp->input, 0x4); + Stream_Read_UINT32(irp->input, map[1]); - stream_read_UINT32(irp->input, pioSendPci.dwProtocol); - stream_read_UINT32(irp->input, pioSendPci.cbPciLength); + Stream_Read_UINT32(irp->input, pioSendPci.dwProtocol); + Stream_Read_UINT32(irp->input, pioSendPci.cbPciLength); - stream_read_UINT32(irp->input, map[2]); - stream_read_UINT32(irp->input, cbSendLength); - stream_read_UINT32(irp->input, map[3]); - stream_read_UINT32(irp->input, map[4]); - stream_read_UINT32(irp->input, map[5]); - stream_read_UINT32(irp->input, cbRecvLength); + Stream_Read_UINT32(irp->input, map[2]); + Stream_Read_UINT32(irp->input, cbSendLength); + Stream_Read_UINT32(irp->input, map[3]); + Stream_Read_UINT32(irp->input, map[4]); + Stream_Read_UINT32(irp->input, map[5]); + Stream_Read_UINT32(irp->input, cbRecvLength); if (map[0] & SCARD_INPUT_LINKED) smartcard_input_skip_linked(irp); - stream_seek(irp->input, 4); - stream_read_UINT32(irp->input, hCard); + Stream_Seek(irp->input, 4); + Stream_Read_UINT32(irp->input, hCard); if (map[2] & SCARD_INPUT_LINKED) { /* sendPci */ - stream_read_UINT32(irp->input, linkedLen); + Stream_Read_UINT32(irp->input, linkedLen); - stream_read_UINT32(irp->input, pioSendPci.dwProtocol); - stream_seek(irp->input, linkedLen - 4); + Stream_Read_UINT32(irp->input, pioSendPci.dwProtocol); + Stream_Seek(irp->input, linkedLen - 4); smartcard_input_repos(irp, linkedLen); } @@ -912,10 +912,10 @@ static UINT32 handle_Transmit(IRP* irp) if (map[3] & SCARD_INPUT_LINKED) { /* send buffer */ - stream_read_UINT32(irp->input, linkedLen); + Stream_Read_UINT32(irp->input, linkedLen); sendBuf = malloc(linkedLen); - stream_read(irp->input, sendBuf, linkedLen); + Stream_Read(irp->input, sendBuf, linkedLen); smartcard_input_repos(irp, linkedLen); } @@ -925,19 +925,19 @@ static UINT32 handle_Transmit(IRP* irp) if (map[4] & SCARD_INPUT_LINKED) { /* recvPci */ - stream_read_UINT32(irp->input, linkedLen); + Stream_Read_UINT32(irp->input, linkedLen); - stream_read_UINT32(irp->input, pioRecvPci.dwProtocol); - stream_seek(irp->input, linkedLen - 4); + Stream_Read_UINT32(irp->input, pioRecvPci.dwProtocol); + Stream_Seek(irp->input, linkedLen - 4); smartcard_input_repos(irp, linkedLen); - stream_read_UINT32(irp->input, map[6]); + Stream_Read_UINT32(irp->input, map[6]); if (map[6] & SCARD_INPUT_LINKED) { /* not sure what this is */ - stream_read_UINT32(irp->input, linkedLen); - stream_seek(irp->input, linkedLen); + Stream_Read_UINT32(irp->input, linkedLen); + Stream_Seek(irp->input, linkedLen); smartcard_input_repos(irp, linkedLen); } @@ -964,7 +964,7 @@ static UINT32 handle_Transmit(IRP* irp) { DEBUG_SCARD("Success (%d bytes)", (int) cbRecvLength); - stream_write_UINT32(irp->output, 0); /* pioRecvPci 0x00; */ + Stream_Write_UINT32(irp->output, 0); /* pioRecvPci 0x00; */ smartcard_output_buffer_start(irp, cbRecvLength); /* start of recvBuf output */ @@ -993,19 +993,19 @@ static UINT32 handle_Control(IRP* irp) DWORD nBytesReturned; DWORD outBufferSize; - stream_seek(irp->input, 0x14); - stream_read_UINT32(irp->input, map[0]); - stream_seek(irp->input, 0x4); - stream_read_UINT32(irp->input, map[1]); - stream_read_UINT32(irp->input, controlCode); - stream_read_UINT32(irp->input, recvLength); - stream_read_UINT32(irp->input, map[2]); - stream_seek(irp->input, 0x4); - stream_read_UINT32(irp->input, outBufferSize); - stream_seek(irp->input, 0x4); - stream_read_UINT32(irp->input, hContext); - stream_seek(irp->input, 0x4); - stream_read_UINT32(irp->input, hCard); + Stream_Seek(irp->input, 0x14); + Stream_Read_UINT32(irp->input, map[0]); + Stream_Seek(irp->input, 0x4); + Stream_Read_UINT32(irp->input, map[1]); + Stream_Read_UINT32(irp->input, controlCode); + Stream_Read_UINT32(irp->input, recvLength); + Stream_Read_UINT32(irp->input, map[2]); + Stream_Seek(irp->input, 0x4); + Stream_Read_UINT32(irp->input, outBufferSize); + Stream_Seek(irp->input, 0x4); + Stream_Read_UINT32(irp->input, hContext); + Stream_Seek(irp->input, 0x4); + Stream_Read_UINT32(irp->input, hCard); /* Translate Windows SCARD_CTL_CODE's to corresponding local code */ if (WIN_CTL_DEVICE_TYPE(controlCode) == WIN_FILE_DEVICE_SMARTCARD) @@ -1018,14 +1018,14 @@ static UINT32 handle_Control(IRP* irp) if (map[2] & SCARD_INPUT_LINKED) { /* read real input size */ - stream_read_UINT32(irp->input, recvLength); + Stream_Read_UINT32(irp->input, recvLength); recvBuffer = malloc(recvLength); if (!recvBuffer) return smartcard_output_return(irp, SCARD_E_NO_MEMORY); - stream_read(irp->input, recvBuffer, recvLength); + Stream_Read(irp->input, recvBuffer, recvLength); } nBytesReturned = outBufferSize; @@ -1042,13 +1042,13 @@ static UINT32 handle_Control(IRP* irp) else DEBUG_SCARD("Success (out: %u bytes)", (unsigned) nBytesReturned); - stream_write_UINT32(irp->output, (UINT32) nBytesReturned); - stream_write_UINT32(irp->output, 0x00000004); - stream_write_UINT32(irp->output, nBytesReturned); + Stream_Write_UINT32(irp->output, (UINT32) nBytesReturned); + Stream_Write_UINT32(irp->output, 0x00000004); + Stream_Write_UINT32(irp->output, nBytesReturned); if (nBytesReturned > 0) { - stream_write(irp->output, sendBuffer, nBytesReturned); + Stream_Write(irp->output, sendBuffer, nBytesReturned); smartcard_output_repos(irp, nBytesReturned); } @@ -1069,12 +1069,12 @@ static UINT32 handle_GetAttrib(IRP* irp) DWORD attrLen = 0; BYTE* pbAttr = NULL; - stream_seek(irp->input, 0x20); - stream_read_UINT32(irp->input, dwAttrId); - stream_seek(irp->input, 0x4); - stream_read_UINT32(irp->input, dwAttrLen); - stream_seek(irp->input, 0xC); - stream_read_UINT32(irp->input, hCard); + Stream_Seek(irp->input, 0x20); + Stream_Read_UINT32(irp->input, dwAttrId); + Stream_Seek(irp->input, 0x4); + Stream_Read_UINT32(irp->input, dwAttrLen); + Stream_Seek(irp->input, 0xC); + Stream_Read_UINT32(irp->input, hCard); DEBUG_SCARD("hcard: 0x%08x, attrib: 0x%08x (%d bytes)", (unsigned) hCard, (unsigned) dwAttrId, (int) dwAttrLen); @@ -1148,21 +1148,21 @@ static UINT32 handle_GetAttrib(IRP* irp) { DEBUG_SCARD("Success (%d bytes)", (int) dwAttrLen); - stream_write_UINT32(irp->output, dwAttrLen); - stream_write_UINT32(irp->output, 0x00000200); - stream_write_UINT32(irp->output, dwAttrLen); + Stream_Write_UINT32(irp->output, dwAttrLen); + Stream_Write_UINT32(irp->output, 0x00000200); + Stream_Write_UINT32(irp->output, dwAttrLen); if (!pbAttr) { - stream_write_zero(irp->output, dwAttrLen); + Stream_Zero(irp->output, dwAttrLen); } else { - stream_write(irp->output, pbAttr, dwAttrLen); + Stream_Write(irp->output, pbAttr, dwAttrLen); } smartcard_output_repos(irp, dwAttrLen); /* align to multiple of 4 */ - stream_write_UINT32(irp->output, 0); + Stream_Write_UINT32(irp->output, 0); } smartcard_output_alignment(irp, 8); @@ -1182,7 +1182,7 @@ void scard_error(SMARTCARD_DEVICE* scard, IRP* irp, UINT32 ntstatus) /* [MS-RDPESC] 3.1.4.4 */ fprintf(stderr, "scard processing error %x\n", ntstatus); - stream_set_pos(irp->output, 0); /* CHECKME */ + Stream_SetPosition(irp->output, 0); /* CHECKME */ irp->IoStatus = ntstatus; irp->Complete(irp); } @@ -1209,9 +1209,9 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) SERVER_SCARD_ATRMASK* curAtr = NULL; SERVER_SCARD_ATRMASK* pAtrMasks = NULL; - stream_seek(irp->input, 0x2C); - stream_read_UINT32(irp->input, hContext); - stream_read_UINT32(irp->input, atrMaskCount); + Stream_Seek(irp->input, 0x2C); + Stream_Read_UINT32(irp->input, hContext); + Stream_Read_UINT32(irp->input, atrMaskCount); pAtrMasks = malloc(atrMaskCount * sizeof(SERVER_SCARD_ATRMASK)); @@ -1220,12 +1220,12 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) for (i = 0; i < atrMaskCount; i++) { - stream_read_UINT32(irp->input, pAtrMasks[i].cbAtr); - stream_read(irp->input, pAtrMasks[i].rgbAtr, 36); - stream_read(irp->input, pAtrMasks[i].rgbMask, 36); + Stream_Read_UINT32(irp->input, pAtrMasks[i].cbAtr); + Stream_Read(irp->input, pAtrMasks[i].rgbAtr, 36); + Stream_Read(irp->input, pAtrMasks[i].rgbMask, 36); } - stream_read_UINT32(irp->input, readerCount); + Stream_Read_UINT32(irp->input, readerCount); readerStates = malloc(readerCount * sizeof(SCARD_READERSTATE)); ZeroMemory(readerStates, readerCount * sizeof(SCARD_READERSTATE)); @@ -1237,19 +1237,19 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) { cur = &readerStates[i]; - stream_seek(irp->input, 4); + Stream_Seek(irp->input, 4); /* * TODO: on-wire is little endian; need to either * convert to host endian or fix the headers to * request the order we want */ - stream_read_UINT32(irp->input, cur->dwCurrentState); - stream_read_UINT32(irp->input, cur->dwEventState); - stream_read_UINT32(irp->input, cur->cbAtr); - stream_read(irp->input, cur->rgbAtr, 32); + Stream_Read_UINT32(irp->input, cur->dwCurrentState); + Stream_Read_UINT32(irp->input, cur->dwEventState); + Stream_Read_UINT32(irp->input, cur->cbAtr); + Stream_Read(irp->input, cur->rgbAtr, 32); - stream_seek(irp->input, 4); + Stream_Seek(irp->input, 4); /* reset high bytes? */ cur->dwCurrentState &= 0x0000FFFF; @@ -1262,8 +1262,8 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) cur = &readerStates[i]; UINT32 dataLength; - stream_seek(irp->input, 8); - stream_read_UINT32(irp->input, dataLength); + Stream_Seek(irp->input, 8); + Stream_Read_UINT32(irp->input, dataLength); smartcard_input_repos(irp, smartcard_input_string(irp, (char **) &cur->szReader, dataLength, wide)); DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); @@ -1306,18 +1306,18 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) } } - stream_write_UINT32(irp->output, readerCount); - stream_write_UINT32(irp->output, 0x00084dd8); - stream_write_UINT32(irp->output, readerCount); + Stream_Write_UINT32(irp->output, readerCount); + Stream_Write_UINT32(irp->output, 0x00084dd8); + Stream_Write_UINT32(irp->output, readerCount); for (i = 0, rsCur = readerStates; i < readerCount; i++, rsCur++) { - stream_write_UINT32(irp->output, cur->dwCurrentState); - stream_write_UINT32(irp->output, cur->dwEventState); - stream_write_UINT32(irp->output, cur->cbAtr); - stream_write(irp->output, cur->rgbAtr, 32); + Stream_Write_UINT32(irp->output, cur->dwCurrentState); + Stream_Write_UINT32(irp->output, cur->dwEventState); + Stream_Write_UINT32(irp->output, cur->cbAtr); + Stream_Write(irp->output, cur->rgbAtr, 32); - stream_write_zero(irp->output, 4); + Stream_Zero(irp->output, 4); free((void*) cur->szReader); } @@ -1334,9 +1334,9 @@ BOOL smartcard_async_op(IRP* irp) UINT32 ioctl_code; /* peek ahead */ - stream_seek(irp->input, 8); - stream_read_UINT32(irp->input, ioctl_code); - stream_rewind(irp->input, 12); + Stream_Seek(irp->input, 8); + Stream_Read_UINT32(irp->input, ioctl_code); + Stream_Rewind(irp->input, 12); switch (ioctl_code) { @@ -1384,38 +1384,38 @@ void smartcard_device_control(SMARTCARD_DEVICE* scard, IRP* irp) /* MS-RPCE, Sections 2.2.6.1 and 2.2.6.2. */ - stream_read_UINT32(irp->input, output_len); - stream_read_UINT32(irp->input, input_len); - stream_read_UINT32(irp->input, ioctl_code); + Stream_Read_UINT32(irp->input, output_len); + Stream_Read_UINT32(irp->input, input_len); + Stream_Read_UINT32(irp->input, ioctl_code); - stream_seek(irp->input, 20); /* padding */ + Stream_Seek(irp->input, 20); /* padding */ - // stream_seek(irp->input, 4); /* TODO: parse len, le, v1 */ - // stream_seek(irp->input, 4); /* 0xcccccccc */ - // stream_seek(irp->input, 4); /* rpce len */ + // Stream_Seek(irp->input, 4); /* TODO: parse len, le, v1 */ + // Stream_Seek(irp->input, 4); /* 0xcccccccc */ + // Stream_Seek(irp->input, 4); /* rpce len */ /* [MS-RDPESC] 3.2.5.1 Sending Outgoing Messages */ - stream_extend(irp->output, 2048); + Stream_EnsureRemainingCapacity(irp->output, 2048); - irp_result_pos = stream_get_pos(irp->output); + irp_result_pos = Stream_GetPosition(irp->output); - stream_write_UINT32(irp->output, 0x00000000); /* MS-RDPEFS + Stream_Write_UINT32(irp->output, 0x00000000); /* MS-RDPEFS * OutputBufferLength * will be updated * later in this * function. */ /* [MS-RPCE] 2.2.6.1 */ - stream_write_UINT32(irp->output, 0x00081001); /* len 8, LE, v1 */ - stream_write_UINT32(irp->output, 0xcccccccc); /* filler */ + Stream_Write_UINT32(irp->output, 0x00081001); /* len 8, LE, v1 */ + Stream_Write_UINT32(irp->output, 0xcccccccc); /* filler */ - output_len_pos = stream_get_pos(irp->output); - stream_seek(irp->output, 4); /* size */ + output_len_pos = Stream_GetPosition(irp->output); + Stream_Seek(irp->output, 4); /* size */ - stream_write_UINT32(irp->output, 0x0); /* filler */ + Stream_Write_UINT32(irp->output, 0x0); /* filler */ - result_pos = stream_get_pos(irp->output); - stream_seek(irp->output, 4); /* result */ + result_pos = Stream_GetPosition(irp->output); + Stream_Seek(irp->output, 4); /* result */ /* body */ switch (ioctl_code) @@ -1529,24 +1529,24 @@ void smartcard_device_control(SMARTCARD_DEVICE* scard, IRP* irp) result = 0x80100022; /* handle response packet */ - pos = stream_get_pos(irp->output); + pos = Stream_GetPosition(irp->output); stream_len = pos - irp_result_pos - 4; /* Value of OutputBufferLength */ - stream_set_pos(irp->output, irp_result_pos); - stream_write_UINT32(irp->output, stream_len); + Stream_SetPosition(irp->output, irp_result_pos); + Stream_Write_UINT32(irp->output, stream_len); - stream_set_pos(irp->output, output_len_pos); + Stream_SetPosition(irp->output, output_len_pos); /* Remove the effect of the MS-RPCE Common Type Header and Private * Header (Sections 2.2.6.1 and 2.2.6.2). */ - stream_write_UINT32(irp->output, stream_len - header_lengths); + Stream_Write_UINT32(irp->output, stream_len - header_lengths); - stream_set_pos(irp->output, result_pos); - stream_write_UINT32(irp->output, result); + Stream_SetPosition(irp->output, result_pos); + Stream_Write_UINT32(irp->output, result); - stream_set_pos(irp->output, pos); + Stream_SetPosition(irp->output, pos); #ifdef WITH_DEBUG_SCARD - winpr_HexDump(stream_get_data(irp->output), stream_get_length(irp->output)); + winpr_HexDump(Stream_Buffer(irp->output), Stream_GetPosition(irp->output)); #endif irp->IoStatus = 0; diff --git a/channels/tsmf/client/tsmf_codec.c b/channels/tsmf/client/tsmf_codec.c index 9cf19e92a..2b0af5031 100644 --- a/channels/tsmf/client/tsmf_codec.c +++ b/channels/tsmf/client/tsmf_codec.c @@ -290,10 +290,10 @@ static UINT32 tsmf_codec_parse_BITMAPINFOHEADER(TS_AM_MEDIA_TYPE* mediatype, wSt UINT32 biWidth; UINT32 biHeight; - stream_read_UINT32(s, biSize); - stream_read_UINT32(s, biWidth); - stream_read_UINT32(s, biHeight); - stream_seek(s, 28); + Stream_Read_UINT32(s, biSize); + Stream_Read_UINT32(s, biWidth); + Stream_Read_UINT32(s, biHeight); + Stream_Seek(s, 28); if (mediatype->Width == 0) mediatype->Width = biWidth; @@ -302,7 +302,7 @@ static UINT32 tsmf_codec_parse_BITMAPINFOHEADER(TS_AM_MEDIA_TYPE* mediatype, wSt /* Assume there will be no color table for video? */ if (bypass && biSize > 40) - stream_seek(s, biSize - 40); + Stream_Seek(s, biSize - 40); return (bypass ? biSize : 40); } @@ -313,22 +313,22 @@ static UINT32 tsmf_codec_parse_VIDEOINFOHEADER2(TS_AM_MEDIA_TYPE* mediatype, wSt UINT64 AvgTimePerFrame; /* VIDEOINFOHEADER2.rcSource, RECT(LONG left, LONG top, LONG right, LONG bottom) */ - stream_seek_UINT32(s); - stream_seek_UINT32(s); - stream_read_UINT32(s, mediatype->Width); - stream_read_UINT32(s, mediatype->Height); + Stream_Seek_UINT32(s); + Stream_Seek_UINT32(s); + Stream_Read_UINT32(s, mediatype->Width); + Stream_Read_UINT32(s, mediatype->Height); /* VIDEOINFOHEADER2.rcTarget */ - stream_seek(s, 16); + Stream_Seek(s, 16); /* VIDEOINFOHEADER2.dwBitRate */ - stream_read_UINT32(s, mediatype->BitRate); + Stream_Read_UINT32(s, mediatype->BitRate); /* VIDEOINFOHEADER2.dwBitErrorRate */ - stream_seek_UINT32(s); + Stream_Seek_UINT32(s); /* VIDEOINFOHEADER2.AvgTimePerFrame */ - stream_read_UINT64(s, AvgTimePerFrame); + Stream_Read_UINT64(s, AvgTimePerFrame); mediatype->SamplesPerSecond.Numerator = 1000000; mediatype->SamplesPerSecond.Denominator = (int)(AvgTimePerFrame / 10LL); /* Remaining fields before bmiHeader */ - stream_seek(s, 24); + Stream_Seek(s, 24); return 72; } @@ -349,18 +349,18 @@ typedef struct tagVIDEOINFOHEADER { UINT64 AvgTimePerFrame; /* VIDEOINFOHEADER.rcSource, RECT(LONG left, LONG top, LONG right, LONG bottom) */ - stream_seek_UINT32(s); - stream_seek_UINT32(s); - stream_read_UINT32(s, mediatype->Width); - stream_read_UINT32(s, mediatype->Height); + Stream_Seek_UINT32(s); + Stream_Seek_UINT32(s); + Stream_Read_UINT32(s, mediatype->Width); + Stream_Read_UINT32(s, mediatype->Height); /* VIDEOINFOHEADER.rcTarget */ - stream_seek(s, 16); + Stream_Seek(s, 16); /* VIDEOINFOHEADER.dwBitRate */ - stream_read_UINT32(s, mediatype->BitRate); + Stream_Read_UINT32(s, mediatype->BitRate); /* VIDEOINFOHEADER.dwBitErrorRate */ - stream_seek_UINT32(s); + Stream_Seek_UINT32(s); /* VIDEOINFOHEADER.AvgTimePerFrame */ - stream_read_UINT64(s, AvgTimePerFrame); + Stream_Read_UINT64(s, AvgTimePerFrame); mediatype->SamplesPerSecond.Numerator = 1000000; mediatype->SamplesPerSecond.Denominator = (int)(AvgTimePerFrame / 10LL); @@ -377,55 +377,55 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s) /* MajorType */ DEBUG_DVC("MajorType:"); - tsmf_print_guid(stream_get_tail(s)); + tsmf_print_guid(Stream_Pointer(s)); for (i = 0; tsmf_major_type_map[i].type != TSMF_MAJOR_TYPE_UNKNOWN; i++) { - if (memcmp(tsmf_major_type_map[i].guid, stream_get_tail(s), 16) == 0) + if (memcmp(tsmf_major_type_map[i].guid, Stream_Pointer(s), 16) == 0) break; } mediatype->MajorType = tsmf_major_type_map[i].type; if (mediatype->MajorType == TSMF_MAJOR_TYPE_UNKNOWN) ret = FALSE; DEBUG_DVC("MajorType %s", tsmf_major_type_map[i].name); - stream_seek(s, 16); + Stream_Seek(s, 16); /* SubType */ DEBUG_DVC("SubType:"); - tsmf_print_guid(stream_get_tail(s)); + tsmf_print_guid(Stream_Pointer(s)); for (i = 0; tsmf_sub_type_map[i].type != TSMF_SUB_TYPE_UNKNOWN; i++) { - if (memcmp(tsmf_sub_type_map[i].guid, stream_get_tail(s), 16) == 0) + if (memcmp(tsmf_sub_type_map[i].guid, Stream_Pointer(s), 16) == 0) break; } mediatype->SubType = tsmf_sub_type_map[i].type; if (mediatype->SubType == TSMF_SUB_TYPE_UNKNOWN) ret = FALSE; DEBUG_DVC("SubType %s", tsmf_sub_type_map[i].name); - stream_seek(s, 16); + Stream_Seek(s, 16); /* bFixedSizeSamples, bTemporalCompression, SampleSize */ - stream_seek(s, 12); + Stream_Seek(s, 12); /* FormatType */ DEBUG_DVC("FormatType:"); - tsmf_print_guid(stream_get_tail(s)); + tsmf_print_guid(Stream_Pointer(s)); for (i = 0; tsmf_format_type_map[i].type != TSMF_FORMAT_TYPE_UNKNOWN; i++) { - if (memcmp(tsmf_format_type_map[i].guid, stream_get_tail(s), 16) == 0) + if (memcmp(tsmf_format_type_map[i].guid, Stream_Pointer(s), 16) == 0) break; } mediatype->FormatType = tsmf_format_type_map[i].type; if (mediatype->FormatType == TSMF_FORMAT_TYPE_UNKNOWN) ret = FALSE; DEBUG_DVC("FormatType %s", tsmf_format_type_map[i].name); - stream_seek(s, 16); + Stream_Seek(s, 16); /* cbFormat */ - stream_read_UINT32(s, cbFormat); + Stream_Read_UINT32(s, cbFormat); DEBUG_DVC("cbFormat %d", cbFormat); #ifdef WITH_DEBUG_DVC - winpr_HexDump(stream_get_tail(s), cbFormat); + winpr_HexDump(Stream_Pointer(s), cbFormat); #endif switch (mediatype->FormatType) @@ -433,38 +433,38 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s) case TSMF_FORMAT_TYPE_MFVIDEOFORMAT: /* http://msdn.microsoft.com/en-us/library/aa473808.aspx */ - stream_seek(s, 8); /* dwSize and ? */ - stream_read_UINT32(s, mediatype->Width); /* videoInfo.dwWidth */ - stream_read_UINT32(s, mediatype->Height); /* videoInfo.dwHeight */ - stream_seek(s, 32); + Stream_Seek(s, 8); /* dwSize and ? */ + Stream_Read_UINT32(s, mediatype->Width); /* videoInfo.dwWidth */ + Stream_Read_UINT32(s, mediatype->Height); /* videoInfo.dwHeight */ + Stream_Seek(s, 32); /* videoInfo.FramesPerSecond */ - stream_read_UINT32(s, mediatype->SamplesPerSecond.Numerator); - stream_read_UINT32(s, mediatype->SamplesPerSecond.Denominator); - stream_seek(s, 80); - stream_read_UINT32(s, mediatype->BitRate); /* compressedInfo.AvgBitrate */ - stream_seek(s, 36); + Stream_Read_UINT32(s, mediatype->SamplesPerSecond.Numerator); + Stream_Read_UINT32(s, mediatype->SamplesPerSecond.Denominator); + Stream_Seek(s, 80); + Stream_Read_UINT32(s, mediatype->BitRate); /* compressedInfo.AvgBitrate */ + Stream_Seek(s, 36); if (cbFormat > 176) { mediatype->ExtraDataSize = cbFormat - 176; - mediatype->ExtraData = stream_get_tail(s); + mediatype->ExtraData = Stream_Pointer(s); } break; case TSMF_FORMAT_TYPE_WAVEFORMATEX: /* http://msdn.microsoft.com/en-us/library/dd757720.aspx */ - stream_seek_UINT16(s); - stream_read_UINT16(s, mediatype->Channels); - stream_read_UINT32(s, mediatype->SamplesPerSecond.Numerator); + Stream_Seek_UINT16(s); + Stream_Read_UINT16(s, mediatype->Channels); + Stream_Read_UINT32(s, mediatype->SamplesPerSecond.Numerator); mediatype->SamplesPerSecond.Denominator = 1; - stream_read_UINT32(s, mediatype->BitRate); + Stream_Read_UINT32(s, mediatype->BitRate); mediatype->BitRate *= 8; - stream_read_UINT16(s, mediatype->BlockAlign); - stream_read_UINT16(s, mediatype->BitsPerSample); - stream_read_UINT16(s, mediatype->ExtraDataSize); + Stream_Read_UINT16(s, mediatype->BlockAlign); + Stream_Read_UINT16(s, mediatype->BitsPerSample); + Stream_Read_UINT16(s, mediatype->ExtraDataSize); if (mediatype->ExtraDataSize > 0) - mediatype->ExtraData = stream_get_tail(s); + mediatype->ExtraData = Stream_Pointer(s); break; @@ -476,7 +476,7 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s) if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; - mediatype->ExtraData = stream_get_tail(s); + mediatype->ExtraData = Stream_Pointer(s); } break; @@ -488,7 +488,7 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s) if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; - mediatype->ExtraData = stream_get_tail(s); + mediatype->ExtraData = Stream_Pointer(s); } break; @@ -498,7 +498,7 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s) if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; - mediatype->ExtraData = stream_get_tail(s); + mediatype->ExtraData = Stream_Pointer(s); } break; @@ -520,9 +520,9 @@ BOOL tsmf_codec_check_media_type(wStream* s) BOOL ret; TS_AM_MEDIA_TYPE mediatype; - stream_get_mark(s, m); + Stream_GetPointer(s, m); ret = tsmf_codec_parse_media_type(&mediatype, s); - stream_set_mark(s, m); + Stream_SetPointer(s, m); return ret; } diff --git a/channels/tsmf/client/tsmf_constants.h b/channels/tsmf/client/tsmf_constants.h index 107372992..4e3a666a5 100644 --- a/channels/tsmf/client/tsmf_constants.h +++ b/channels/tsmf/client/tsmf_constants.h @@ -67,6 +67,7 @@ #define NOTIFY_PREROLL 0x00000113 #define UPDATE_GEOMETRY_INFO 0x00000114 #define REMOVE_STREAM 0x00000115 +#define SET_SOURCE_VIDEO_RECT 0x00000116 /* Supported platform */ #define MMREDIR_CAPABILITY_PLATFORM_MF 0x00000001 diff --git a/channels/tsmf/client/tsmf_ifman.c b/channels/tsmf/client/tsmf_ifman.c index b3bd1e97b..59059dbba 100644 --- a/channels/tsmf/client/tsmf_ifman.c +++ b/channels/tsmf/client/tsmf_ifman.c @@ -41,12 +41,12 @@ int tsmf_ifman_rim_exchange_capability_request(TSMF_IFMAN* ifman) { UINT32 CapabilityValue; - stream_read_UINT32(ifman->input, CapabilityValue); + Stream_Read_UINT32(ifman->input, CapabilityValue); DEBUG_DVC("server CapabilityValue %d", CapabilityValue); - stream_check_size(ifman->output, 8); - stream_write_UINT32(ifman->output, 1); /* CapabilityValue */ - stream_write_UINT32(ifman->output, 0); /* Result */ + Stream_EnsureRemainingCapacity(ifman->output, 8); + Stream_Write_UINT32(ifman->output, 1); /* CapabilityValue */ + Stream_Write_UINT32(ifman->output, 0); /* Result */ return 0; } @@ -60,39 +60,39 @@ int tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman) UINT32 cbCapabilityLength; UINT32 numHostCapabilities; - pos = stream_get_pos(ifman->output); - stream_check_size(ifman->output, ifman->input_size + 4); - stream_copy(ifman->output, ifman->input, ifman->input_size); + pos = Stream_GetPosition(ifman->output); + Stream_EnsureRemainingCapacity(ifman->output, ifman->input_size + 4); + Stream_Copy(ifman->output, ifman->input, ifman->input_size); - stream_set_pos(ifman->output, pos); - stream_read_UINT32(ifman->output, numHostCapabilities); + Stream_SetPosition(ifman->output, pos); + Stream_Read_UINT32(ifman->output, numHostCapabilities); for (i = 0; i < numHostCapabilities; i++) { - stream_read_UINT32(ifman->output, CapabilityType); - stream_read_UINT32(ifman->output, cbCapabilityLength); - pos = stream_get_pos(ifman->output); + Stream_Read_UINT32(ifman->output, CapabilityType); + Stream_Read_UINT32(ifman->output, cbCapabilityLength); + pos = Stream_GetPosition(ifman->output); switch (CapabilityType) { case 1: /* Protocol version request */ - stream_read_UINT32(ifman->output, v); + Stream_Read_UINT32(ifman->output, v); DEBUG_DVC("server protocol version %d", v); break; case 2: /* Supported platform */ - stream_peek_UINT32(ifman->output, v); + Stream_Peek_UINT32(ifman->output, v); DEBUG_DVC("server supported platform %d", v); /* Claim that we support both MF and DShow platforms. */ - stream_write_UINT32(ifman->output, + Stream_Write_UINT32(ifman->output, MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW); break; default: DEBUG_WARN("unknown capability type %d", CapabilityType); break; } - stream_set_pos(ifman->output, pos + cbCapabilityLength); + Stream_SetPosition(ifman->output, pos + cbCapabilityLength); } - stream_write_UINT32(ifman->output, 0); /* Result */ + Stream_Write_UINT32(ifman->output, 0); /* Result */ ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; @@ -105,9 +105,9 @@ int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman) UINT32 PlatformCookie; UINT32 FormatSupported = 1; - stream_read_UINT32(ifman->input, PlatformCookie); - stream_seek_UINT32(ifman->input); /* NoRolloverFlags (4 bytes) */ - stream_read_UINT32(ifman->input, numMediaType); + Stream_Read_UINT32(ifman->input, PlatformCookie); + Stream_Seek_UINT32(ifman->input); /* NoRolloverFlags (4 bytes) */ + Stream_Read_UINT32(ifman->input, numMediaType); DEBUG_DVC("PlatformCookie %d numMediaType %d", PlatformCookie, numMediaType); @@ -117,10 +117,10 @@ int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman) if (FormatSupported) DEBUG_DVC("format ok."); - stream_check_size(ifman->output, 12); - stream_write_UINT32(ifman->output, FormatSupported); - stream_write_UINT32(ifman->output, PlatformCookie); - stream_write_UINT32(ifman->output, 0); /* Result */ + Stream_EnsureRemainingCapacity(ifman->output, 12); + Stream_Write_UINT32(ifman->output, FormatSupported); + Stream_Write_UINT32(ifman->output, PlatformCookie); + Stream_Write_UINT32(ifman->output, 0); /* Result */ ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; @@ -143,7 +143,7 @@ int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman) } - presentation = tsmf_presentation_new(stream_get_tail(ifman->input), ifman->channel_callback); + presentation = tsmf_presentation_new(Stream_Pointer(ifman->input), ifman->channel_callback); pexisted = presentation; if (presentation == NULL) @@ -165,8 +165,8 @@ int tsmf_ifman_add_stream(TSMF_IFMAN* ifman) DEBUG_DVC(""); - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); - stream_seek(ifman->input, 16); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + Stream_Seek(ifman->input, 16); if (presentation == NULL) { @@ -174,8 +174,8 @@ int tsmf_ifman_add_stream(TSMF_IFMAN* ifman) } else { - stream_read_UINT32(ifman->input, StreamId); - stream_seek_UINT32(ifman->input); /* numMediaType */ + Stream_Read_UINT32(ifman->input, StreamId); + Stream_Seek_UINT32(ifman->input); /* numMediaType */ stream = tsmf_stream_new(presentation, StreamId); if (stream) @@ -191,9 +191,9 @@ int tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman) { DEBUG_DVC(""); - stream_check_size(ifman->output, 8); - stream_write_UINT32(ifman->output, 1); /* TopologyReady */ - stream_write_UINT32(ifman->output, 0); /* Result */ + Stream_EnsureRemainingCapacity(ifman->output, 8); + Stream_Write_UINT32(ifman->output, 1); /* TopologyReady */ + Stream_Write_UINT32(ifman->output, 0); /* Result */ ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; return 0; @@ -208,8 +208,8 @@ int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman) DEBUG_DVC(""); - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); - stream_seek(ifman->input, 16); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + Stream_Seek(ifman->input, 16); if (presentation == NULL) { @@ -217,7 +217,7 @@ int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman) } else { - stream_read_UINT32(ifman->input, StreamId); + Stream_Read_UINT32(ifman->input, StreamId); stream = tsmf_stream_find_by_id(presentation, StreamId); if (stream) tsmf_stream_free(stream); @@ -230,21 +230,64 @@ int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman) return status; } +float tsmf_stream_read_float(wStream* s) +{ + float fValue; + UINT32 iValue; + + Stream_Read_UINT32(s, iValue); + CopyMemory(&fValue, &iValue, 4); + + return fValue; +} + +int tsmf_ifman_set_source_video_rect(TSMF_IFMAN* ifman) +{ + int status = 0; + float Left, Top; + float Right, Bottom; + TSMF_PRESENTATION* presentation; + + DEBUG_DVC(""); + + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + Stream_Seek(ifman->input, 16); + + if (!presentation) + { + status = 1; + } + else + { + Left = tsmf_stream_read_float(ifman->input); /* Left (4 bytes) */ + Top = tsmf_stream_read_float(ifman->input); /* Top (4 bytes) */ + Right = tsmf_stream_read_float(ifman->input); /* Right (4 bytes) */ + Bottom = tsmf_stream_read_float(ifman->input); /* Bottom (4 bytes) */ + + DEBUG_DVC("SetSourceVideoRect: Left: %f Top: %f Right: %f Bottom: %f", + Left, Top, Right, Bottom); + } + + ifman->output_pending = TRUE; + + return status; +} + int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman) { TSMF_PRESENTATION* presentation; DEBUG_DVC(""); - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); if (presentation) tsmf_presentation_free(presentation); pexisted = 0; - stream_check_size(ifman->output, 4); - stream_write_UINT32(ifman->output, 0); /* Result */ + Stream_EnsureRemainingCapacity(ifman->output, 4); + Stream_Write_UINT32(ifman->output, 0); /* Result */ ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; return 0; @@ -256,17 +299,17 @@ int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman) DEBUG_DVC("on stream volume"); - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); if (presentation) { UINT32 newVolume; UINT32 muted; - stream_seek(ifman->input, 16); - stream_read_UINT32(ifman->input, newVolume); + Stream_Seek(ifman->input, 16); + Stream_Read_UINT32(ifman->input, newVolume); DEBUG_DVC("on stream volume: new volume=[%d]", newVolume); - stream_read_UINT32(ifman->input, muted); + Stream_Read_UINT32(ifman->input, muted); DEBUG_DVC("on stream volume: muted=[%d]", muted); tsmf_presentation_volume_changed(presentation, newVolume, muted); } @@ -286,17 +329,17 @@ int tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman) DEBUG_DVC("on channel volume"); - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); if (presentation) { UINT32 channelVolume; UINT32 changedChannel; - stream_seek(ifman->input, 16); - stream_read_UINT32(ifman->input, channelVolume); + Stream_Seek(ifman->input, 16); + Stream_Read_UINT32(ifman->input, channelVolume); DEBUG_DVC("on channel volume: channel volume=[%d]", channelVolume); - stream_read_UINT32(ifman->input, changedChannel); + Stream_Read_UINT32(ifman->input, changedChannel); DEBUG_DVC("on stream volume: changed channel=[%d]", changedChannel); } @@ -327,20 +370,20 @@ int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman) int i; int pos; - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); - stream_seek(ifman->input, 16); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + Stream_Seek(ifman->input, 16); - stream_read_UINT32(ifman->input, numGeometryInfo); - pos = stream_get_pos(ifman->input); + Stream_Read_UINT32(ifman->input, numGeometryInfo); + pos = Stream_GetPosition(ifman->input); - stream_seek(ifman->input, 12); /* VideoWindowId (8 bytes), VideoWindowState (4 bytes) */ - stream_read_UINT32(ifman->input, Width); - stream_read_UINT32(ifman->input, Height); - stream_read_UINT32(ifman->input, Left); - stream_read_UINT32(ifman->input, Top); + Stream_Seek(ifman->input, 12); /* VideoWindowId (8 bytes), VideoWindowState (4 bytes) */ + Stream_Read_UINT32(ifman->input, Width); + Stream_Read_UINT32(ifman->input, Height); + Stream_Read_UINT32(ifman->input, Left); + Stream_Read_UINT32(ifman->input, Top); - stream_set_pos(ifman->input, pos + numGeometryInfo); - stream_read_UINT32(ifman->input, cbVisibleRect); + Stream_SetPosition(ifman->input, pos + numGeometryInfo); + Stream_Read_UINT32(ifman->input, cbVisibleRect); num_rects = cbVisibleRect / 16; DEBUG_DVC("numGeometryInfo %d Width %d Height %d Left %d Top %d cbVisibleRect %d num_rects %d", @@ -359,14 +402,14 @@ int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman) for (i = 0; i < num_rects; i++) { - stream_read_UINT16(ifman->input, rects[i].y); /* Top */ - stream_seek_UINT16(ifman->input); - stream_read_UINT16(ifman->input, rects[i].x); /* Left */ - stream_seek_UINT16(ifman->input); - stream_read_UINT16(ifman->input, rects[i].height); /* Bottom */ - stream_seek_UINT16(ifman->input); - stream_read_UINT16(ifman->input, rects[i].width); /* Right */ - stream_seek_UINT16(ifman->input); + Stream_Read_UINT16(ifman->input, rects[i].y); /* Top */ + Stream_Seek_UINT16(ifman->input); + Stream_Read_UINT16(ifman->input, rects[i].x); /* Left */ + Stream_Seek_UINT16(ifman->input); + Stream_Read_UINT16(ifman->input, rects[i].height); /* Bottom */ + Stream_Seek_UINT16(ifman->input); + Stream_Read_UINT16(ifman->input, rects[i].width); /* Right */ + Stream_Seek_UINT16(ifman->input); rects[i].width -= rects[i].x; rects[i].height -= rects[i].y; @@ -407,15 +450,15 @@ int tsmf_ifman_on_sample(TSMF_IFMAN* ifman) UINT32 SampleExtensions; UINT32 cbData; - stream_seek(ifman->input, 16); - stream_read_UINT32(ifman->input, StreamId); - stream_seek_UINT32(ifman->input); /* numSample */ - stream_read_UINT64(ifman->input, SampleStartTime); - stream_read_UINT64(ifman->input, SampleEndTime); - stream_read_UINT64(ifman->input, ThrottleDuration); - stream_seek_UINT32(ifman->input); /* SampleFlags */ - stream_read_UINT32(ifman->input, SampleExtensions); - stream_read_UINT32(ifman->input, cbData); + Stream_Seek(ifman->input, 16); + Stream_Read_UINT32(ifman->input, StreamId); + Stream_Seek_UINT32(ifman->input); /* numSample */ + Stream_Read_UINT64(ifman->input, SampleStartTime); + Stream_Read_UINT64(ifman->input, SampleEndTime); + Stream_Read_UINT64(ifman->input, ThrottleDuration); + Stream_Seek_UINT32(ifman->input); /* SampleFlags */ + Stream_Read_UINT32(ifman->input, SampleExtensions); + Stream_Read_UINT32(ifman->input, cbData); DEBUG_DVC("MessageId %d StreamId %d SampleStartTime %d SampleEndTime %d " "ThrottleDuration %d SampleExtensions %d cbData %d", @@ -440,7 +483,7 @@ int tsmf_ifman_on_sample(TSMF_IFMAN* ifman) tsmf_stream_push_sample(stream, ifman->channel_callback, ifman->message_id, SampleStartTime, SampleEndTime, ThrottleDuration, SampleExtensions, - cbData, stream_get_tail(ifman->input)); + cbData, Stream_Pointer(ifman->input)); ifman->output_pending = TRUE; @@ -452,8 +495,8 @@ int tsmf_ifman_on_flush(TSMF_IFMAN* ifman) UINT32 StreamId; TSMF_PRESENTATION* presentation; - stream_seek(ifman->input, 16); - stream_read_UINT32(ifman->input, StreamId); + Stream_Seek(ifman->input, 16); + Stream_Read_UINT32(ifman->input, StreamId); DEBUG_DVC("StreamId %d", StreamId); presentation = tsmf_presentation_find_by_id(ifman->presentation_id); @@ -477,9 +520,9 @@ int tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman) TSMF_STREAM* stream; TSMF_PRESENTATION* presentation; - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); - stream_seek(ifman->input, 16); - stream_read_UINT32(ifman->input, StreamId); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + Stream_Seek(ifman->input, 16); + Stream_Read_UINT32(ifman->input, StreamId); if (presentation) { @@ -489,11 +532,11 @@ int tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman) } DEBUG_DVC("StreamId %d", StreamId); - stream_check_size(ifman->output, 16); - stream_write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ - stream_write_UINT32(ifman->output, StreamId); /* StreamId */ - stream_write_UINT32(ifman->output, TSMM_CLIENT_EVENT_ENDOFSTREAM); /* EventId */ - stream_write_UINT32(ifman->output, 0); /* cbData */ + Stream_EnsureRemainingCapacity(ifman->output, 16); + Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ + Stream_Write_UINT32(ifman->output, StreamId); /* StreamId */ + Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_ENDOFSTREAM); /* EventId */ + Stream_Write_UINT32(ifman->output, 0); /* cbData */ ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; return 0; @@ -505,18 +548,18 @@ int tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman) DEBUG_DVC(""); - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); if (presentation) tsmf_presentation_start(presentation); else DEBUG_WARN("unknown presentation id"); - stream_check_size(ifman->output, 16); - stream_write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ - stream_write_UINT32(ifman->output, 0); /* StreamId */ - stream_write_UINT32(ifman->output, TSMM_CLIENT_EVENT_START_COMPLETED); /* EventId */ - stream_write_UINT32(ifman->output, 0); /* cbData */ + Stream_EnsureRemainingCapacity(ifman->output, 16); + Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ + Stream_Write_UINT32(ifman->output, 0); /* StreamId */ + Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_START_COMPLETED); /* EventId */ + Stream_Write_UINT32(ifman->output, 0); /* cbData */ ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; return 0; @@ -531,7 +574,7 @@ int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman) /* Added pause control so gstreamer pipeline can be paused accordingly */ - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); if (presentation) tsmf_presentation_paused(presentation); @@ -550,7 +593,7 @@ int tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman) /* Added restart control so gstreamer pipeline can be resumed accordingly */ - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); if (presentation) tsmf_presentation_restarted(presentation); @@ -566,18 +609,18 @@ int tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman) DEBUG_DVC(""); - presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); if (presentation) tsmf_presentation_stop(presentation); else DEBUG_WARN("unknown presentation id"); - stream_check_size(ifman->output, 16); - stream_write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ - stream_write_UINT32(ifman->output, 0); /* StreamId */ - stream_write_UINT32(ifman->output, TSMM_CLIENT_EVENT_STOP_COMPLETED); /* EventId */ - stream_write_UINT32(ifman->output, 0); /* cbData */ + Stream_EnsureRemainingCapacity(ifman->output, 16); + Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ + Stream_Write_UINT32(ifman->output, 0); /* StreamId */ + Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_STOP_COMPLETED); /* EventId */ + Stream_Write_UINT32(ifman->output, 0); /* cbData */ ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; return 0; @@ -587,11 +630,11 @@ int tsmf_ifman_on_playback_rate_changed(TSMF_IFMAN * ifman) { DEBUG_DVC(""); - stream_check_size(ifman->output, 16); - stream_write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ - stream_write_UINT32(ifman->output, 0); /* StreamId */ - stream_write_UINT32(ifman->output, TSMM_CLIENT_EVENT_MONITORCHANGED); /* EventId */ - stream_write_UINT32(ifman->output, 0); /* cbData */ + Stream_EnsureRemainingCapacity(ifman->output, 16); + Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ + Stream_Write_UINT32(ifman->output, 0); /* StreamId */ + Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_MONITORCHANGED); /* EventId */ + Stream_Write_UINT32(ifman->output, 0); /* cbData */ ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; return 0; diff --git a/channels/tsmf/client/tsmf_ifman.h b/channels/tsmf/client/tsmf_ifman.h index 8d3fbc2a5..56ae4c5e7 100644 --- a/channels/tsmf/client/tsmf_ifman.h +++ b/channels/tsmf/client/tsmf_ifman.h @@ -45,6 +45,7 @@ int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman); int tsmf_ifman_add_stream(TSMF_IFMAN* ifman); int tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman); int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman); +int tsmf_ifman_set_source_video_rect(TSMF_IFMAN* ifman); int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman); int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman); int tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman); diff --git a/channels/tsmf/client/tsmf_main.c b/channels/tsmf/client/tsmf_main.c index 591b59659..e449e5935 100644 --- a/channels/tsmf/client/tsmf_main.c +++ b/channels/tsmf/client/tsmf_main.c @@ -81,23 +81,23 @@ void tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback, int status; TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback; - s = stream_new(32); - stream_write_UINT32(s, TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY); - stream_write_UINT32(s, message_id); - stream_write_UINT32(s, PLAYBACK_ACK); /* FunctionId */ - stream_write_UINT32(s, callback->stream_id); /* StreamId */ - stream_write_UINT64(s, duration); /* DataDuration */ - stream_write_UINT64(s, data_size); /* cbData */ + s = Stream_New(NULL, 32); + Stream_Write_UINT32(s, TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY); + Stream_Write_UINT32(s, message_id); + Stream_Write_UINT32(s, PLAYBACK_ACK); /* FunctionId */ + Stream_Write_UINT32(s, callback->stream_id); /* StreamId */ + Stream_Write_UINT64(s, duration); /* DataDuration */ + Stream_Write_UINT64(s, data_size); /* cbData */ - DEBUG_DVC("response size %d", (int) stream_get_length(s)); - status = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL); + DEBUG_DVC("response size %d", (int) Stream_GetPosition(s)); + status = callback->channel->Write(callback->channel, Stream_GetPosition(s), Stream_Buffer(s), NULL); if (status) { DEBUG_WARN("response error %d", status); } - stream_free(s); + Stream_Free(s, TRUE); } BOOL tsmf_push_event(IWTSVirtualChannelCallback* pChannelCallback, wMessage* event) @@ -136,14 +136,14 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, DEBUG_WARN("invalid size. cbSize=%d", cbSize); return 1; } - input = stream_new(0); - stream_attach(input, (BYTE*) pBuffer, cbSize); - output = stream_new(256); - stream_seek(output, 8); - stream_read_UINT32(input, InterfaceId); - stream_read_UINT32(input, MessageId); - stream_read_UINT32(input, FunctionId); + input = Stream_New((BYTE*) pBuffer, cbSize); + output = Stream_New(NULL, 256); + Stream_Seek(output, 8); + + Stream_Read_UINT32(input, InterfaceId); + Stream_Read_UINT32(input, MessageId); + Stream_Read_UINT32(input, FunctionId); DEBUG_DVC("cbSize=%d InterfaceId=0x%X MessageId=0x%X FunctionId=0x%X", cbSize, InterfaceId, MessageId, FunctionId); @@ -181,9 +181,9 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, switch (FunctionId) { case SET_CHANNEL_PARAMS: - memcpy(callback->presentation_id, stream_get_tail(input), 16); - stream_seek(input, 16); - stream_read_UINT32(input, callback->stream_id); + memcpy(callback->presentation_id, Stream_Pointer(input), 16); + Stream_Seek(input, 16); + Stream_Read_UINT32(input, callback->stream_id); DEBUG_DVC("SET_CHANNEL_PARAMS StreamId=%d", callback->stream_id); ifman.output_pending = TRUE; status = 0; @@ -213,6 +213,10 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, status = tsmf_ifman_remove_stream(&ifman); break; + case SET_SOURCE_VIDEO_RECT: + status = tsmf_ifman_set_source_video_rect(&ifman); + break; + case SHUTDOWN_PRESENTATION_REQ: status = tsmf_ifman_shutdown_presentation(&ifman); break; @@ -282,8 +286,7 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, break; } - stream_detach(input); - stream_free(input); + Stream_Free(input, FALSE); input = NULL; ifman.input = NULL; @@ -317,20 +320,20 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, if (status == 0 && !ifman.output_pending) { /* Response packet does not have FunctionId */ - length = stream_get_length(output); - stream_set_pos(output, 0); - stream_write_UINT32(output, ifman.output_interface_id); - stream_write_UINT32(output, MessageId); + length = Stream_GetPosition(output); + Stream_SetPosition(output, 0); + Stream_Write_UINT32(output, ifman.output_interface_id); + Stream_Write_UINT32(output, MessageId); DEBUG_DVC("response size %d", length); - status = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL); + status = callback->channel->Write(callback->channel, length, Stream_Buffer(output), NULL); if (status) { DEBUG_WARN("response error %d", status); } } - stream_free(output); + Stream_Free(output, TRUE); return status; } diff --git a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake index 639d5ac80..1632a7c18 100644 --- a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake +++ b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake @@ -4,11 +4,13 @@ android:installLocation="auto" package="com.freerdp.freerdpcore" android:versionCode="1" - android:versionName="@FREERDP_VERSION_FULL@" > + android:versionName="@GIT_REVISION@" > + + diff --git a/client/Android/FreeRDPCore/jni/CMakeLists.txt b/client/Android/FreeRDPCore/jni/CMakeLists.txt index 58d96f6c7..5aec24ef1 100644 --- a/client/Android/FreeRDPCore/jni/CMakeLists.txt +++ b/client/Android/FreeRDPCore/jni/CMakeLists.txt @@ -33,6 +33,8 @@ set(${MODULE_PREFIX}_SRCS android_event.h android_freerdp.c android_freerdp.h + android_jni_utils.c + android_jni_utils.h android_jni_callback.c android_jni_callback.h) @@ -40,6 +42,12 @@ set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} generated/android_freerdp_jni.c generated/android_freerdp_jni.h) +if(WITH_CLIENT_CHANNELS) + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} + android_cliprdr.c + android_cliprdr.h) +endif() + add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS}) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client) diff --git a/client/Android/FreeRDPCore/jni/android_cliprdr.c b/client/Android/FreeRDPCore/jni/android_cliprdr.c new file mode 100644 index 000000000..f34014de5 --- /dev/null +++ b/client/Android/FreeRDPCore/jni/android_cliprdr.c @@ -0,0 +1,619 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Android Clipboard Redirection + * + * Copyright 2013 Felix Long + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include +#include + +#include +#include +#include + +#include "android_debug.h" +#include "android_cliprdr.h" +#include "android_jni_utils.h" +#include "android_jni_callback.h" + +typedef struct clipboard_context clipboardContext; +struct clipboard_context +{ + freerdp* instance; + rdpChannels* channels; + + /* server->client data */ + UINT32* formats; + int num_formats; + BYTE* data; + UINT32 data_format; + int data_length; + + /* client->server data */ + UINT32* android_formats; + int android_num_formats; + BYTE* android_data; + int android_data_length; +}; + +static BYTE* lf2crlf(BYTE* data, int* size) +{ + BYTE c; + BYTE* outbuf; + BYTE* out; + BYTE* in_end; + BYTE* in; + int out_size; + + out_size = (*size) * 2 + 1; + outbuf = (BYTE*) malloc(out_size); + ZeroMemory(outbuf, out_size); + + out = outbuf; + in = data; + in_end = data + (*size); + + while (in < in_end) + { + c = *in++; + if (c == '\n') + { + *out++ = '\r'; + *out++ = '\n'; + } + else + { + *out++ = c; + } + } + + *out++ = 0; + *size = out - outbuf; + + return outbuf; +} + +static void crlf2lf(BYTE* data, int* size) +{ + BYTE c; + BYTE* out; + BYTE* in; + BYTE* in_end; + + out = data; + in = data; + in_end = data + (*size); + + while (in < in_end) + { + c = *in++; + + if (c != '\r') + *out++ = c; + } + + *size = out - data; +} + +static void be2le(BYTE* data, int size) +{ + BYTE c; + + while (size >= 2) + { + c = data[0]; + data[0] = data[1]; + data[1] = c; + + data += 2; + size -= 2; + } +} + +void android_cliprdr_init(freerdp* inst) +{ + androidContext* ctx = (androidContext*)inst->context; + clipboardContext* cb; + + cb = (clipboardContext*)malloc(sizeof(clipboardContext)); + ZeroMemory(cb, sizeof(clipboardContext)); + cb->instance = inst; + cb->channels = inst->context->channels; + + cb->android_formats = (UINT32*)malloc(sizeof(UINT32) * 3); + cb->android_formats[0] = CB_FORMAT_TEXT; + cb->android_formats[1] = CB_FORMAT_UNICODETEXT; + cb->android_formats[2] = CB_FORMAT_HTML; + cb->android_num_formats = 3; + +#if 0 + cb->android_data = strdup("ANDROID_CLIPBOARD_TEST"); + cb->android_data_length = strlen(cb->android_data); +#endif + + ctx->clipboard_context = cb; +} + +void android_cliprdr_uninit(freerdp* inst) +{ + androidContext* ctx = (androidContext*)inst->context; + clipboardContext* cb = (clipboardContext*)ctx->clipboard_context; + + if (cb) + { + if (cb->formats) + free(cb->formats); + if (cb->data) + free(cb->data); + if (cb->android_formats) + free(cb->android_formats); + if (cb->android_data) + free(cb->android_data); + free(cb); + ctx->clipboard_context = NULL; + } +} + +static void android_cliprdr_send_null_format_list(clipboardContext* cb) +{ + RDP_CB_FORMAT_LIST_EVENT* event; + + event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class, + CliprdrChannel_FormatList, NULL, NULL); + + event->num_formats = 0; + + freerdp_channels_send_event(cb->channels, (wMessage*) event); +} + +static void android_cliprdr_send_supported_format_list(clipboardContext* cb) +{ + int i; + RDP_CB_FORMAT_LIST_EVENT* event; + + event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class, + CliprdrChannel_FormatList, NULL, NULL); + + event->formats = (UINT32*) malloc(sizeof(UINT32) * cb->android_num_formats); + event->num_formats = cb->android_num_formats; + + for (i = 0; i < cb->android_num_formats; i++) + { + event->formats[i] = cb->android_formats[i]; + } + + freerdp_channels_send_event(cb->channels, (wMessage*) event); +} + +static void android_cliprdr_send_format_list(clipboardContext* cb) +{ + if (cb->android_data) + { + android_cliprdr_send_supported_format_list(cb); + } + else + { + android_cliprdr_send_null_format_list(cb); + } +} + +static void android_cliprdr_send_data_request(clipboardContext* cb, UINT32 format) +{ + RDP_CB_DATA_REQUEST_EVENT* event; + + event = (RDP_CB_DATA_REQUEST_EVENT*) freerdp_event_new(CliprdrChannel_Class, + CliprdrChannel_DataRequest, NULL, NULL); + + event->format = format; + + freerdp_channels_send_event(cb->channels, (wMessage*) event); +} + +static void android_cliprdr_send_data_response(clipboardContext* cb, BYTE* data, int size) +{ + RDP_CB_DATA_RESPONSE_EVENT* event; + + event = (RDP_CB_DATA_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class, + CliprdrChannel_DataResponse, NULL, NULL); + + event->data = data; + event->size = size; + + freerdp_channels_send_event(cb->channels, (wMessage*) event); +} + +static void android_cliprdr_send_null_data_response(clipboardContext* cb) +{ + android_cliprdr_send_data_response(cb, NULL, 0); +} + +static void android_cliprdr_process_cb_monitor_ready_event(clipboardContext* cb) +{ + android_cliprdr_send_format_list(cb); +} + +static BYTE* android_cliprdr_process_requested_unicodetext(BYTE* data, int* size) +{ + char* inbuf; + WCHAR* outbuf = NULL; + int out_size; + + inbuf = (char*) lf2crlf(data, size); + out_size = ConvertToUnicode(CP_UTF8, 0, inbuf, -1, &outbuf, 0); + free(inbuf); + + *size = (int) ((out_size + 1) * 2); + + return (BYTE*) outbuf; +} + +static BYTE* android_cliprdr_process_requested_text(BYTE* data, int* size) +{ + BYTE* outbuf; + + outbuf = lf2crlf(data, size); + + return outbuf; +} + +static BYTE* android_cliprdr_process_requested_html(BYTE* data, int* size) +{ + char* inbuf; + BYTE* in; + BYTE* outbuf; + char num[11]; + + inbuf = NULL; + + if (*size > 2) + { + if ((BYTE) data[0] == 0xFE && (BYTE) data[1] == 0xFF) + { + be2le(data, *size); + } + + if ((BYTE) data[0] == 0xFF && (BYTE) data[1] == 0xFE) + { + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) (data + 2), (*size - 2) / 2, &inbuf, 0, NULL, NULL); + } + } + + if (inbuf == NULL) + { + inbuf = malloc(*size + 1); + ZeroMemory(inbuf, *size + 1); + + memcpy(inbuf, data, *size); + } + + outbuf = (BYTE*) malloc(*size + 200); + ZeroMemory(outbuf, *size + 200); + + strcpy((char*) outbuf, + "Version:0.9\r\n" + "StartHTML:0000000000\r\n" + "EndHTML:0000000000\r\n" + "StartFragment:0000000000\r\n" + "EndFragment:0000000000\r\n"); + + in = (BYTE*) strstr((char*) inbuf, ""); + } + strcat((char*) outbuf, ""); + /* StartFragment */ + snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf)); + memcpy(outbuf + 69, num, 10); + strcat((char*) outbuf, (char*) inbuf); + /* EndFragment */ + snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf)); + memcpy(outbuf + 93, num, 10); + strcat((char*) outbuf, ""); + if (in == NULL) + { + strcat((char*) outbuf, ""); + } + /* EndHTML */ + snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf)); + memcpy(outbuf + 43, num, 10); + + *size = strlen((char*) outbuf) + 1; + free(inbuf); + + return outbuf; +} + +static void android_cliprdr_process_cb_data_request_event(clipboardContext* cb, RDP_CB_DATA_REQUEST_EVENT* event) +{ + int i; + + DEBUG_ANDROID("format %d", event->format); + + for(i = 0; i < cb->android_num_formats; i++) + { + if (event->format == cb->android_formats[i]) + break; + } + + if (i >= cb->android_num_formats) + { + DEBUG_ANDROID("unsupported format requested"); + android_cliprdr_send_null_data_response(cb); + } + else if (!cb->android_data) + { + DEBUG_ANDROID("no android clipdata"); + android_cliprdr_send_null_data_response(cb); + } + else + { + BYTE* outbuf; + int size = cb->android_data_length; + + switch (event->format) + { + case CB_FORMAT_RAW: + case CB_FORMAT_PNG: + case CB_FORMAT_JPEG: + case CB_FORMAT_GIF: + case CB_FORMAT_DIB: + default: + DEBUG_ANDROID("unsupported format %x\n", event->format); + outbuf = NULL; + break; + + case CB_FORMAT_UNICODETEXT: + outbuf = android_cliprdr_process_requested_unicodetext(cb->android_data, &size); + break; + + case CB_FORMAT_TEXT: + outbuf = android_cliprdr_process_requested_text(cb->android_data, &size); + break; + + case CB_FORMAT_HTML: + outbuf = android_cliprdr_process_requested_html(cb->android_data, &size); + break; + } + if (outbuf) + android_cliprdr_send_data_response(cb, outbuf, size); + else + android_cliprdr_send_null_data_response(cb); + } + + /* Resend the format list, otherwise the server won't request again for the next paste */ + android_cliprdr_send_format_list(cb); +} + +static BOOL android_cliprdr_has_format(UINT32* formats, int num_formats, UINT32 format) +{ + int i; + for(i = 0; i < num_formats; i++) + { + if (formats[i] == format) + return TRUE; + } + return FALSE; +} + +static void android_cliprdr_process_cb_format_list_event(clipboardContext* cb, RDP_CB_FORMAT_LIST_EVENT* event) +{ + if (cb->data) + { + free(cb->data); + cb->data = NULL; + cb->data_length = 0; + } + + if (cb->formats) + free(cb->formats); + + cb->data_format = CB_FORMAT_RAW; + cb->formats = event->formats; + cb->num_formats = event->num_formats; + event->formats = NULL; + event->num_formats = 0; + + if (android_cliprdr_has_format(cb->formats, cb->num_formats, CB_FORMAT_TEXT)) + { + cb->data_format = CB_FORMAT_TEXT; + android_cliprdr_send_data_request(cb, CB_FORMAT_TEXT); + } + else if (android_cliprdr_has_format(cb->formats, cb->num_formats, CB_FORMAT_UNICODETEXT)) + { + cb->data_format = CB_FORMAT_UNICODETEXT; + android_cliprdr_send_data_request(cb, CB_FORMAT_UNICODETEXT); + } + else if (android_cliprdr_has_format(cb->formats, cb->num_formats, CB_FORMAT_HTML)) + { + cb->data_format = CB_FORMAT_HTML; + android_cliprdr_send_data_request(cb, CB_FORMAT_HTML); + } +} + +static void android_cliprdr_process_text(clipboardContext* cb, BYTE* data, int size) +{ + if (size > 0 && data) + { + cb->data = (BYTE*) malloc(size + 1); + memcpy(cb->data, data, size); + cb->data[size] = 0; + cb->data_length = size; + } +} + +static void android_cliprdr_process_unicodetext(clipboardContext* cb, BYTE* data, int size) +{ + cb->data_length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) data, size / 2, (CHAR**) &(cb->data), 0, NULL, NULL); + crlf2lf(cb->data, &cb->data_length); +} + +static void android_cliprdr_process_html(clipboardContext* cb, BYTE* data, int size) +{ + char* start_str; + char* end_str; + int start; + int end; + + start_str = strstr((char*) data, "StartHTML:"); + end_str = strstr((char*) data, "EndHTML:"); + if (start_str == NULL || end_str == NULL) + { + DEBUG_ANDROID("invalid HTML clipboard format"); + return; + } + start = atoi(start_str + 10); + end = atoi(end_str + 8); + if (start > size || end > size || start >= end) + { + DEBUG_ANDROID("invalid HTML offset"); + return; + } + + cb->data = (BYTE*) malloc(end - start + 1); + memcpy(cb->data, data + start, end - start); + cb->data[end - start] = 0; + cb->data_length = end - start; +} + +static void android_cliprdr_process_cb_data_response_event(clipboardContext* cb, RDP_CB_DATA_RESPONSE_EVENT* event) +{ + DEBUG_ANDROID("size=%d", event->size); + + if (event->size > 0) + { + if (cb->data) + { + free(cb->data); + cb->data = NULL; + cb->data_length = 0; + } + switch (cb->data_format) + { + case CB_FORMAT_RAW: + case CB_FORMAT_PNG: + case CB_FORMAT_JPEG: + case CB_FORMAT_GIF: + case CB_FORMAT_DIB: + default: + DEBUG_ANDROID("unsupported format\n"); + break; + + case CB_FORMAT_TEXT: + android_cliprdr_process_text(cb, event->data, event->size - 1); + break; + + case CB_FORMAT_UNICODETEXT: + android_cliprdr_process_unicodetext(cb, event->data, event->size - 2); + break; + + case CB_FORMAT_HTML: + android_cliprdr_process_html(cb, event->data, event->size); + break; + } + DEBUG_ANDROID("computer_clipboard_data %s ", (char*)cb->data); + if (cb->data) + { //CALLBACK + JNIEnv* env; + jboolean attached = jni_attach_thread(&env); + jstring jdata = jniNewStringUTF(env, cb->data, cb->data_length); + + freerdp_callback("OnRemoteClipboardChanged", "(ILjava/lang/String;)V", cb->instance, jdata); + + (*env)->DeleteLocalRef(env, jdata); + if(attached == JNI_TRUE) + { + jni_detach_thread(); + } + } + } +} + +void android_process_cliprdr_event(freerdp* inst, wMessage* event) +{ + androidContext* ctx = (androidContext*)inst->context; + clipboardContext* cb = (clipboardContext*) ctx->clipboard_context; + + if (!cb) + { + return; + } + + switch (GetMessageType(event->id)) + { + case CliprdrChannel_MonitorReady: + android_cliprdr_process_cb_monitor_ready_event(cb); + break; + + case CliprdrChannel_FormatList: + android_cliprdr_process_cb_format_list_event(cb, (RDP_CB_FORMAT_LIST_EVENT*) event); + break; + + case CliprdrChannel_DataRequest: + android_cliprdr_process_cb_data_request_event(cb, (RDP_CB_DATA_REQUEST_EVENT*) event); + break; + + case CliprdrChannel_DataResponse: + android_cliprdr_process_cb_data_response_event(cb, (RDP_CB_DATA_RESPONSE_EVENT*) event); + break; + + default: + DEBUG_ANDROID("unknown event type %d", GetMessageType(event->id)); + break; + } +} + +void android_process_cliprdr_send_clipboard_data(freerdp* inst, void* data, int len) +{ + androidContext* ctx = (androidContext*)inst->context; + clipboardContext* cb = (clipboardContext*) ctx->clipboard_context; + + DEBUG_ANDROID("android_clipboard_data %s ", (char*)data); + + if (cb && (data == NULL || cb->android_data == NULL || len != cb->android_data_length || memcmp(data, cb->android_data, len))) + { + if (cb->android_data) + { + free(cb->android_data); + cb->android_data = NULL; + cb->android_data_length = 0; + } + if (data) + { + cb->android_data = (BYTE*)malloc(len + 1); + memcpy(cb->android_data, data, len); + cb->android_data[len] = 0; + cb->android_data_length = len; + } + android_cliprdr_send_format_list(cb); + } +} + diff --git a/client/Mac/AppDelegate.h b/client/Android/FreeRDPCore/jni/android_cliprdr.h similarity index 59% rename from client/Mac/AppDelegate.h rename to client/Android/FreeRDPCore/jni/android_cliprdr.h index a050c8d6c..233bff380 100644 --- a/client/Mac/AppDelegate.h +++ b/client/Android/FreeRDPCore/jni/android_cliprdr.h @@ -1,8 +1,8 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * MacFreeRDP + * Android Clipboard Redirection * - * Copyright 2012 Thomas Goddard + * Copyright 2013 Felix Long * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,14 @@ * limitations under the License. */ -#import -#import "MRDPView.h" +#ifndef __ANDROID_CLIPRDR_H__ +#define __ANDROID_CLIPRDR_H__ -@interface AppDelegate : NSObject +#include "android_freerdp.h" -@property (assign) IBOutlet MRDPView *mrdpView; -@property (assign) IBOutlet NSWindow *window; +void android_cliprdr_init(freerdp* inst); +void android_cliprdr_uninit(freerdp* inst); +void android_process_cliprdr_send_clipboard_data(freerdp* inst, void* data, int len); +void android_process_cliprdr_event(freerdp* inst, wMessage* event); -int rdp_connect(void); -@end +#endif /* __ANDROID_CLIPRDR_H__ */ diff --git a/client/Android/FreeRDPCore/jni/android_event.c b/client/Android/FreeRDPCore/jni/android_event.c index bb0f55bb1..c25582cfc 100644 --- a/client/Android/FreeRDPCore/jni/android_event.c +++ b/client/Android/FreeRDPCore/jni/android_event.c @@ -26,6 +26,7 @@ #endif #include "android_freerdp.h" +#include "android_cliprdr.h" int android_is_event_set(ANDROID_EVENT_QUEUE * queue) { @@ -137,6 +138,12 @@ int android_process_event(ANDROID_EVENT_QUEUE * queue, freerdp * inst) inst->input->MouseEvent(inst->input, cursor_event->flags, cursor_event->x, cursor_event->y); android_event_cursor_free(cursor_event); } + else if (event->type == EVENT_TYPE_CLIPBOARD) + { + ANDROID_EVENT_CLIPBOARD* clipboard_event = (ANDROID_EVENT_CLIPBOARD*)event; + android_process_cliprdr_send_clipboard_data(inst, clipboard_event->data, clipboard_event->data_length); + android_event_clipboard_free(clipboard_event); + } else if (event->type == EVENT_TYPE_DISCONNECT) { android_event_disconnect_free(event); @@ -254,6 +261,36 @@ void android_event_disconnect_free(ANDROID_EVENT* event) free(event); } +ANDROID_EVENT_CLIPBOARD* android_event_clipboard_new(void* data, int data_length) +{ + ANDROID_EVENT_CLIPBOARD* event; + + event = (ANDROID_EVENT_CLIPBOARD*) malloc(sizeof(ANDROID_EVENT_CLIPBOARD)); + memset(event, 0, sizeof(ANDROID_EVENT_CLIPBOARD)); + + event->type = EVENT_TYPE_CLIPBOARD; + if (data) + { + event->data = malloc(data_length); + memcpy(event->data, data, data_length); + event->data_length = data_length; + } + + return event; +} + +void android_event_clipboard_free(ANDROID_EVENT_CLIPBOARD* event) +{ + if (event != NULL) + { + if (event->data) + { + free(event->data); + } + free(event); + } +} + void android_event_queue_init(freerdp * inst) { androidContext* aCtx = (androidContext*)inst->context; diff --git a/client/Android/FreeRDPCore/jni/android_event.h b/client/Android/FreeRDPCore/jni/android_event.h index 7a3b6e599..7872ec770 100644 --- a/client/Android/FreeRDPCore/jni/android_event.h +++ b/client/Android/FreeRDPCore/jni/android_event.h @@ -17,6 +17,7 @@ #define EVENT_TYPE_CURSOR 2 #define EVENT_TYPE_DISCONNECT 3 #define EVENT_TYPE_KEY_UNICODE 4 +#define EVENT_TYPE_CLIPBOARD 5 struct _ANDROID_EVENT { @@ -41,6 +42,14 @@ struct _ANDROID_EVENT_CURSOR }; typedef struct _ANDROID_EVENT_CURSOR ANDROID_EVENT_CURSOR; +struct _ANDROID_EVENT_CLIPBOARD +{ + int type; + void* data; + int data_length; +}; +typedef struct _ANDROID_EVENT_CLIPBOARD ANDROID_EVENT_CLIPBOARD; + struct _ANDROID_EVENT_QUEUE { int size; @@ -64,10 +73,12 @@ ANDROID_EVENT_KEY* android_event_key_new(int flags, UINT16 scancode); ANDROID_EVENT_KEY* android_event_unicodekey_new(UINT16 key); ANDROID_EVENT_CURSOR* android_event_cursor_new(UINT16 flags, UINT16 x, UINT16 y); ANDROID_EVENT* android_event_disconnect_new(void); +ANDROID_EVENT_CLIPBOARD* android_event_clipboard_new(void* data, int data_length); void android_event_key_free(ANDROID_EVENT_KEY* event); void android_event_unicodekey_free(ANDROID_EVENT_KEY* event); void android_event_cursor_free(ANDROID_EVENT_CURSOR* event); void android_event_disconnect_free(ANDROID_EVENT* event); +void android_event_clipboard_free(ANDROID_EVENT_CLIPBOARD* event); void android_event_queue_init(freerdp * inst); void android_event_queue_uninit(freerdp * inst); diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index e93c6b217..51a6a4695 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -16,21 +16,23 @@ #include #include #include -#include #include #include #include +#include +#include #include #include #include #include #include -#include #include "android_freerdp.h" #include "android_jni_callback.h" +#include "android_jni_utils.h" #include "android_debug.h" +#include "android_cliprdr.h" struct thread_data { @@ -119,7 +121,8 @@ BOOL android_pre_connect(freerdp* instance) settings->FrameAcknowledge = 10; - freerdp_channels_load_plugin(instance->context->channels, instance->settings, "tsxlc", NULL); + freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); + freerdp_client_load_addins(instance->context->channels, instance->settings); freerdp_channels_pre_connect(instance->context->channels, instance); @@ -140,10 +143,7 @@ BOOL android_post_connect(freerdp* instance) instance->update->EndPaint = android_end_paint; instance->update->DesktopResize = android_desktop_resize; - //ai->rail = rail_new(instance->settings); - //instance->update->rail = (void*) ai->rail; - //rail_register_update_callbacks(xfi->rail, instance->update); - //android_rail_register_callbacks(xfi, xfi->rail); + android_cliprdr_init(instance); freerdp_channels_post_connect(instance->context->channels, instance); @@ -153,74 +153,6 @@ BOOL android_post_connect(freerdp* instance) return TRUE; } -jobject create_string_builder(JNIEnv *env, char* initialStr) -{ - jclass cls; - jmethodID methodId; - jobject obj; - - // get class - cls = (*env)->FindClass(env, "java/lang/StringBuilder"); - if(!cls) - return NULL; - - if(initialStr) - { - // get method id for constructor - methodId = (*env)->GetMethodID(env, cls, "", "(Ljava/lang/String;)V"); - if(!methodId) - return NULL; - - // create string that holds our initial string - jstring jstr = (*env)->NewStringUTF(env, initialStr); - - // construct new StringBuilder - obj = (*env)->NewObject(env, cls, methodId, jstr); - } - else - { - // get method id for constructor - methodId = (*env)->GetMethodID(env, cls, "", "()V"); - if(!methodId) - return NULL; - - // construct new StringBuilder - obj = (*env)->NewObject(env, cls, methodId); - } - - return obj; -} - -char* get_string_from_string_builder(JNIEnv* env, jobject strBuilder) -{ - jclass cls; - jmethodID methodId; - jstring strObj; - const jbyte* native_str; - char* result; - - // get class - cls = (*env)->FindClass(env, "java/lang/StringBuilder"); - if(!cls) - return NULL; - - // get method id for constructor - methodId = (*env)->GetMethodID(env, cls, "toString", "()Ljava/lang/String;"); - if(!methodId) - return NULL; - - // get jstring representation of our buffer - strObj = (*env)->CallObjectMethod(env, strBuilder, methodId); - - // read string - native_str = (*env)->GetStringUTFChars(env, strObj, NULL); - result = strdup(native_str); - (*env)->ReleaseStringUTFChars(env, strObj, native_str); - - return result; -} - - BOOL android_authenticate(freerdp* instance, char** username, char** password, char** domain) { DEBUG_ANDROID("Authenticate user:"); @@ -288,19 +220,6 @@ BOOL android_verify_changed_certificate(freerdp* instance, char* subject, char* return android_verify_certificate(instance, subject, issuer, new_fingerprint); } - -/* -int xf_process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data) -{ - rdpChanMan* chanman = (rdpChanMan*) user_data; - - printf("loading plugin %s\n", name); - freerdp_chanman_load_plugin(chanman, settings, name, plugin_data); - - return 1; -} -*/ - int android_receive_channel_data(freerdp* instance, int channelId, UINT8* data, int size, int flags, int total_size) { return freerdp_channels_data(instance, channelId, data, size, flags, total_size); @@ -314,25 +233,16 @@ void android_process_channel_event(rdpChannels* channels, freerdp* instance) if (event) { -/* switch (event->event_class) + switch(GetMessageClass(event->id)) { - case RailChannel_Class: - xf_process_rail_event(ai, chanman, event); + case CliprdrChannel_Class: + android_process_cliprdr_event(instance, event); break; default: break; } - switch (event->event_type) - { - case RDP_EVENT_TYPE_CB_SYNC: - android_process_cb_sync_event(chanman, instance); - break; - default: - break; - } -*/ freerdp_event_free(event); } } @@ -434,6 +344,7 @@ int android_freerdp_run(freerdp* instance) freerdp_disconnect(instance); gdi_free(instance); cache_free(instance->context->cache); + android_cliprdr_uninit(instance); freerdp_callback("OnDisconnected", "(I)V", instance); return 0; @@ -453,20 +364,6 @@ void* android_thread_func(void* param) return NULL; } -jint JNI_OnLoad(JavaVM* vm, void* reserved) -{ - - DEBUG_ANDROID("JNI_OnLoad"); - - jint res = init_callback_environment(vm); - - setlocale(LC_ALL, ""); - - freerdp_channels_global_init(); - - return res; -} - JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls) { freerdp* instance; @@ -654,7 +551,7 @@ JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( { freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; - + DEBUG_ANDROID("remotefx: %d", (remotefx == JNI_TRUE) ? 1 : 0); if (remotefx == JNI_TRUE) { @@ -729,6 +626,63 @@ JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls (*env)->ReleaseStringUTFChars(env, jWorkDir, work_dir); } +JNIEXPORT void JNICALL jni_freerdp_set_drive_redirection(JNIEnv *env, jclass cls, jint instance, jstring jpath) +{ + freerdp* inst = (freerdp*)instance; + rdpSettings * settings = inst->settings; + char* args[] = {"drive", "Android", ""}; + + const jbyte *path = (*env)->GetStringUTFChars(env, jpath, NULL); + DEBUG_ANDROID("drive redirect: %s", (char*)path); + + args[2] = (char*)path; + freerdp_client_add_device_channel(settings, 3, args); + settings->DeviceRedirection = TRUE; + + (*env)->ReleaseStringUTFChars(env, jpath, path); +} + +JNIEXPORT void JNICALL jni_freerdp_set_clipboard_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable) +{ + freerdp* inst = (freerdp*)instance; + rdpSettings * settings = inst->settings; + + DEBUG_ANDROID("clipboard redirect: %s", enable ? "TRUE" : "FALSE"); + + settings->RedirectClipboard = enable ? TRUE : FALSE; +} + +JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jint instance, jstring jgatewayhostname, jint port, + jstring jgatewayusername, jstring jgatewaypassword, jstring jgatewaydomain) +{ + freerdp* inst = (freerdp*)instance; + rdpSettings * settings = inst->settings; + + const jbyte *gatewayhostname = (*env)->GetStringUTFChars(env, jgatewayhostname, NULL); + const jbyte *gatewayusername = (*env)->GetStringUTFChars(env, jgatewayusername, NULL); + const jbyte *gatewaypassword = (*env)->GetStringUTFChars(env, jgatewaypassword, NULL); + const jbyte *gatewaydomain = (*env)->GetStringUTFChars(env, jgatewaydomain, NULL); + + DEBUG_ANDROID("gatewayhostname: %s", (char*) gatewayhostname); + DEBUG_ANDROID("gatewayport: %d", port); + DEBUG_ANDROID("gatewayusername: %s", (char*) gatewayusername); + DEBUG_ANDROID("gatewaypassword: %s", (char*) gatewaypassword); + DEBUG_ANDROID("gatewaydomain: %s", (char*) gatewaydomain); + + settings->GatewayHostname = strdup(gatewayhostname); + settings->GatewayPort = port; + settings->GatewayUsername = strdup(gatewayusername); + settings->GatewayPassword = strdup(gatewaypassword); + settings->GatewayDomain = strdup(gatewaydomain); + settings->GatewayUsageMethod = TRUE; + settings->GatewayUseSameCredentials = FALSE; + + (*env)->ReleaseStringUTFChars(env, jgatewayhostname, gatewayhostname); + (*env)->ReleaseStringUTFChars(env, jgatewayusername, gatewayusername); + (*env)->ReleaseStringUTFChars(env, jgatewaypassword, gatewaypassword); + (*env)->ReleaseStringUTFChars(env, jgatewaydomain, gatewaydomain); +} + void copy_pixel_buffer(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int width, int height, int wBuf, int hBuf, int bpp) { int i, j; @@ -814,7 +768,7 @@ JNIEXPORT void JNICALL jni_freerdp_send_key_event( android_push_event(inst, event); - DEBUG_ANDROID("send_key_event: %d, %d", scancode, flags); + DEBUG_ANDROID("send_key_event: %d, %d", (int)scancode, flags); } JNIEXPORT void JNICALL jni_freerdp_send_unicodekey_event( @@ -841,6 +795,22 @@ JNIEXPORT void JNICALL jni_freerdp_send_cursor_event( DEBUG_ANDROID("send_cursor_event: (%d, %d), %d", x, y, flags); } +JNIEXPORT void JNICALL jni_freerdp_send_clipboard_data(JNIEnv *env, jclass cls, jint instance, jstring jdata) +{ + ANDROID_EVENT* event; + freerdp* inst = (freerdp*)instance; + const jbyte *data = jdata != NULL ? (*env)->GetStringUTFChars(env, jdata, NULL) : NULL; + int data_length = data ? strlen(data) : 0; + + event = (ANDROID_EVENT*) android_event_clipboard_new((void*)data, data_length); + android_push_event(inst, event); + + DEBUG_ANDROID("send_clipboard_data: (%s)", data); + + if (data) + (*env)->ReleaseStringUTFChars(env, jdata, data); +} + JNIEXPORT jstring JNICALL jni_freerdp_get_version(JNIEnv *env, jclass cls) { return (*env)->NewStringUTF(env, GIT_REVISION); diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.h b/client/Android/FreeRDPCore/jni/android_freerdp.h index e932220d0..ad96bc398 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.h +++ b/client/Android/FreeRDPCore/jni/android_freerdp.h @@ -23,6 +23,8 @@ struct android_context ANDROID_EVENT_QUEUE* event_queue; pthread_t thread; BOOL is_connected; + + void* clipboard_context; }; typedef struct android_context androidContext; @@ -42,11 +44,15 @@ JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, JNIEXPORT void JNICALL jni_freerdp_set_performance_flags(JNIEnv *env, jclass cls, jint instance, jboolean remotefx, jboolean disableWallpaper, jboolean disableFullWindowDrag, jboolean disableMenuAnimations, jboolean disableTheming, jboolean enableFontSmoothing, jboolean enableDesktopComposition); JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls, jint instance, jstring jRemoteProgram, jstring jWorkDir); +JNIEXPORT void JNICALL jni_freerdp_set_drive_redirection(JNIEnv *env, jclass cls, jint instance, jstring jpath); +JNIEXPORT void JNICALL jni_freerdp_set_clipboard_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable); +JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jint instance, jstring jgatewayhostname, jint port, jstring jgatewayusername, jstring jgatewaypassword, jstring jgatewaydomain); JNIEXPORT void JNICALL jni_freerdp_set_data_directory(JNIEnv *env, jclass cls, jint instance, jstring jdirectory); JNIEXPORT jboolean JNICALL jni_freerdp_update_graphics(JNIEnv *env, jclass cls, jint instance, jobject bitmap, jint x, jint y, jint width, jint height); JNIEXPORT void JNICALL jni_freerdp_send_cursor_event(JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags); JNIEXPORT void JNICALL jni_freerdp_send_key_event(JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down); JNIEXPORT void JNICALL jni_freerdp_send_unicodekey_event(JNIEnv *env, jclass cls, jint instance, jint keycode); +JNIEXPORT void JNICALL jni_freerdp_send_clipboard_data(JNIEnv *env, jclass cls, jint instance, jstring jdata); JNIEXPORT jstring JNICALL jni_freerdp_get_version(JNIEnv *env, jclass cls); #endif /* __ANDROID_FREERDP_H */ diff --git a/client/Android/FreeRDPCore/jni/android_jni_utils.c b/client/Android/FreeRDPCore/jni/android_jni_utils.c new file mode 100644 index 000000000..0424c501a --- /dev/null +++ b/client/Android/FreeRDPCore/jni/android_jni_utils.c @@ -0,0 +1,211 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Android Event System + * + * Copyright 2013 Felix Long + * Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "android_jni_utils.h" + +#include +#include + +#include "android_debug.h" +#include "android_jni_callback.h" + + +JavaVM *g_JavaVm; + + +JavaVM* getJavaVM() +{ + return g_JavaVm; +} + +JNIEnv* getJNIEnv() +{ + JNIEnv* env = NULL; + if ((*g_JavaVm)->GetEnv(g_JavaVm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) + { + DEBUG_ANDROID("Failed to obtain JNIEnv"); + return NULL; + } + return env; +} + +jobject create_string_builder(JNIEnv *env, char* initialStr) +{ + jclass cls; + jmethodID methodId; + jobject obj; + + // get class + cls = (*env)->FindClass(env, "java/lang/StringBuilder"); + if(!cls) + return NULL; + + if(initialStr) + { + // get method id for constructor + methodId = (*env)->GetMethodID(env, cls, "", "(Ljava/lang/String;)V"); + if(!methodId) + return NULL; + + // create string that holds our initial string + jstring jstr = (*env)->NewStringUTF(env, initialStr); + + // construct new StringBuilder + obj = (*env)->NewObject(env, cls, methodId, jstr); + } + else + { + // get method id for constructor + methodId = (*env)->GetMethodID(env, cls, "", "()V"); + if(!methodId) + return NULL; + + // construct new StringBuilder + obj = (*env)->NewObject(env, cls, methodId); + } + + return obj; +} + +char* get_string_from_string_builder(JNIEnv* env, jobject strBuilder) +{ + jclass cls; + jmethodID methodId; + jstring strObj; + const jbyte* native_str; + char* result; + + // get class + cls = (*env)->FindClass(env, "java/lang/StringBuilder"); + if(!cls) + return NULL; + + // get method id for constructor + methodId = (*env)->GetMethodID(env, cls, "toString", "()Ljava/lang/String;"); + if(!methodId) + return NULL; + + // get jstring representation of our buffer + strObj = (*env)->CallObjectMethod(env, strBuilder, methodId); + + // read string + native_str = (*env)->GetStringUTFChars(env, strObj, NULL); + result = strdup(native_str); + (*env)->ReleaseStringUTFChars(env, strObj, native_str); + + return result; +} + +jstring jniNewStringUTF(JNIEnv* env, const char* in, int len) +{ + jstring out = NULL; + jchar* unicode = NULL; + jint result_size = 0; + jint i; + unsigned char* utf8 = (unsigned char*)in; + + if (!in) + { + return NULL; + } + if (len < 0) + len = strlen(in); + + unicode = (jchar*)malloc(sizeof(jchar) * (len + 1)); + if (!unicode) + { + return NULL; + } + + for(i = 0; i < len; i++) + { + unsigned char one = utf8[i]; + switch(one >> 4) + { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + unicode[result_size++] = one; + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + //case 0x0f: + /* + * Bit pattern 10xx or 1111, which are illegal start bytes. + * Note: 1111 is valid for normal UTF-8, but not the + * modified UTF-8 used here. + */ + break; + case 0x0f: + case 0x0e: + // Bit pattern 111x, so there are two additional bytes. + if (i < (len - 2)) + { + unsigned char two = utf8[i+1]; + unsigned char three = utf8[i+2]; + if ((two & 0xc0) == 0x80 && (three & 0xc0) == 0x80) + { + i += 2; + unicode[result_size++] = + ((one & 0x0f) << 12) + | ((two & 0x3f) << 6) + | (three & 0x3f); + } + } + break; + case 0x0c: + case 0x0d: + // Bit pattern 110x, so there is one additional byte. + if (i < (len - 1)) + { + unsigned char two = utf8[i+1]; + if ((two & 0xc0) == 0x80) + { + i += 1; + unicode[result_size++] = + ((one & 0x1f) << 6) + | (two & 0x3f); + } + } + break; + } + } + + out = (*env)->NewString(env, unicode, result_size); + free(unicode); + + return out; +} + +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + jint result = JNI_ERR; + + DEBUG_ANDROID("JNI_OnLoad"); + + g_JavaVm = vm; + result = init_callback_environment(vm); + + setlocale(LC_ALL, ""); + + freerdp_channels_global_init(); + + return result; +} + diff --git a/client/Android/FreeRDPCore/jni/android_jni_utils.h b/client/Android/FreeRDPCore/jni/android_jni_utils.h new file mode 100644 index 000000000..f5ac12e36 --- /dev/null +++ b/client/Android/FreeRDPCore/jni/android_jni_utils.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Android Event System + * + * Copyright 2013 Felix Long + * Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#ifndef _ANDROID_JNI_UTILS_H_ +#define _ANDROID_JNI_UTILS_H_ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +JNIEnv* getJNIEnv(); + +JavaVM* getJavaVM(); + +char* get_string_from_string_builder(JNIEnv* env, jobject strBuilder); +jobject create_string_builder(JNIEnv *env, char* initialStr); +jstring jniNewStringUTF(JNIEnv* env, const char* in, int len); + +#ifdef __cplusplus +} +#endif + +#endif /* _ANDROID_JNI_UTILS_H_ */ diff --git a/client/Android/FreeRDPCore/jni/generated/android_freerdp_jni.c b/client/Android/FreeRDPCore/jni/generated/android_freerdp_jni.c index 308c146cb..1aa889abe 100644 --- a/client/Android/FreeRDPCore/jni/generated/android_freerdp_jni.c +++ b/client/Android/FreeRDPCore/jni/generated/android_freerdp_jni.c @@ -70,6 +70,24 @@ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_ jni_freerdp_set_performance_flags(env, cls, instance, remotefx, disableWallpaper, disableFullWindowDrag, disableMenuAnimations, disableTheming, enableFontSmoothing, enableDesktopComposition); } +JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1clipboard_1redirection + (JNIEnv *env, jclass cls, jint inst, jboolean enable) +{ + jni_freerdp_set_clipboard_redirection(env, cls, inst, enable); +} + +JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1drive_1redirection + (JNIEnv *env, jclass cls, jint inst, jstring path) +{ + jni_freerdp_set_drive_redirection(env, cls, inst, path); +} + +JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1gateway_1info + (JNIEnv *env, jclass cls, jint inst, jstring hostname, jint port, jstring username, jstring password, jstring domain) +{ + jni_freerdp_set_gateway_info(env, cls, inst, hostname, port, username, password, domain); +} + JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1update_1graphics( JNIEnv *env, jclass cls, jint instance, jobject bitmap, jint x, jint y, jint width, jint height) { @@ -94,6 +112,12 @@ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_ jni_freerdp_send_unicodekey_event(env, cls, instance, keycode); } +JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1clipboard_1data + (JNIEnv *env, jclass cls, jint instance, jstring data) +{ + jni_freerdp_send_clipboard_data(env, cls, instance, data); +} + JNIEXPORT jstring JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1get_1version(JNIEnv *env, jclass cls) { return jni_freerdp_get_version(env, cls); diff --git a/client/Android/FreeRDPCore/jni/generated/com_freerdp_freerdpcore_services_LibFreeRDP.h b/client/Android/FreeRDPCore/jni/generated/com_freerdp_freerdpcore_services_LibFreeRDP.h index 17c62cd99..1e6be8dff 100644 --- a/client/Android/FreeRDPCore/jni/generated/com_freerdp_freerdpcore_services_LibFreeRDP.h +++ b/client/Android/FreeRDPCore/jni/generated/com_freerdp_freerdpcore_services_LibFreeRDP.h @@ -79,6 +79,30 @@ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1data_1directory (JNIEnv *, jclass, jint, jstring); +/* + * Class: com_freerdp_freerdpcore_services_LibFreeRDP + * Method: freerdp_set_clipboard_redirection + * Signature: (IZ)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1clipboard_1redirection + (JNIEnv *, jclass, jint, jboolean); + +/* + * Class: com_freerdp_freerdpcore_services_LibFreeRDP + * Method: freerdp_set_drive_redirection + * Signature: (ILjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1drive_1redirection + (JNIEnv *, jclass, jint, jstring); + +/* + * Class: com_freerdp_freerdpcore_services_LibFreeRDP + * Method: freerdp_set_gateway_info + * Signature: (ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1gateway_1info + (JNIEnv *, jclass, jint, jstring, jint, jstring, jstring, jstring); + /* * Class: com_freerdp_freerdpcore_services_LibFreeRDP * Method: freerdp_update_graphics @@ -111,6 +135,14 @@ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1unicodekey_1event (JNIEnv *, jclass, jint, jint); +/* + * Class: com_freerdp_freerdpcore_services_LibFreeRDP + * Method: freerdp_send_clipboard_data + * Signature: (ILjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1clipboard_1data + (JNIEnv *, jclass, jint, jstring); + /* * Class: com_freerdp_freerdpcore_services_LibFreeRDP * Method: freerdp_get_version diff --git a/client/Android/FreeRDPCore/project.properties b/client/Android/FreeRDPCore/project.properties index db721fd89..b4af3b428 100644 --- a/client/Android/FreeRDPCore/project.properties +++ b/client/Android/FreeRDPCore/project.properties @@ -11,5 +11,5 @@ #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-8 +target=android-11 android.library=true diff --git a/client/Android/FreeRDPCore/res/values-es/strings.xml b/client/Android/FreeRDPCore/res/values-es/strings.xml index 2f9d36d8e..cf9b933a9 100644 --- a/client/Android/FreeRDPCore/res/values-es/strings.xml +++ b/client/Android/FreeRDPCore/res/values-es/strings.xml @@ -28,7 +28,7 @@ Conexión Manual Sesiones Activas - Connectarse a iWinCloud + Connect to Computer Login No hay escritorios virtuales @@ -37,13 +37,13 @@ Conexión perdida Contraseña equivocada Usuario Invalido - Agregar escritorio virtual de iWinCloud + Add Connection Host Su nombre IP Puerto - Credenciales de iWinCloud + Credenciales Credenciales Usuario Contraseña @@ -105,6 +105,10 @@ Configuracion 3G Pantalla 3G Rendimiento 3G + Gateway + Enable Gateway + Gateway Settings + Redirect SDCard Seguridad Automatico @@ -141,28 +145,28 @@ Configuración de la conexión Configuración - iWinCloud - iWinCloud para Android + aFreeRDP - aFreeRDP para Android Conexiones RDP Ayuda Sobre Cancelar sin guardar? Pulse el botón "Cancelar" para abortar! \ NPulse "Continuar" para especificar los campos obligatorios! - No se pudo establecer una conexión con iWinCloud! + Failed to establish a connection to the server! Los ajustes de pantalla se han cambiado porque el escritorio virtual no es compatible con la configuración especificada! Eliminado el cache del certificado! No se pudo borrar el caché del certificado! verificar el certificado - La identidad de su escritorio de iWinCloud debe ser verificada. ¿Desea conectarse de todos modos? + The identity of the remote computer cannot be verified. Do you want to connect anyway? Por favor, introduzca sus credenciales Crear acceso directo Nombre corto: Conectando ... Ingresando a ... - Sobre iWinCloud - Version: %1$s\n\u00A9 2012 iWinCloud LLc + Sobre aFreeRDP + Version: %1$s\n\u00A9 2012 Thinstuff Technologies GmbH Guardar configuración de conexión? La configuración de conexión no se han guardado! ¿Quieres guardarlos? Guardar Conexión diff --git a/client/Android/FreeRDPCore/res/values-fr/strings.xml b/client/Android/FreeRDPCore/res/values-fr/strings.xml index 95f3d6490..3e0f1711f 100644 --- a/client/Android/FreeRDPCore/res/values-fr/strings.xml +++ b/client/Android/FreeRDPCore/res/values-fr/strings.xml @@ -104,6 +104,10 @@ "Paramètres 3G" "Écran 3G" "Performance 3G" + Gateway + Enable Gateway + Gateway Settings + "Redirect SDCard" "Securité" "Automatique" diff --git a/client/Android/FreeRDPCore/res/values-nl/strings.xml b/client/Android/FreeRDPCore/res/values-nl/strings.xml new file mode 100644 index 000000000..5dfbf0c24 --- /dev/null +++ b/client/Android/FreeRDPCore/res/values-nl/strings.xml @@ -0,0 +1,175 @@ + + + + Ja + Nee + Annuleren + Doorgaan + Inloggen + Uitloggen + + Sluiten + Over + Help + Nieuwe connectie + Instellingen + + Connectie + Verbinden + Bewerken + Verwijderen + + Toetsenbord + Functietoetsen + Touch Pointer + home + Verbinding verbreken + + Handmatige connecties + Actieve sessies + + Verbinden met computer + + Login + Geen servers + Verbinden ... + Verbinding verbreken ... + Connectie verloren + Ongeldig wachtwoord + Ongeldige gebruikersnaam + Connectie toevoegen + + Host + Label + Host + Poort + Inloggegevens + Inloggegevens + Gebruikersnaam + Wachtwoord + Domein + Instellingen + Scherm + Scherminstellingen + Kleuren + + Hoge kleuren (16 Bit) + Ware kleuren (24 Bit) + Hoogste kwaliteit (32 Bit) + + + 16 + 24 + 32 + + Resolutie + Automatisch + Aangepast + + Automatisch + Aangepast + 640x480 + 720x480 + 800x600 + 1024x768 + 1280x1024 + 1440x900 + 1920x1080 + 1920x1200 + + + Automatisch + Aangepast + 640x480 + 720x480 + 800x600 + 1024x768 + 1280x1024 + 1440x900 + 1920x1080 + 1920x1200 + + Breedte + Hoogte + Prestatie + Prestatieinstellingen + RemoteFX + Bureaublad achtergrond + Lettertype Smoothing + Bureaublad compositie + Inhoud van het venster weergeven tijdens slepen + Menu animatie + Visuele stijlen + Geavanceerd + Geavanceerde instellingen + 3G Instellingen + 3G Scherm + 3G Prestatie + Beveiliging + + Automatisch + RDP + TLS + NLA + + + 0 + 1 + 2 + 3 + + Extern programma + Werkmap + Console modus + + ******* + Niet ingesteld + Gebruikersinterface + Verberg statusbalk + Verberg Zoom Controls + Wissel muisknoppen + Scrollen omkeren + Touch Pointer Auto Scroll + Toon dialoog bij sluiten + Energiebesparing + Sluit inactieve ingen + Beveiliging + Accepteer alle certificaten + Certificaat cache opschonen + na %1$d minuten + Uitgeschakeld + + Connectie instellingen + Instellingen + aFreeRDP - FreeRDP voor Android + RDP verbinding + Help + Over + + Annuleren zonder opslaan? + Druk op "Annuleren" om af te breken!\nKlik op "Doorgaan" om de verplichte velden op te geven! + Fout bij het verbinden met de server! + + De scherm instellingen zijn veranderd omdat de server de door u opgegeven instellingen niet ondersteunt! + Certificaat cache is verwijderd! + Fout bij het verwijderderen van certificaat cache! + + Controleer certificaat + De identiteit van de externe computer niet kan worden geverifieerd. Wilt u toch verbinden? + Vul uw gegevens in + Snelkoppeling maken + Snelkoppeling naam: + Verbinden ... + Aanmelden ... + Over aFreeRDP + Versie: %1$s\n\u00A9 2012 Thinstuff Technologies GmbH + Connectie instellingen opslaan? + Uw connectie instellingen zijn niet opgeslagen! Wilt u deze opslaan? + Verbinding opslaan? + Wilt u alle wijzigingen opslaan? + Niet opnieuw vragen + Toepassing sluiten? + Weet u zeker dat u de applicatie wilt sluiten? + Verwijder certificaten? + Weet u zeker dat u al uw cache certificaten wilt verwijderen? + diff --git a/client/Android/FreeRDPCore/res/values/strings.xml b/client/Android/FreeRDPCore/res/values/strings.xml index 810127219..6110afd5d 100644 --- a/client/Android/FreeRDPCore/res/values/strings.xml +++ b/client/Android/FreeRDPCore/res/values/strings.xml @@ -105,6 +105,10 @@ 3G Settings 3G Screen 3G Performance + Gateway + Enable Gateway + Gateway Settings + Redirect SDCard Security Automatic diff --git a/client/Android/FreeRDPCore/res/xml/advanced_settings.xml b/client/Android/FreeRDPCore/res/xml/advanced_settings.xml index 9158acf16..61cd61d19 100644 --- a/client/Android/FreeRDPCore/res/xml/advanced_settings.xml +++ b/client/Android/FreeRDPCore/res/xml/advanced_settings.xml @@ -12,8 +12,15 @@ - - + + + + + + + diff --git a/client/Android/FreeRDPCore/res/xml/gateway_settings.xml b/client/Android/FreeRDPCore/res/xml/gateway_settings.xml new file mode 100644 index 000000000..207871251 --- /dev/null +++ b/client/Android/FreeRDPCore/res/xml/gateway_settings.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java index c37f8df5a..aca737a4b 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java @@ -194,8 +194,7 @@ public class GlobalApp extends Application implements LibFreeRDP.EventListener { Log.v("LibFreeRDP", "OnConnectionFailure"); - // free session - GlobalApp.freeSession(instance); + // send notification to session activity sendRDPNotification(FREERDP_EVENT_CONNECTION_FAILURE, instance); } @@ -210,8 +209,5 @@ public class GlobalApp extends Application implements LibFreeRDP.EventListener public void OnDisconnected(int instance) { Log.v("LibFreeRDP", "OnDisconnected"); - - // free session - GlobalApp.freeSession(instance); } } diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java index 12828ffd4..981386b6d 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java @@ -284,6 +284,7 @@ public class BookmarkBase implements Parcelable, Cloneable private boolean enable3GSettings; private ScreenSettings screen3G; private PerformanceFlags performance3G; + private boolean redirectSDCard; private int security; private boolean consoleMode; private String remoteProgram; @@ -297,6 +298,7 @@ public class BookmarkBase implements Parcelable, Cloneable enable3GSettings = (parcel.readInt() == 1) ? true : false; screen3G = parcel.readParcelable(ScreenSettings.class.getClassLoader()); performance3G = parcel.readParcelable(PerformanceFlags.class.getClassLoader()); + redirectSDCard = (parcel.readInt() == 1) ? true : false; security = parcel.readInt(); consoleMode = (parcel.readInt() == 1) ? true : false; remoteProgram = parcel.readString(); @@ -307,6 +309,7 @@ public class BookmarkBase implements Parcelable, Cloneable enable3GSettings = false; screen3G = new ScreenSettings(); performance3G = new PerformanceFlags(); + redirectSDCard = false; security = 0; consoleMode = false; remoteProgram = ""; @@ -337,6 +340,14 @@ public class BookmarkBase implements Parcelable, Cloneable this.performance3G = performance3G; } + public void setRedirectSDCard(boolean redirectSDCard) { + this.redirectSDCard = redirectSDCard; + } + + public boolean getRedirectSDCard() { + return redirectSDCard; + } + public void setSecurity(int security) { this.security = security; } @@ -396,6 +407,7 @@ public class BookmarkBase implements Parcelable, Cloneable out.writeInt(enable3GSettings ? 1 : 0); out.writeParcelable(screen3G, flags); out.writeParcelable(performance3G, flags); + out.writeInt(redirectSDCard ? 1 : 0); out.writeInt(security); out.writeInt(consoleMode ? 1 : 0); out.writeString(remoteProgram); @@ -597,6 +609,7 @@ public class BookmarkBase implements Parcelable, Cloneable editor.putBoolean("bookmark.perf_menu_animation_3g", advancedSettings.getPerformance3G().getMenuAnimations()); editor.putBoolean("bookmark.perf_themes_3g", advancedSettings.getPerformance3G().getTheming()); + editor.putBoolean("bookmark.redirect_sdcard", advancedSettings.getRedirectSDCard()); editor.putInt("bookmark.security", advancedSettings.getSecurity()); editor.putString("bookmark.remote_program", advancedSettings.getRemoteProgram()); editor.putString("bookmark.work_dir", advancedSettings.getWorkDir()); @@ -638,6 +651,7 @@ public class BookmarkBase implements Parcelable, Cloneable advancedSettings.getPerformance3G().setMenuAnimations(sharedPrefs.getBoolean("bookmark.perf_menu_animation_3g", false)); advancedSettings.getPerformance3G().setTheming(sharedPrefs.getBoolean("bookmark.perf_themes_3g", false)); + advancedSettings.setRedirectSDCard(sharedPrefs.getBoolean("bookmark.redirect_sdcard", false)); advancedSettings.setSecurity(sharedPrefs.getInt("bookmark.security", 0)); advancedSettings.setRemoteProgram(sharedPrefs.getString("bookmark.remote_program", "")); advancedSettings.setWorkDir(sharedPrefs.getString("bookmark.work_dir", "")); diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/ManualBookmark.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/ManualBookmark.java index 81d9b717c..b8e3da862 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/ManualBookmark.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/ManualBookmark.java @@ -15,14 +15,111 @@ import android.os.Parcelable; public class ManualBookmark extends BookmarkBase { + // Gateway Settings class + public static class GatewaySettings implements Parcelable + { + private String hostname; + private int port; + private String username; + private String password; + private String domain; + + public GatewaySettings() { + hostname = ""; + port = 443; + username = ""; + password = ""; + domain = ""; + } + + public GatewaySettings(Parcel parcel) { + hostname = parcel.readString(); + port = parcel.readInt(); + username = parcel.readString(); + password = parcel.readString(); + domain = parcel.readString(); + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + public String getHostname() { + return hostname; + } + + public void setPort(int port) { + this.port = port; + } + + public int getPort() { + return port; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getDomain() { + return domain; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) + { + out.writeString(hostname); + out.writeInt(port); + out.writeString(username); + out.writeString(password); + out.writeString(domain); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() + { + public GatewaySettings createFromParcel(Parcel in) { + return new GatewaySettings(in); + } + + @Override + public GatewaySettings[] newArray(int size) { + return new GatewaySettings[size]; + } + }; + } + private String hostname; private int port; + private boolean enableGatewaySettings; + private GatewaySettings gatewaySettings; private void init() { type = TYPE_MANUAL; hostname = ""; - port = 3389; + port = 3389; + enableGatewaySettings = false; + gatewaySettings = new GatewaySettings(); } public ManualBookmark(Parcel parcel) @@ -31,6 +128,9 @@ public class ManualBookmark extends BookmarkBase type = TYPE_MANUAL; hostname = parcel.readString(); port = parcel.readInt(); + + enableGatewaySettings = (parcel.readInt() == 1 ? true : false); + gatewaySettings = parcel.readParcelable(GatewaySettings.class.getClassLoader()); } public ManualBookmark() { @@ -53,7 +153,27 @@ public class ManualBookmark extends BookmarkBase public int getPort() { return port; } + + public boolean getEnableGatewaySettings() + { + return enableGatewaySettings; + } + + public void setEnableGatewaySettings(boolean enableGatewaySettings) + { + this.enableGatewaySettings = enableGatewaySettings; + } + + public GatewaySettings getGatewaySettings() + { + return gatewaySettings; + } + public void setGatewaySettings(GatewaySettings gatewaySettings) + { + this.gatewaySettings = gatewaySettings; + } + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public ManualBookmark createFromParcel(Parcel in) { @@ -77,6 +197,8 @@ public class ManualBookmark extends BookmarkBase super.writeToParcel(out, flags); out.writeString(hostname); out.writeInt(port); + out.writeInt(enableGatewaySettings ? 1 : 0); + out.writeParcelable(gatewaySettings, flags); } @Override @@ -87,6 +209,12 @@ public class ManualBookmark extends BookmarkBase SharedPreferences.Editor editor = sharedPrefs.edit(); editor.putString("bookmark.hostname", hostname); editor.putInt("bookmark.port", port); + editor.putBoolean("bookmark.enable_gateway_settings", enableGatewaySettings); + editor.putString("bookmark.gateway_hostname", gatewaySettings.getHostname()); + editor.putInt("bookmark.gateway_port", gatewaySettings.getPort()); + editor.putString("bookmark.gateway_username", gatewaySettings.getUsername()); + editor.putString("bookmark.gateway_password", gatewaySettings.getPassword()); + editor.putString("bookmark.gateway_domain", gatewaySettings.getDomain()); editor.commit(); } @@ -97,6 +225,12 @@ public class ManualBookmark extends BookmarkBase hostname = sharedPrefs.getString("bookmark.hostname", ""); port = sharedPrefs.getInt("bookmark.port", 3389); + enableGatewaySettings = sharedPrefs.getBoolean("bookmark.enable_gateway_settings", false); + gatewaySettings.setHostname(sharedPrefs.getString("bookmark.gateway_hostname", "")); + gatewaySettings.setPort(sharedPrefs.getInt("bookmark.gateway_port", 443)); + gatewaySettings.setUsername(sharedPrefs.getString("bookmark.gateway_username", "")); + gatewaySettings.setPassword(sharedPrefs.getString("bookmark.gateway_password", "")); + gatewaySettings.setDomain(sharedPrefs.getString("bookmark.gateway_domain", "")); } // Cloneable diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java index 4d938f419..004a716e7 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java @@ -45,6 +45,7 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref private static final int PREFERENCES_ADVANCED = 5; private static final int PREFERENCES_SCREEN3G = 6; private static final int PREFERENCES_PERFORMANCE3G = 7; + private static final int PREFERENCES_GATEWAY = 8; // bookmark needs to be static because the activity is started for each subview // (we have to do this because Android has a bug where the style for Preferences @@ -112,6 +113,13 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref if(bookmark == null) bookmark = new ManualBookmark(); + // hide gateway settings if we edit a non-manual bookmark + if (current_preferences == PREFERENCES_ADVANCED && bookmark.getType() != ManualBookmark.TYPE_MANUAL) + { + getPreferenceScreen().removePreference(findPreference("bookmark.enable_gateway")); + getPreferenceScreen().removePreference(findPreference("bookmark.gateway")); + } + // update preferences from bookmark bookmark.writeToSharedPreferences(getPreferenceManager().getSharedPreferences()); @@ -155,6 +163,11 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref addPreferencesFromResource(R.xml.credentials_settings); current_preferences = PREFERENCES_CREDENTIALS; } + else if (getIntent().getData().toString().equals("preferences://gateway_settings")) + { + addPreferencesFromResource(R.xml.gateway_settings); + current_preferences = PREFERENCES_GATEWAY; + } else { addPreferencesFromResource(R.xml.bookmark_settings); @@ -230,7 +243,8 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref "bookmark.performance", "bookmark.advanced", "bookmark.screen_3g", - "bookmark.performance_3g" + "bookmark.performance_3g", + "bookmark.gateway_settings" }; for (int i = 0; i < prefKeys.length; ++i) @@ -264,6 +278,10 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref case PREFERENCES_SCREEN3G: screenSettingsChanged(sharedPreferences, key); break; + + case PREFERENCES_GATEWAY: + gatewaySettingsChanged(sharedPreferences, key); + break; } } @@ -291,6 +309,10 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref case PREFERENCES_SCREEN3G: initScreenSettings3G(sharedPreferences); break; + + case PREFERENCES_GATEWAY: + initGatewaySettings(sharedPreferences); + break; } } @@ -332,6 +354,7 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref private void initAdvancedSettings(SharedPreferences sharedPreferences) { + advancedSettingsChanged(sharedPreferences, "bookmark.enable_gateway_settings"); advancedSettingsChanged(sharedPreferences, "bookmark.enable_3g_settings"); advancedSettingsChanged(sharedPreferences, "bookmark.security"); advancedSettingsChanged(sharedPreferences, "bookmark.resolution_3g"); @@ -341,7 +364,12 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref private void advancedSettingsChanged(SharedPreferences sharedPreferences, String key) { - if (key.equals("bookmark.enable_3g_settings")) + if (key.equals("bookmark.enable_gateway_settings")) + { + boolean enabled = sharedPreferences.getBoolean(key, false); + findPreference("bookmark.gateway_settings").setEnabled(enabled); + } + else if (key.equals("bookmark.enable_3g_settings")) { boolean enabled = sharedPreferences.getBoolean(key, false); findPreference("bookmark.screen_3g").setEnabled(enabled); @@ -441,6 +469,40 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref findPreference(key).setSummary(String.valueOf(sharedPreferences.getInt(key, 600))); } + private void initGatewaySettings(SharedPreferences sharedPreferences) + { + gatewaySettingsChanged(sharedPreferences, "bookmark.gateway_hostname"); + gatewaySettingsChanged(sharedPreferences, "bookmark.gateway_port"); + gatewaySettingsChanged(sharedPreferences, "bookmark.gateway_username"); + gatewaySettingsChanged(sharedPreferences, "bookmark.gateway_password"); + gatewaySettingsChanged(sharedPreferences, "bookmark.gateway_domain"); + } + + private void gatewaySettingsChanged(SharedPreferences sharedPreferences, String key) + { + if (key.equals("bookmark.gateway_hostname")) + { + findPreference(key).setSummary(sharedPreferences.getString(key, "")); + } + else if (key.equals("bookmark.gateway_port")) + { + findPreference(key).setSummary(String.valueOf(sharedPreferences.getInt(key, 443))); + } + else if (key.equals("bookmark.gateway_username")) + { + findPreference(key).setSummary(sharedPreferences.getString(key, "")); + } + else if (key.equals("bookmark.gateway_password")) + { + if (sharedPreferences.getString(key, "").length() == 0) + findPreference(key).setSummary(getResources().getString(R.string.settings_password_empty)); + else + findPreference(key).setSummary(getResources().getString(R.string.settings_password_present)); + } + else if (key.equals("bookmark.gateway_domain")) + findPreference(key).setSummary(sharedPreferences.getString(key, "")); + } + private boolean verifySettings(SharedPreferences sharedPreferences) { boolean verifyFailed = false; @@ -464,6 +526,7 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref private void finishAndResetBookmark() { bookmark = null; + getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); finish(); } @@ -474,6 +537,7 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref if (current_preferences != PREFERENCES_BOOKMARK) { super.onBackPressed(); + getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); return; } diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java index 657678bc7..055b48b73 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java @@ -22,6 +22,7 @@ import com.freerdp.freerdpcore.domain.ManualBookmark; import com.freerdp.freerdpcore.services.LibFreeRDP; import com.freerdp.freerdpcore.utils.KeyboardMapper; import com.freerdp.freerdpcore.utils.Mouse; +import com.freerdp.freerdpcore.utils.ClipboardManagerProxy; import android.app.Activity; import android.app.Dialog; @@ -59,7 +60,8 @@ import android.inputmethodservice.KeyboardView; public class SessionActivity extends Activity implements LibFreeRDP.UIEventListener, KeyboardView.OnKeyboardActionListener, ScrollView2D.ScrollView2DListener, - KeyboardMapper.KeyProcessingListener, SessionView.SessionViewListener, TouchPointerView.TouchPointerListener + KeyboardMapper.KeyProcessingListener, SessionView.SessionViewListener, TouchPointerView.TouchPointerListener, + ClipboardManagerProxy.OnClipboardChangedListener { private class UIHandler extends Handler { @@ -256,7 +258,6 @@ public class SessionActivity extends Activity if (!connectCancelledByUser) uiHandler.sendMessage(Message.obtain(null, UIHandler.DISPLAY_TOAST, getResources().getText(R.string.error_connection_failure))); - session = null; closeSessionActivity(RESULT_CANCELED); } @@ -271,7 +272,6 @@ public class SessionActivity extends Activity } session.setUIEventListener(null); - session = null; closeSessionActivity(RESULT_OK); } } @@ -330,6 +330,8 @@ public class SessionActivity extends Activity private static final int SEND_MOVE_EVENT_TIMEOUT = 150; private int discardedMoveEvents = 0; + private ClipboardManagerProxy mClipboardManager; + private void createDialogs() { // build verify certificate dialog @@ -479,6 +481,9 @@ public class SessionActivity extends Activity IntentFilter filter = new IntentFilter(); filter.addAction(GlobalApp.ACTION_EVENT_FREERDP); registerReceiver(libFreeRDPBroadcastReceiver, filter); + + mClipboardManager = ClipboardManagerProxy.getClipboardManager(this); + mClipboardManager.addClipboardChangedListener(this); } @Override @@ -518,9 +523,16 @@ public class SessionActivity extends Activity protected void onDestroy() { super.onDestroy(); Log.v(TAG, "Session.onDestroy"); - + // unregister freerdp events broadcast receiver unregisterReceiver(libFreeRDPBroadcastReceiver); + + // remove clipboard listener + mClipboardManager.removeClipboardboardChangedListener(this); + + // free session + GlobalApp.freeSession(session.getInstance()); + session = null; } @Override @@ -1011,7 +1023,13 @@ public class SessionActivity extends Activity return callbackDialogResult; } - + @Override + public void OnRemoteClipboardChanged(String data) + { + Log.v(TAG, "OnRemoteClipboardChanged: " + data); + mClipboardManager.setClipboardData(data); + } + // **************************************************************************** // ScrollView2DListener implementation private void resetZoomControlsAutoHideTimeout() { @@ -1129,5 +1147,13 @@ public class SessionActivity extends Activity public void onTouchPointerResetScrollZoom() { sessionView.setZoom(1.0f); scrollView.scrollTo(0, 0); + } + + // **************************************************************************** + // ClipboardManagerProxy.OnClipboardChangedListener + @Override + public void onClipboardChanged(String data) { + Log.v(TAG, "onClipboardChanged: " + data); + LibFreeRDP.sendClipboardData(session.getInstance(), data); } } diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkBaseGateway.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkBaseGateway.java index 6abac51d2..7f6a939b1 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkBaseGateway.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkBaseGateway.java @@ -63,6 +63,7 @@ public abstract class BookmarkBaseGateway values.put("screen_3g", rowid); rowid = insertPerformanceFlags(db, bookmark.getAdvancedSettings().getPerformance3G()); values.put("performance_3g", rowid); + values.put("redirect_sdcard", bookmark.getAdvancedSettings().getRedirectSDCard()); values.put("security", bookmark.getAdvancedSettings().getSecurity()); values.put("console_mode", bookmark.getAdvancedSettings().getConsoleMode()); values.put("remote_program", bookmark.getAdvancedSettings().getRemoteProgram()); @@ -98,6 +99,7 @@ public abstract class BookmarkBaseGateway // update 3G screen and 3G performance settings settings updateScreenSettings3G(db, bookmark); updatePerformanceFlags3G(db, bookmark); + values.put("redirect_sdcard", bookmark.getAdvancedSettings().getRedirectSDCard()); values.put("security", bookmark.getAdvancedSettings().getSecurity()); values.put("console_mode", bookmark.getAdvancedSettings().getConsoleMode()); values.put("remote_program", bookmark.getAdvancedSettings().getRemoteProgram()); @@ -216,6 +218,7 @@ public abstract class BookmarkBaseGateway // advanced settings columns.add("enable_3g_settings"); + columns.add("redirect_sdcard"); columns.add("security"); columns.add("console_mode"); columns.add("remote_program"); @@ -273,6 +276,7 @@ public abstract class BookmarkBaseGateway bookmark.getAdvancedSettings().setEnable3GSettings(cursor.getInt(cursor.getColumnIndex("enable_3g_settings")) == 0 ? false : true); readScreenSettings3G(bookmark, cursor); readPerformanceFlags3G(bookmark, cursor); + bookmark.getAdvancedSettings().setRedirectSDCard(cursor.getInt(cursor.getColumnIndex("redirect_sdcard")) == 0 ? false : true); bookmark.getAdvancedSettings().setSecurity(cursor.getInt(cursor.getColumnIndex("security"))); bookmark.getAdvancedSettings().setConsoleMode(cursor.getInt(cursor.getColumnIndex("console_mode")) == 0 ? false : true); bookmark.getAdvancedSettings().setRemoteProgram(cursor.getString(cursor.getColumnIndex("remote_program"))); diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkDB.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkDB.java index 5d10d7048..e54cc1502 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkDB.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkDB.java @@ -9,14 +9,20 @@ package com.freerdp.freerdpcore.services; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import android.content.Context; import android.provider.BaseColumns; +import android.util.Log; +import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class BookmarkDB extends SQLiteOpenHelper { - private static final int DB_VERSION = 1; + private static final int DB_VERSION = 3; private static final String DB_NAME = "bookmarks.db"; public static final String ID = BaseColumns._ID; @@ -52,33 +58,7 @@ public class BookmarkDB extends SQLiteOpenHelper db.execSQL(sqlPerformanceFlags); - String sqlManualBookmarks = - "CREATE TABLE tbl_manual_bookmarks (" - + ID + " INTEGER PRIMARY KEY, " - + "label TEXT NOT NULL, " - + "hostname TEXT NOT NULL, " - + "username TEXT NOT NULL, " - + "password TEXT, " - + "domain TEXT, " - + "port TEXT, " - + "screen_settings INTEGER NOT NULL, " - + "performance_flags INTEGER NOT NULL, " - - + "enable_3g_settings INTEGER DEFAULT 0, " - + "screen_3g INTEGER NOT NULL, " - + "performance_3g INTEGER NOT NULL, " - + "security INTEGER, " - + "remote_program TEXT, " - + "work_dir TEXT, " - + "console_mode INTEGER, " - - + "FOREIGN KEY(screen_settings) REFERENCES tbl_screen_settings(" + ID + "), " - + "FOREIGN KEY(performance_flags) REFERENCES tbl_performance_flags(" + ID + "), " - + "FOREIGN KEY(screen_3g) REFERENCES tbl_screen_settings(" + ID + "), " - + "FOREIGN KEY(performance_3g) REFERENCES tbl_performance_flags(" + ID + ") " - - + ");"; - + String sqlManualBookmarks = getManualBookmarksCreationString(); db.execSQL(sqlManualBookmarks); @@ -120,6 +100,7 @@ public class BookmarkDB extends SQLiteOpenHelper + "performance_flags, " + "screen_3g, " + "performance_3g, " + + "redirect_sdcard, " + "security, " + "remote_program, " + "work_dir, " @@ -131,12 +112,101 @@ public class BookmarkDB extends SQLiteOpenHelper + "'', " + "'', " + "3389, " - + "1, 1, 2, 2, 0, '', '', 0);"; + + "1, 1, 2, 2, 0, 0, '', '', 0);"; db.execSQL(sqlInsertDefaultSessionEntry); } + private String getManualBookmarksCreationString() + { + return ( + "CREATE TABLE IF NOT EXISTS tbl_manual_bookmarks (" + + ID + " INTEGER PRIMARY KEY, " + + "label TEXT NOT NULL, " + + "hostname TEXT NOT NULL, " + + "username TEXT NOT NULL, " + + "password TEXT, " + + "domain TEXT, " + + "port TEXT, " + + "screen_settings INTEGER NOT NULL, " + + "performance_flags INTEGER NOT NULL, " + + + "enable_gateway_settings INTEGER DEFAULT 0, " + + "gateway_hostname TEXT, " + + "gateway_port INTEGER DEFAULT 443, " + + "gateway_username TEXT, " + + "gateway_password TEXT, " + + "gateway_domain TEXT, " + + + "enable_3g_settings INTEGER DEFAULT 0, " + + "screen_3g INTEGER NOT NULL, " + + "performance_3g INTEGER NOT NULL, " + + "redirect_sdcard INTEGER, " + + "security INTEGER, " + + "remote_program TEXT, " + + "work_dir TEXT, " + + "console_mode INTEGER, " + + + "FOREIGN KEY(screen_settings) REFERENCES tbl_screen_settings(" + ID + "), " + + "FOREIGN KEY(performance_flags) REFERENCES tbl_performance_flags(" + ID + "), " + + "FOREIGN KEY(screen_3g) REFERENCES tbl_screen_settings(" + ID + "), " + + "FOREIGN KEY(performance_3g) REFERENCES tbl_performance_flags(" + ID + ") " + + + ");"); + } + + // from http://stackoverflow.com/questions/3424156/upgrade-sqlite-database-from-one-version-to-another @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) - { + { + db.beginTransaction(); + + // run a table creation with if not exists (we are doing an upgrade, so the table might + // not exists yet, it will fail alter and drop) + db.execSQL(getManualBookmarksCreationString()); + // put in a list the existing columns + List columns = GetColumns(db, "tbl_manual_bookmarks"); + // backup table + db.execSQL("ALTER TABLE tbl_manual_bookmarks RENAME TO 'temp_tbl_manual_bookmarks'"); + // create new table (with new scheme) + db.execSQL(getManualBookmarksCreationString()); + // get the intersection with the new columns, this time columns taken from the upgraded table + columns.retainAll(GetColumns(db, "tbl_manual_bookmarks")); + // restore data + String cols = joinStrings(columns, ","); + db.execSQL(String.format("INSERT INTO %s (%s) SELECT %s from 'temp_%s", "tbl_manual_bookmarks", cols, cols, "tbl_manual_bookmarks'")); + // remove backup table + db.execSQL("DROP table 'temp_tbl_manual_bookmarks'"); + + db.setTransactionSuccessful(); + db.endTransaction(); } + + private static List GetColumns(SQLiteDatabase db, String tableName) { + List ar = null; + Cursor c = null; + try { + c = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 1", null); + if (c != null) { + ar = new ArrayList(Arrays.asList(c.getColumnNames())); + } + } catch (Exception e) { + Log.v(tableName, e.getMessage(), e); + e.printStackTrace(); + } finally { + if (c != null) + c.close(); + } + return ar; + } + + private static String joinStrings(List list, String delim) { + StringBuilder buf = new StringBuilder(); + int num = list.size(); + for (int i = 0; i < num; i++) { + if (i != 0) + buf.append(delim); + buf.append((String) list.get(i)); + } + return buf.toString(); + } } diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/LibFreeRDP.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/LibFreeRDP.java index 8fec00aa7..54de217c9 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/LibFreeRDP.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/LibFreeRDP.java @@ -39,13 +39,20 @@ public class LibFreeRDP private static native void freerdp_set_data_directory(int inst, String directory); + private static native void freerdp_set_clipboard_redirection(int inst, boolean enable); + private static native void freerdp_set_drive_redirection(int inst, String path); + + private static native void freerdp_set_gateway_info(int inst, String gatewayhostname, int port, + String gatewayusername, String gatewaypassword, String gatewaydomain); + private static native boolean freerdp_update_graphics(int inst, Bitmap bitmap, int x, int y, int width, int height); private static native void freerdp_send_cursor_event(int inst, int x, int y, int flags); private static native void freerdp_send_key_event(int inst, int keycode, boolean down); private static native void freerdp_send_unicodekey_event(int inst, int keycode); - + private static native void freerdp_send_clipboard_data(int inst, String data); + private static native String freerdp_get_version(); private static final String TAG = "LibFreeRDP"; @@ -65,6 +72,7 @@ public class LibFreeRDP boolean OnVerifiyCertificate(String subject, String issuer, String fingerprint); void OnGraphicsUpdate(int x, int y, int width, int height); void OnGraphicsResize(int width, int height, int bpp); + void OnRemoteClipboardChanged(String data); } private static EventListener listener; @@ -143,6 +151,21 @@ public class LibFreeRDP BookmarkBase.AdvancedSettings advancedSettings = bookmark.getAdvancedSettings(); freerdp_set_advanced_settings(inst, advancedSettings.getRemoteProgram(), advancedSettings.getWorkDir()); + // drive redirection enabled? + if (advancedSettings.getRedirectSDCard()) + freerdp_set_drive_redirection(inst, android.os.Environment.getExternalStorageDirectory().getPath()); + + // always enable clipboard redirection + freerdp_set_clipboard_redirection(inst, true); + + // Gateway enabled? + if (bookmark.getType() == BookmarkBase.TYPE_MANUAL && bookmark.get().getEnableGatewaySettings()) + { + ManualBookmark.GatewaySettings gatewaySettings = bookmark.get().getGatewaySettings(); + freerdp_set_gateway_info(inst, gatewaySettings.getHostname(), gatewaySettings.getPort(), + gatewaySettings.getUsername(), gatewaySettings.getPassword(), gatewaySettings.getDomain()); + } + return true; } @@ -171,6 +194,11 @@ public class LibFreeRDP freerdp_send_unicodekey_event(inst, keycode); } + public static void sendClipboardData(int inst, String data) + { + freerdp_send_clipboard_data(inst, data); + } + private static void OnConnectionSuccess(int inst) { if (listener != null) @@ -246,7 +274,17 @@ public class LibFreeRDP if (uiEventListener != null) uiEventListener.OnGraphicsResize(width, height, bpp); } - + + private static void OnRemoteClipboardChanged(int inst, String data) + { + SessionState s = GlobalApp.getSession(inst); + if (s == null) + return; + UIEventListener uiEventListener = s.getUIEventListener(); + if (uiEventListener != null) + uiEventListener.OnRemoteClipboardChanged(data); + } + public static String getVersion() { return freerdp_get_version(); diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/ManualBookmarkGateway.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/ManualBookmarkGateway.java index 6b07850ac..146631544 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/ManualBookmarkGateway.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/ManualBookmarkGateway.java @@ -39,12 +39,26 @@ public class ManualBookmarkGateway extends BookmarkBaseGateway { ManualBookmark bm = (ManualBookmark)bookmark; columns.put("hostname", bm.getHostname()); columns.put("port", bm.getPort()); + + // gateway settings + columns.put("enable_gateway_settings", bm.getEnableGatewaySettings()); + columns.put("gateway_hostname", bm.getGatewaySettings().getHostname()); + columns.put("gateway_port", bm.getGatewaySettings().getPort()); + columns.put("gateway_username", bm.getGatewaySettings().getUsername()); + columns.put("gateway_password", bm.getGatewaySettings().getPassword()); + columns.put("gateway_domain", bm.getGatewaySettings().getDomain()); } @Override protected void addBookmarkSpecificColumns(ArrayList columns) { columns.add("hostname"); columns.add("port"); + columns.add("enable_gateway_settings"); + columns.add("gateway_hostname"); + columns.add("gateway_port"); + columns.add("gateway_username"); + columns.add("gateway_password"); + columns.add("gateway_domain"); } @Override @@ -52,8 +66,11 @@ public class ManualBookmarkGateway extends BookmarkBaseGateway { ManualBookmark bm = (ManualBookmark)bookmark; bm.setHostname(cursor.getString(cursor.getColumnIndex("hostname"))); bm.setPort(cursor.getInt(cursor.getColumnIndex("port"))); - } + bm.setEnableGatewaySettings(cursor.getInt(cursor.getColumnIndex("enable_gateway_settings")) == 0 ? false : true); + readGatewaySettings(bm, cursor); + } + public BookmarkBase findByLabelOrHostname(String pattern) { if(pattern.length() == 0) @@ -84,4 +101,14 @@ public class ManualBookmarkGateway extends BookmarkBaseGateway { cursor.close(); return bookmarks; } + + private void readGatewaySettings(ManualBookmark bookmark, Cursor cursor) + { + ManualBookmark.GatewaySettings gatewaySettings = bookmark.getGatewaySettings(); + gatewaySettings.setHostname(cursor.getString(cursor.getColumnIndex("gateway_hostname"))); + gatewaySettings.setPort(cursor.getInt(cursor.getColumnIndex("gateway_port"))); + gatewaySettings.setUsername(cursor.getString(cursor.getColumnIndex("gateway_username"))); + gatewaySettings.setPassword(cursor.getString(cursor.getColumnIndex("gateway_password"))); + gatewaySettings.setDomain(cursor.getString(cursor.getColumnIndex("gateway_domain"))); + } } diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/ClipboardManagerProxy.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/ClipboardManagerProxy.java new file mode 100644 index 000000000..83f6ca562 --- /dev/null +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/ClipboardManagerProxy.java @@ -0,0 +1,89 @@ +package com.freerdp.freerdpcore.utils; + +import android.annotation.TargetApi; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; + +public abstract class ClipboardManagerProxy { + + public static ClipboardManagerProxy getClipboardManager(Context ctx) { + if (VERSION.SDK_INT < VERSION_CODES.HONEYCOMB) + return new PreHCClipboardManager(ctx); + else + return new HCClipboardManager(ctx); + } + + public static interface OnClipboardChangedListener { + void onClipboardChanged(String data); + } + + public abstract void setClipboardData(String data); + public abstract void addClipboardChangedListener(OnClipboardChangedListener listener); + public abstract void removeClipboardboardChangedListener(OnClipboardChangedListener listener); + + private static class PreHCClipboardManager extends ClipboardManagerProxy { + + public PreHCClipboardManager(Context ctx) { + + } + + @Override + public void setClipboardData(String data) { + } + + @Override + public void addClipboardChangedListener( + OnClipboardChangedListener listener) { + } + + @Override + public void removeClipboardboardChangedListener( + OnClipboardChangedListener listener) { + } + } + + @TargetApi(11) + private static class HCClipboardManager extends ClipboardManagerProxy implements ClipboardManager.OnPrimaryClipChangedListener { + private ClipboardManager mClipboardManager; + private OnClipboardChangedListener mListener; + + public HCClipboardManager(Context ctx) { + mClipboardManager = (ClipboardManager) ctx.getSystemService(Context.CLIPBOARD_SERVICE); + } + + @Override + public void setClipboardData(String data) { + mClipboardManager.setPrimaryClip(ClipData.newPlainText("rdp-clipboard", data == null ? "" : data)); + } + + @Override + public void onPrimaryClipChanged() { + ClipData clip = mClipboardManager.getPrimaryClip(); + String data = null; + + if (clip != null && clip.getItemCount() > 0) { + data = clip.getItemAt(0).getText().toString(); + } + if (mListener != null) { + mListener.onClipboardChanged(data); + } + } + + @Override + public void addClipboardChangedListener( + OnClipboardChangedListener listener) { + mListener = listener; + mClipboardManager.addPrimaryClipChangedListener(this); + } + + @Override + public void removeClipboardboardChangedListener( + OnClipboardChangedListener listener) { + mListener = null; + mClipboardManager.removePrimaryClipChangedListener(this); + } + } +} diff --git a/client/Android/aFreeRDP/AndroidManifest.xml.cmake b/client/Android/aFreeRDP/AndroidManifest.xml.cmake index 7e6e0e86c..751c235b9 100644 --- a/client/Android/aFreeRDP/AndroidManifest.xml.cmake +++ b/client/Android/aFreeRDP/AndroidManifest.xml.cmake @@ -3,8 +3,8 @@ + android:versionCode="3" + android:versionName="@GIT_REVISION@" > diff --git a/client/Android/aFreeRDP/project.properties b/client/Android/aFreeRDP/project.properties index 857d31de6..4507b1846 100644 --- a/client/Android/aFreeRDP/project.properties +++ b/client/Android/aFreeRDP/project.properties @@ -8,6 +8,6 @@ # project structure. # Project target. -target=android-8 +target=android-11 android.library.reference.1=../FreeRDPCore manifestmerger.enabled=true diff --git a/client/Android/aFreeRDP/res/values-fr/strings.xml b/client/Android/aFreeRDP/res/values-fr/strings.xml new file mode 100644 index 000000000..3c36d79ff --- /dev/null +++ b/client/Android/aFreeRDP/res/values-fr/strings.xml @@ -0,0 +1,7 @@ + + + aFreeRDP + + aFreeRDP + L\'ordinateur distant + diff --git a/client/Mac/.gitignore b/client/Mac/.gitignore index 600769254..334032120 100644 --- a/client/Mac/.gitignore +++ b/client/Mac/.gitignore @@ -1,2 +1,3 @@ *.app +*.framework diff --git a/client/Mac/CMakeLists.txt b/client/Mac/CMakeLists.txt index 2183eb9d2..ec8b56eab 100644 --- a/client/Mac/CMakeLists.txt +++ b/client/Mac/CMakeLists.txt @@ -1,83 +1,122 @@ -project(MacFreeRDP) +project(MacFreeRDP-library) -set(MODULE_NAME "MacFreeRDP") -set(MODULE_PREFIX "FREERDP_CLIENT_MAC") +# add directory for App +add_subdirectory(cli) -set(FRAMEWORK_HEADERS_PATH /System/Library/Frameworks/Cocoa.framework/Versions/A/Headers/) -include_directories(${FRAMEWORK_HEADERS_PATH} /System/Library/Frameworks) - -# set(CMAKE_OSX_SYSROOT MacOSX10.7.sdk) -set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.4") -set(GUI_TYPE MACOSX_BUNDLE) +set(MODULE_NAME "MacFreeRDP-library") +set(MODULE_PREFIX "FREERDP_CLIENT_MAC-LIB") # Import libraries find_library(FOUNDATION_LIBRARY Foundation) find_library(COCOA_LIBRARY Cocoa) find_library(APPKIT_LIBRARY AppKit) -set(MACOSX_BUNDLE_INFO_STRING "MacFreeRDP") -set(MACOSX_BUNDLE_ICON_FILE "FreeRDP.icns") +set(MACOSX_BUNDLE_INFO_STRING "MacFreeRDP-library") set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.freerdp.mac") -set(MACOSX_BUNDLE_BUNDLE_IDENTIFIER "FreeRDP.Mac") -set(MACOSX_BUNDLE_LONG_VERSION_STRING "MacFreeRDP Version 1.0.1") -set(MACOSX_BUNDLE_BUNDLE_NAME "MacFreeRDP") -set(MACOSX_BUNDLE_SHORT_VERSION_STRING 1.0.1) -set(MACOSX_BUNDLE_BUNDLE_VERSION 1.0.1) -set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2012. All Rights Reserved.") - -set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "MainMenu") -set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication") +set(MACOSX_BUNDLE_BUNDLE_IDENTIFIER "FreeRDP-library.Mac") +set(MACOSX_BUNDLE_LONG_VERSION_STRING "MacFreeRDP library Version 1.1") +set(MACOSX_BUNDLE_BUNDLE_NAME "MacFreeRDP-library") +set(MACOSX_BUNDLE_SHORT_VERSION_STRING 1.1.0) +set(MACOSX_BUNDLE_BUNDLE_VERSION 1.1.0) +set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2013. All Rights Reserved.") mark_as_advanced(COCOA_LIBRARY FOUNDATION_LIBRARY APPKIT_LIBRARY) set(EXTRA_LIBS ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY}) -set(APP_TYPE MACOSX_BUNDLE) + +set(${MODULE_NAME}_RESOURCES "en.lproj/InfoPlist.strings") # OS X Interface Builder files file(GLOB ${MODULE_NAME}_XIBS *.xib) -set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_XIBS} ${MACOSX_BUNDLE_ICON_FILE}) +# Include XIB file in Xcode resources. +if("${CMAKE_GENERATOR}" MATCHES "Xcode") + message(STATUS "Adding Xcode XIB resources for ${MODULE_NAME}") + set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_RESOURCES} ${${MODULE_NAME}_XIBS}) +endif("${CMAKE_GENERATOR}" MATCHES "Xcode") -# Headers -file(GLOB ${MODULE_NAME}_HEADERS *.h) -# Source -file(GLOB ${MODULE_NAME}_SOURCES *.m) - -add_executable(${MODULE_NAME} - ${APP_TYPE} - ${${MODULE_NAME}_HEADERS} - ${${MODULE_NAME}_SOURCES} +add_library(${MODULE_NAME} + SHARED + MRDPView.h + MRDPView.m + MRDPCursor.m + PasswordDialog.m ${${MODULE_NAME}_RESOURCES}) -# This is necessary for the xib file part below -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) - -# This allows for automatic xib to nib ibitool -set_target_properties(${MODULE_NAME} PROPERTIES RESOURCE "${${MODULE_NAME}_RESOURCES}") - -# Automatic ref counting -# temporary turn off for x86_64 build issue -# set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES) +# configures the framework to always be looked for in the application bundle in the Frameworks sub-folder. +SET_TARGET_PROPERTIES(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_INSTALL_PATH @executable_path/../Frameworks/) + +set_target_properties(${MODULE_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH} + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) # Support for automatic reference counting requires non-fragile abi. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-nonfragile-abi") -# XCode project architecture to native architecture of build machine -# ----------------------------------------------------------------------------------------------------- -# Issue: Had some issues with FreeRDP project building only 64 bit and -# MacFreeRDP attempting to link to both 32 and 64 for dual target. -# In the future the FreeRDP Xcode project should be pulled in for a couple of reasons: -# 1) better step-into debugging 2) automatic dependency compilation and multi-arch compilation + linkage -# If you know the solutions for 1 and 2, please add below. set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)") -# Set the info plist to the custom instance -set_target_properties(${MODULE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) +set(MODULE_VERSION, 1.1.0) -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${EXTRA_LIBS}) +set_target_properties(${MODULE_NAME} PROPERTIES + FRAMEWORK TRUE + MACOSX_FRAMEWORK_IDENTIFIER com.awakecoding.${MODULE_NAME} + FRAMEWORK_VERSION 1.1.0 + MACOSX_FRAMEWORK_SHORT_VERSION_STRING 1.1.0 + MACOSX_FRAMEWORK_BUNDLE_VERSION 1.1.0 + PUBLIC_HEADER "MRDPView.h" + INSTALL_NAME_DIR "@executable_path/../../Frameworks" + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist + BUILD_WITH_INSTALL_RPATH 1) -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client) +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${EXTRA_LIBS} freerdp-client) + +# Set a list of the dependent targets used by the application. There should be a way to get this list automatically +# from cmake, but for now I put it down manually. I got the references by calling +# otool -L MacFreeRDP-client + +set(DEPENDENCIES + winpr-asn1 + winpr-heap + winpr-sspi + winpr-bcrypt + winpr-input + winpr-sspicli + winpr-credentials + winpr-interlocked + winpr-synch + winpr-credui + winpr-io + winpr-sysinfo + winpr-crt + winpr-library + winpr-thread + winpr-crypto + winpr-timezone + winpr-dsparse + winpr-path + winpr-utils + winpr-environment + winpr-pipe + winpr-winhttp + winpr-error + winpr-pool + winpr-winsock + winpr-file + winpr-registry + winpr-handle + winpr-rpc + freerdp-utils + freerdp-gdi + freerdp-rail + freerdp-cache + freerdp-codec + freerdp-primitives + freerdp-core + freerdp-crypto + freerdp-client + freerdp-locale + freerdp-common) set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE freerdp @@ -87,6 +126,67 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHI MODULE winpr MODULES winpr-input winpr-crt winpr-utils) +set_target_properties(${MODULE_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "") target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Mac") + +# Add a post-build event to copy the dependent libraries in the framework bundle +# Call install_name_tool to reassign the library install name +foreach(LIB ${DEPENDENCIES}) + # message("adding post-build dependency: ${LIB}") + add_custom_command(TARGET ${MODULE_NAME} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "$" + "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$" + COMMENT "Copying ${LIB} to output directory" + COMMAND install_name_tool -change "$" "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$" "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}" + COMMENT Setting install name for ${LIB} + COMMAND "${CMAKE_COMMAND}" -E echo install_name_tool -change "$" "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$" "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}" + ) +endforeach() + + +# Call install_name_tool to reassign the library install names in dependent libraries +foreach(DEST ${DEPENDENCIES}) +foreach(LIB ${DEPENDENCIES}) + # message("adding post-build dependency: ${LIB}") + add_custom_command(TARGET ${MODULE_NAME} POST_BUILD + COMMAND install_name_tool -change "$" "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$" "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$" + COMMENT Setting install name for ${LIB} in module ${DEST} +) + +# COMMAND "${CMAKE_COMMAND}" -E echo install_name_tool -change "$" #"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$" #"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$" +# ) + +endforeach() +endforeach() + + +# Add post-build NIB file generation in unix makefiles. XCode handles this implicitly. +if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") + message(STATUS "Adding post-build NIB file generation event for ${MODULE_NAME}") + + # Make sure we can find the 'ibtool' program. If we can NOT find it we + # skip generation of this project + find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin") + if (${IBTOOL} STREQUAL "IBTOOL-NOTFOUND") + message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with + the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin") + endif() + + # Make sure the 'Resources' Directory is correctly created before we build + add_custom_command (TARGET ${MODULE_NAME} PRE_BUILD + COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources) + + # Compile the .xib files using the 'ibtool' program with the destination being the app package + foreach(xib ${${MODULE_NAME}_XIBS}) + get_filename_component(XIB_WE ${xib} NAME_WE) + + add_custom_command (TARGET ${MODULE_NAME} POST_BUILD + COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text + --compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources/${XIB_WE}.nib ${xib} + COMMENT "Compiling ${xib}") + endforeach() + +endif() diff --git a/client/Mac/Info.plist b/client/Mac/Info.plist index cb6976502..2b552b421 100644 --- a/client/Mac/Info.plist +++ b/client/Mac/Info.plist @@ -3,11 +3,9 @@ CFBundleDevelopmentRegion - en - CFBundleExecutable - + English CFBundleIconFile - FreeRDP + CFBundleIdentifier FreeRDP.Mac CFBundleInfoDictionaryVersion @@ -15,20 +13,14 @@ CFBundleName CFBundlePackageType - APPL + FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 - LSMinimumSystemVersion - - NSHumanReadableCopyright - Copyright © 2012 __MyCompanyName__. All rights reserved. - NSMainNibFile - MainMenu NSPrincipalClass - NSApplication + diff --git a/client/Mac/MRDPRailView.h b/client/Mac/MRDPRailView.h deleted file mode 100644 index 84d4c55ee..000000000 --- a/client/Mac/MRDPRailView.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * MacFreeRDP - * - * Copyright 2012 Thomas Goddard - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import - -#import "freerdp/gdi/gdi.h" -#import "freerdp/rail/rail.h" - -#import "MRDPRailWindow.h" - -@interface MRDPRailView : NSView -{ - freerdp* rdp_instance; - rdpContext* context; - NSBitmapImageRep* bmiRep; - NSPoint savedDragLocation; - char* pixelData; - BOOL mouseInClientArea; - BOOL titleBarClicked; - BOOL gestureEventInProgress; - int width; - int height; - int savedWindowId; - int scrollWheelCount; - - int kdlshift; - int kdrshift; - int kdlctrl; - int kdrctrl; - int kdlalt; - int kdralt; - int kdlmeta; - int kdrmeta; - int kdcapslock; - -@public - BOOL isMoveSizeInProgress; - BOOL saveInitialDragLoc; - BOOL skipMoveWindowOnce; - int localMoveType; -} - -@property (assign) MRDPRailWindow* mrdpRailWindow; -@property (assign) int windowIndex; -@property (assign) BOOL activateWindow; - -- (void) windowDidMove:(NSNotification*) notification; -- (void) updateDisplay; -- (void) setRdpInstance:(freerdp*) instance width:(int) w andHeight:(int) h windowID:(int) windowID; -- (void) setupBmiRep:(int) width :(int) height; -- (void) releaseResources; - -void mac_rail_MoveWindow(rdpRail* rail, rdpWindow* window); -void apple_to_windowMove(NSRect* r, RAIL_WINDOW_MOVE_ORDER* windowMove); -void mac_send_rail_client_event(rdpChannels* channels, UINT16 event_type, void* param); -void windows_to_apple_cords(NSRect* r); -void rail_MoveWindow(rdpRail* rail, rdpWindow* window); -void mac_rail_send_activate(int window_id); - -@end diff --git a/client/Mac/MRDPRailView.m b/client/Mac/MRDPRailView.m deleted file mode 100644 index b23c9c3e4..000000000 --- a/client/Mac/MRDPRailView.m +++ /dev/null @@ -1,930 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * MacFreeRDP - * - * Copyright 2012 Thomas Goddard - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "MRDPRailView.h" - -#define USE_RAIL_CVT - -@implementation MRDPRailView - -@synthesize mrdpRailWindow, windowIndex, activateWindow; - -MRDPRailView* g_mrdpRailView; - -- (void) updateDisplay -{ - BOOL moveWindow = NO; - NSRect srcRectOuter; - NSRect destRectOuter; - - rdpGdi* gdi; - - if ((context == 0) || (context->gdi == 0)) - return; - - if (context->gdi->primary->hdc->hwnd->invalid->null) - return; - - if (context->gdi->drawing != context->gdi->primary) - return; - - gdi = context->gdi; - - srcRectOuter = NSMakeRect(0, 0, self->width, self->height); - destRectOuter = [[self window] frame]; - - // cannot be bigger than our current screen size - NSRect screenSize = [[NSScreen mainScreen] frame]; - - if (destRectOuter.size.width > screenSize.size.width) - { - destRectOuter.size.width = screenSize.size.width; - moveWindow = YES; - } - - if (destRectOuter.size.height > screenSize.size.height) - { - destRectOuter.size.height = screenSize.size.height; - moveWindow = YES; - } - - if (destRectOuter.origin.x + destRectOuter.size.width > width) - destRectOuter.size.width = width - destRectOuter.origin.x; - - [self setupBmiRep:destRectOuter.size.width :destRectOuter.size.height]; - - if (moveWindow) - { - moveWindow = NO; - RAIL_WINDOW_MOVE_ORDER newWndLoc; - apple_to_windowMove(&destRectOuter, &newWndLoc); - newWndLoc.windowId = savedWindowId; - //skipMoveWindowOnce = TRUE; - //mac_send_rail_client_event(g_mrdpRailView->rdp_instance->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &newWndLoc); - } - - destRectOuter.origin.y = height - destRectOuter.origin.y - destRectOuter.size.height; - rail_convert_color_space(pixelData, (char *) gdi->primary_buffer, - &destRectOuter, self->width, self->height); - - if (moveWindow) - [self setNeedsDisplayInRect:destRectOuter]; - else - [self setNeedsDisplayInRect:[self frame]]; - - gdi->primary->hdc->hwnd->ninvalid = 0; -} - -/** ********************************************************************* - * called when our view needs to be redrawn - ***********************************************************************/ - -- (void) drawRect:(NSRect)dirtyRect -{ - [bmiRep drawInRect:dirtyRect fromRect:dirtyRect operation:NSCompositeCopy fraction:1.0 respectFlipped:NO hints:nil]; - - if (pixelData) - { - free(pixelData); - pixelData = NULL; - } - - bmiRep = nil; -} - -/** ********************************************************************* - * become first responder so we can get keyboard and mouse events - ***********************************************************************/ - -- (BOOL)acceptsFirstResponder -{ - return YES; -} - -- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent -{ - return NO; -} - -/** ********************************************************************* - * called when a mouse move event occurs - * - * ideally we want to be called when the mouse moves over NSView client area, - * but in reality we get called any time the mouse moves anywhere on the screen; - * we could use NSTrackingArea class to handle this but this class is available - * on Mac OS X v10.5 and higher; since we want to be compatible with older - * versions, we do this manually. - * - * TODO: here is how it can be done using legacy methods - * http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/MouseTrackingEvents/MouseTrackingEvents.html#//apple_ref/doc/uid/10000060i-CH11-SW1 - ***********************************************************************/ - -- (void) mouseMoved:(NSEvent *)event -{ - [super mouseMoved:event]; - - NSRect winFrame = [[self window] frame]; - NSPoint loc = [event locationInWindow]; - - int x = (int) (winFrame.origin.x + loc.x); - int y = (int) (winFrame.origin.y + loc.y); - - y = height - y; - - /* send mouse motion event to RDP server */ - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y); -} - -/** ********************************************************************* - * called when left mouse button is pressed down - ***********************************************************************/ - -- (void)mouseDown:(NSEvent *) event -{ - [super mouseDown:event]; - - NSRect winFrame = [[self window] frame]; - NSPoint loc = [event locationInWindow]; - int x = (int) (winFrame.origin.x + loc.x); - int y = (int) (winFrame.origin.y + loc.y); - int yPos = (int) (winFrame.size.height - loc.y); - - y = height - y; - - if ((yPos >= 4) && (yPos <= 20)) - titleBarClicked = YES; - else - titleBarClicked = NO; - - savedDragLocation.x = loc.x; - savedDragLocation.y = loc.y; - - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y); -} - -/** ********************************************************************* - * called when left mouse button is released - ***********************************************************************/ - -- (void) mouseUp:(NSEvent *) event -{ - [super mouseUp:event]; - - NSRect winFrame = [[self window] frame]; - NSPoint loc = [event locationInWindow]; - int x = (int) (winFrame.origin.x + loc.x); - int y = (int) (winFrame.origin.y + loc.y); - y = height - y; - - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON1, x, y); - titleBarClicked = NO; -} - -/** ********************************************************************* - * called when right mouse button is pressed down - ***********************************************************************/ - -- (void) rightMouseDown:(NSEvent *)event -{ - [super rightMouseDown:event]; - - NSRect winFrame = [[self window] frame]; - NSPoint loc = [event locationInWindow]; - int x = (int) (winFrame.origin.x + loc.x); - int y = (int) (winFrame.origin.y + loc.y); - y = height - y; - - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y); -} - -/** ********************************************************************* - * called when right mouse button is released - ***********************************************************************/ - -- (void) rightMouseUp:(NSEvent *)event -{ - [super rightMouseUp:event]; - - NSRect winFrame = [[self window] frame]; - NSPoint loc = [event locationInWindow]; - int x = (int) (winFrame.origin.x + loc.x); - int y = (int) (winFrame.origin.y + loc.y); - y = height - y; - - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON2, x, y); -} - -/** ********************************************************************* - * called when middle mouse button is pressed - ***********************************************************************/ - -- (void) otherMouseDown:(NSEvent *)event -{ - [super otherMouseDown:event]; - - NSRect winFrame = [[self window] frame]; - NSPoint loc = [event locationInWindow]; - int x = (int) (winFrame.origin.x + loc.x); - int y = (int) (winFrame.origin.y + loc.y); - y = height - y; - - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y); -} - -/** ********************************************************************* - * called when middle mouse button is released - ***********************************************************************/ - -- (void) otherMouseUp:(NSEvent *)event -{ - [super otherMouseUp:event]; - - NSRect winFrame = [[self window] frame]; - NSPoint loc = [event locationInWindow]; - int x = (int) (winFrame.origin.x + loc.x); - int y = (int) (winFrame.origin.y + loc.y); - y = height - y; - - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON3, x, y); -} - -- (void) scrollWheel:(NSEvent *)event -{ - uint16 flags; - - [super scrollWheel:event]; - - // we get more two finger trackpad scroll events - // than scrollWheel events, so we drop some - - if (gestureEventInProgress) - { - scrollWheelCount++; - - if (scrollWheelCount % 8 != 0) - return; - } - - if ([event scrollingDeltaY] < 0) - { - flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; - } - else - { - flags = PTR_FLAGS_WHEEL | 0x78; - } - - rdp_instance->input->MouseEvent(rdp_instance->input, flags, 0, 0); -} - -/** ********************************************************************* - * called when mouse is moved with left button pressed - * note: invocation order is: mouseDown, mouseDragged, mouseUp - ***********************************************************************/ -- (void) mouseDragged:(NSEvent *)event -{ - [super mouseDragged:event]; - - NSRect winFrame = [[self window] frame]; - NSPoint loc = [event locationInWindow]; - int x = (int) loc.x; - int y = (int) loc.y; - - if (titleBarClicked) - { - // window is being dragged to a new location - int newX = x - savedDragLocation.x; - int newY = y - savedDragLocation.y; - - if ((newX == 0) && (newY == 0)) - return; - - winFrame.origin.x += newX; - winFrame.origin.y += newY; - - [[self window] setFrame:winFrame display:YES]; - return; - } - - if (localMoveType == RAIL_WMSZ_LEFT) - { - // left border resize taking place - int diff = (int) (loc.x - savedDragLocation.x); - - if (diff == 0) - return; - - if (diff < 0) - { - diff = abs(diff); - winFrame.origin.x -= diff; - winFrame.size.width += diff; - } - else - { - winFrame.origin.x += diff; - winFrame.size.width -= diff; - } - - [[self window] setFrame:winFrame display:YES]; - return; - } - - if (localMoveType == RAIL_WMSZ_RIGHT) - { - // right border resize taking place - int diff = (int) (loc.x - savedDragLocation.x); - - if (diff == 0) - return; - - savedDragLocation.x = loc.x; - savedDragLocation.y = loc.y; - - winFrame.size.width += diff; - [[self window] setFrame:winFrame display:YES]; - - return; - } - - if (localMoveType == RAIL_WMSZ_TOP) - { - // top border resize taking place - int diff = (int) (loc.y - savedDragLocation.y); - - if (diff == 0) - return; - - savedDragLocation.x = loc.x; - savedDragLocation.y = loc.y; - - winFrame.size.height += diff; - [[self window] setFrame:winFrame display:YES]; - - return; - } - - if (localMoveType == RAIL_WMSZ_BOTTOM) - { - // bottom border resize taking place - int diff = (int) (loc.y - savedDragLocation.y); - - if (diff == 0) - return; - - if (diff < 0) - { - diff = abs(diff); - winFrame.origin.y -= diff; - winFrame.size.height += diff; - } - else - { - winFrame.origin.y += diff; - winFrame.size.height -= diff; - } - - [[self window] setFrame:winFrame display:YES]; - return; - } - - if (localMoveType == RAIL_WMSZ_TOPLEFT) - { - // top left border resize taking place - int diff = (int) (loc.x - savedDragLocation.x); - - if (diff != 0) - { - if (diff < 0) - { - diff = abs(diff); - winFrame.origin.x -= diff; - winFrame.size.width += diff; - } - else - { - winFrame.origin.x += diff; - winFrame.size.width -= diff; - } - } - - diff = (int) (loc.y - savedDragLocation.y); - - if (diff != 0) - { - savedDragLocation.y = loc.y; - winFrame.size.height += diff; - } - - [[self window] setFrame:winFrame display:YES]; - return; - } - - if (localMoveType == RAIL_WMSZ_TOPRIGHT) - { - // top right border resize taking place - int diff = (int) (loc.x - savedDragLocation.x); - - if (diff != 0) - winFrame.size.width += diff; - - diff = (int) (loc.y - savedDragLocation.y); - - if (diff != 0) - winFrame.size.height += diff; - - savedDragLocation.x = loc.x; - savedDragLocation.y = loc.y; - - [[self window] setFrame:winFrame display:YES]; - return; - } - - if (localMoveType == RAIL_WMSZ_BOTTOMLEFT) - { - // bottom left border resize taking place - int diff = (int) (loc.x - savedDragLocation.x); - - if (diff != 0) - { - if (diff < 0) - { - diff = abs(diff); - winFrame.origin.x -= diff; - winFrame.size.width += diff; - } - else - { - winFrame.origin.x += diff; - winFrame.size.width -= diff; - } - } - - diff = (int) (loc.y - savedDragLocation.y); - - if (diff != 0) - { - if (diff < 0) - { - diff = abs(diff); - winFrame.origin.y -= diff; - winFrame.size.height += diff; - } - else - { - winFrame.origin.y += diff; - winFrame.size.height -= diff; - } - } - - [[self window] setFrame:winFrame display:YES]; - return; - } - - if (localMoveType == RAIL_WMSZ_BOTTOMRIGHT) - { - // bottom right border resize taking place - int diff = (int) (loc.x - savedDragLocation.x); - - if (diff != 0) - { - savedDragLocation.x = loc.x; - //savedDragLocation.y = loc.y; - winFrame.size.width += diff; - } - - diff = (int) (loc.y - savedDragLocation.y); - - if (diff != 0) - { - if (diff < 0) - { - diff = abs(diff); - winFrame.origin.y -= diff; - winFrame.size.height += diff; - } - else - { - winFrame.origin.y += diff; - winFrame.size.height -= diff; - } - } - - [[self window] setFrame:winFrame display:YES]; - return; - } - - x = (int) (winFrame.origin.x + loc.x); - y = (int) (winFrame.origin.y + loc.y); - y = height - y; - - // send mouse motion event to RDP server - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y); -} - -/** ********************************************************************* - * called when a key is pressed - ***********************************************************************/ - -- (void) keyDown:(NSEvent *) event -{ - int key; - USHORT extended; - DWORD vkcode; - DWORD scancode; - - key = [event keyCode] + 8; - - vkcode = GetVirtualKeyCodeFromKeycode(key, KEYCODE_TYPE_APPLE); - scancode = GetVirtualScanCodeFromVirtualKeyCode(vkcode, 4); - extended = (scancode & KBDEXT) ? KBDEXT : 0; - - rdp_instance->input->KeyboardEvent(rdp_instance->input, extended | KBD_FLAGS_DOWN, scancode & 0xFF); -} - -/** ********************************************************************* - * called when a key is released - ***********************************************************************/ - -- (void) keyUp:(NSEvent *) event -{ - int key; - USHORT extended; - DWORD vkcode; - DWORD scancode; - - key = [event keyCode] + 8; - - vkcode = GetVirtualKeyCodeFromKeycode(key, KEYCODE_TYPE_APPLE); - scancode = GetVirtualScanCodeFromVirtualKeyCode(vkcode, 4); - extended = (scancode & KBDEXT) ? TRUE : FALSE; - - rdp_instance->input->KeyboardEvent(rdp_instance->input, extended | KBD_FLAGS_RELEASE, scancode & 0xFF); -} - -/** ********************************************************************* - * called when shift, control, alt and meta keys are pressed/released - ***********************************************************************/ - -- (void) flagsChanged:(NSEvent *) event -{ - NSUInteger mf = [event modifierFlags]; - - // caps lock - if (mf == 0x10100) { - printf("TODO: caps lock is on\n"); - kdcapslock = 1; - } - if (kdcapslock && (mf == 0x100)) { - kdcapslock = 0; - printf("TODO: caps lock is off\n"); - } - // left shift - if ((kdlshift == 0) && ((mf & 2) != 0)) { - // left shift went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x2a); - kdlshift = 1; - } - if ((kdlshift != 0) && ((mf & 2) == 0)) { - // left shift went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x2a); - kdlshift = 0; - } - - // right shift - if ((kdrshift == 0) && ((mf & 4) != 0)) { - // right shift went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x36); - kdrshift = 1; - } - if ((kdrshift != 0) && ((mf & 4) == 0)) { - // right shift went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x36); - kdrshift = 0; - } - - // left ctrl - if ((kdlctrl == 0) && ((mf & 1) != 0)) { - // left ctrl went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x1d); - kdlctrl = 1; - } - if ((kdlctrl != 0) && ((mf & 1) == 0)) { - // left ctrl went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x1d); - kdlctrl = 0; - } - - // right ctrl - if ((kdrctrl == 0) && ((mf & 0x2000) != 0)) { - // right ctrl went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x1d); - kdrctrl = 1; - } - if ((kdrctrl != 0) && ((mf & 0x2000) == 0)) { - // right ctrl went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x1d); - kdrctrl = 0; - } - - // left alt - if ((kdlalt == 0) && ((mf & 0x20) != 0)) { - // left alt went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x38); - kdlalt = 1; - } - if ((kdlalt != 0) && ((mf & 0x20) == 0)) { - // left alt went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x38); - kdlalt = 0; - } - - // right alt - if ((kdralt == 0) && ((mf & 0x40) != 0)) { - // right alt went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x38); - kdralt = 1; - } - if ((kdralt != 0) && ((mf & 0x40) == 0)) { - // right alt went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x38); - kdralt = 0; - } - - // left meta - if ((kdlmeta == 0) && ((mf & 0x08) != 0)) { - // left meta went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5b); - kdlmeta = 1; - } - if ((kdlmeta != 0) && ((mf & 0x08) == 0)) { - // left meta went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5b); - kdlmeta = 0; - } - - // right meta - if ((kdrmeta == 0) && ((mf & 0x10) != 0)) { - // right meta went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5c); - kdrmeta = 1; - } - if ((kdrmeta != 0) && ((mf & 0x10) == 0)) { - // right meta went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5c); - kdrmeta = 0; - } -} - -- (void) setRdpInstance:(freerdp *) instance width:(int) w andHeight:(int) h windowID:(int) windowID -{ - rdp_instance = instance; - context = instance->context; - width = w; - height = h; - savedWindowId = windowID; - - NSRect tr = NSMakeRect(0, 0, - [[NSScreen mainScreen] frame].size.width, - [[NSScreen mainScreen] frame].size.height); - - NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:tr options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveAlways owner:self userInfo:nil]; - - [self addTrackingArea:trackingArea]; - - g_mrdpRailView = self; - - [self becomeFirstResponder]; - [self setAcceptsTouchEvents:YES]; - - // we want to be notified when window resizes.... - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:nil]; - - // ...moves - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:nil]; - - // ...and becomes the key window - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:nil]; -} - -- (void) setupBmiRep:(int) frameWidth :(int) frameHeight -{ - struct rgba_data - { - char red; - char green; - char blue; - char alpha; - }; - - if (pixelData) - free(pixelData); - - pixelData = (char *) malloc(frameWidth * frameHeight * sizeof(struct rgba_data)); - bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &pixelData - pixelsWide:frameWidth - pixelsHigh:frameHeight - bitsPerSample:8 - samplesPerPixel:sizeof(struct rgba_data) - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSDeviceRGBColorSpace - bitmapFormat:0 - bytesPerRow:frameWidth * sizeof(struct rgba_data) - bitsPerPixel:0]; -} -- (void) beginGestureWithEvent:(NSEvent *)event -{ - gestureEventInProgress = YES; -} - -- (void) endGestureWithEvent:(NSEvent *)event -{ - gestureEventInProgress = NO; -} - -/** - * called when a bordered window changes size - */ - -- (void) windowDidResize:(NSNotification *) notification -{ - // if we are not the source of this notification, just return - if ([notification object] != [self mrdpRailWindow]) - return; - - // let RDP server know that window has moved - RAIL_WINDOW_MOVE_ORDER windowMove; - NSRect r = [[self window] frame]; - - int diffInHeight = [[self window] frame].size.height - [self frame].size.height; - r.size.height -= diffInHeight; - - apple_to_windowMove(&r, &windowMove); - windowMove.windowId = self->savedWindowId; - mac_send_rail_client_event(self->context->channels, RailChannel_ClientWindowMove, &windowMove); -} - -/** - * called when user moves a bordered window - */ - -- (void) windowDidMove:(NSNotification *) notification -{ - // if we are not the source of this notification, just return - if ([notification object] != [self mrdpRailWindow]) - return; - - // let RDP server know that window has moved - RAIL_WINDOW_MOVE_ORDER windowMove; - NSRect r = [[self window] frame]; - - int diffInHeight = [[self window] frame].size.height - [self frame].size.height; - r.size.height -= diffInHeight; - - apple_to_windowMove(&r, &windowMove); - windowMove.windowId = self->savedWindowId; - mac_send_rail_client_event(self->context->channels, RailChannel_ClientWindowMove, &windowMove); -} - -/** - * called when a NSWindow becomes the key window - */ - -- (void) windowDidBecomeKey:(NSNotification *) notification -{ - // if we are not the source of this notification, just return - if ([notification object] != [self mrdpRailWindow]) - return; - - if (![self activateWindow]) - return; - - [[self window] setAcceptsMouseMovedEvents: YES]; - - //if ([self activateWindow]) - mac_rail_send_activate(savedWindowId); - - // set_current_window(windowIndex); // ? code mis-merge? -} - -- (void) releaseResources -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -void rail_cvt_from_rect(char* dest, char* src, NSRect destRect, int destWidth, int destHeight, NSRect srcRect) -{ -} - -/** ********************************************************************* - * color space conversion used specifically in RAIL - ***********************************************************************/ -void rail_convert_color_space(char* destBuf, char* srcBuf, NSRect* destRect, int width, int height) -{ - int i; - int j; - int numRows; - int srcX; - int srcY; - int destX; - int destY; - int pixelsPerRow; - int pixel; - int pixel1; - int pixel2; - int * src32; - int * dest32; - - int destWidth = destRect->size.width; - int destHeight = destRect->size.height; - - if ((!destBuf) || (!srcBuf)) - return; - - numRows = (destRect->origin.y + destHeight > height) ? height - destRect->origin.y : destHeight; - pixelsPerRow = destWidth; - - srcX = destRect->origin.x; - srcY = destRect->origin.y; - destX = 0; - destY = 0; - - for (i = 0; i < numRows; i++) - { - src32 = (int *) (srcBuf + ((srcY + i) * width + srcX) * 4); - dest32 = (int *) (destBuf + ((destY + i) * destWidth + destX) * 4); - - for (j = 0; j < pixelsPerRow; j++) - { - pixel = *src32; - pixel1 = (pixel & 0x00ff0000) >> 16; - pixel2 = (pixel & 0x000000ff) << 16; - pixel = (pixel & 0xff00ff00) | pixel1 | pixel2; - - *dest32 = pixel; - - src32++; - dest32++; - } - } - - destRect->origin.y = destHeight - destRect->origin.y - destRect->size.height; - return; -} - -/** - * let RDP server know that window has moved - */ - -void rail_MoveWindow(rdpRail * rail, rdpWindow * window) -{ - if (g_mrdpRailView->isMoveSizeInProgress) - return; - - if (g_mrdpRailView->skipMoveWindowOnce) - { - g_mrdpRailView->skipMoveWindowOnce = NO; - return; - } - - // this rect is based on Windows co-ordinates... - NSRect r; - r.origin.x = window->windowOffsetX; - r.origin.y = window->windowOffsetY; - r.size.width = window->windowWidth; - r.size.height = window->windowHeight; - - windows_to_apple_cords(&r); - [[g_mrdpRailView window] setFrame:r display:YES]; -} - - -void mac_rail_send_activate(int window_id) -{ - RAIL_ACTIVATE_ORDER activate; - - activate.windowId = window_id; - activate.enabled = 1; - - mac_send_rail_client_event(g_mrdpRailView->context->channels, RailChannel_ClientActivate, &activate); -} - -@end - diff --git a/client/Mac/MRDPRailWindow.h b/client/Mac/MRDPRailWindow.h deleted file mode 100644 index 52f1c045a..000000000 --- a/client/Mac/MRDPRailWindow.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * MacFreeRDP - * - * Copyright 2012 Thomas Goddard - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import - -@interface MRDPRailWindow : NSWindow - -@end diff --git a/client/Mac/MRDPView.h b/client/Mac/MRDPView.h index c894cb939..96b6f2bd0 100644 --- a/client/Mac/MRDPView.h +++ b/client/Mac/MRDPView.h @@ -19,8 +19,12 @@ #import +#ifdef HAVE_RAIL #import "MRDPWindow.h" -#import "freerdp/freerdp.h" +#endif + +/* + #import "freerdp/freerdp.h" #import "freerdp/types.h" #import "freerdp/channels/channels.h" #import "freerdp/gdi/gdi.h" @@ -32,6 +36,9 @@ #import "freerdp/rail/rail.h" #import "freerdp/rail.h" #import "freerdp/utils/rail.h" +*/ + + @interface MRDPView : NSView { @@ -43,17 +50,20 @@ NSTimer* pasteboard_timer; NSRect prevWinPosition; int titleBarHeight; - freerdp* rdp_instance; - rdpContext* rdp_context; + void* rdp_instance; + void* rdp_context; CGContextRef bitmap_context; char* pixel_data; int width; int height; int argc; char** argv; - - /* RemoteApp */ + +#ifdef HAVE_RAIL + // RemoteApp MRDPWindow* currentWindow; +#endif + NSPoint savedDragLocation; BOOL mouseInClientArea; BOOL isRemoteApp; @@ -62,7 +72,7 @@ BOOL skipResizeOnce; BOOL saveInitialDragLoc; BOOL skipMoveWindowOnce; - + /* store state info for some keys */ int kdlshift; int kdrshift; @@ -83,9 +93,10 @@ int is_connected; } +- (int) rdpConnect; - (void) rdpConnectError; - (void) rdpRemoteAppError; -- (void) saveStateInfo :(freerdp *) instance :(rdpContext *) context; +- (void) saveStateInfo :(void *) instance :(void *) context; - (void) onPasteboardTimerFired :(NSTimer *) timer; - (void) releaseResources; - (void) setViewSize : (int) width : (int) height; @@ -103,79 +114,3 @@ #define PTR_FLAGS_BUTTON2 0x2000 #define PTR_FLAGS_BUTTON3 0x4000 #define WheelRotationMask 0x01FF - -void mf_Pointer_New(rdpContext* context, rdpPointer* pointer); -void mf_Pointer_Free(rdpContext* context, rdpPointer* pointer); -void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer); -void mf_Pointer_SetNull(rdpContext* context); -void mf_Pointer_SetDefault(rdpContext* context); -int rdp_connect(void); -BOOL mac_pre_connect(freerdp* instance); -BOOL mac_post_connect(freerdp* instance); -BOOL mac_authenticate(freerdp* instance, char** username, char** password, char** domain); -void mac_context_new(freerdp* instance, rdpContext* context); -void mac_context_free(freerdp* instance, rdpContext* context); -void mac_set_bounds(rdpContext* context, rdpBounds* bounds); -void mac_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap); -void mac_begin_paint(rdpContext* context); -void mac_end_paint(rdpContext* context); -void mac_save_state_info(freerdp* instance, rdpContext* context); -void skt_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void* data, void* info); -void channel_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void* data, void* info); -int register_fds(int* fds, int count, void* instance); -int invoke_draw_rect(rdpContext* context); -int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data); -int receive_channel_data(freerdp* instance, int chan_id, BYTE* data, int size, int flags, int total_size); -void process_cliprdr_event(freerdp* instance, wMessage* event); -void cliprdr_process_cb_format_list_event(freerdp* instance, RDP_CB_FORMAT_LIST_EVENT* event); -void cliprdr_send_data_request(freerdp* instance, UINT32 format); -void cliprdr_process_cb_monitor_ready_event(freerdp* inst); -void cliprdr_process_cb_data_response_event(freerdp* instance, RDP_CB_DATA_RESPONSE_EVENT* event); -void cliprdr_process_text(freerdp* instance, BYTE* data, int len); -void cliprdr_send_supported_format_list(freerdp* instance); -int register_channel_fds(int* fds, int count, void* instance); - -void mac_process_rail_event(freerdp* instance, wMessage* event); -void mac_rail_register_callbacks(freerdp* instance, rdpRail* rail); -void mac_rail_CreateWindow(rdpRail* rail, rdpWindow* window); -void mac_rail_MoveWindow(rdpRail* rail, rdpWindow* window); -void mac_rail_ShowWindow(rdpRail* rail, rdpWindow* window, BYTE state); -void mac_rail_SetWindowText(rdpRail* rail, rdpWindow* window); -void mac_rail_SetWindowIcon(rdpRail* rail, rdpWindow* window, rdpIcon* icon); -void mac_rail_SetWindowRects(rdpRail* rail, rdpWindow* window); -void mac_rail_SetWindowVisibilityRects(rdpRail* rail, rdpWindow* window); -void mac_rail_DestroyWindow(rdpRail* rail, rdpWindow* window); -void mac_process_rail_get_sysparams_event(rdpChannels* channels, wMessage* event); -void mac_send_rail_client_event(rdpChannels* channels, UINT16 event_type, void* param); -void mac_on_free_rail_client_event(wMessage* event); -void mac_process_rail_server_sysparam_event(rdpChannels* channels, wMessage* event); -void mac_process_rail_exec_result_event(rdpChannels* channels, wMessage* event); -void mac_rail_enable_remoteapp_mode(void); -void mac_process_rail_server_minmaxinfo_event(rdpChannels* channels, wMessage* event); -void mac_process_rail_server_localmovesize_event(freerdp* instance, wMessage* event); -void apple_center_window(NSRect* r); -void apple_to_windowMove(NSRect* r, RAIL_WINDOW_MOVE_ORDER * windowMove); - -struct mac_context -{ - // *must* have this - do not delete - rdpContext _p; -}; - -struct cursor -{ - rdpPointer* pointer; - BYTE* cursor_data; - void* bmiRep; /* NSBitmapImageRep */ - void* nsCursor; /* NSCursor */ - void* nsImage; /* NSImage */ -}; - -struct rgba_data -{ - char red; - char green; - char blue; - char alpha; -}; - diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index db30f5830..8548f01dd 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -51,9 +51,113 @@ #include +#import "freerdp/freerdp.h" +#import "freerdp/types.h" +#import "freerdp/channels/channels.h" +#import "freerdp/gdi/gdi.h" +#import "freerdp/graphics.h" +#import "freerdp/utils/event.h" +#import "freerdp/client/cliprdr.h" +#import "freerdp/client/file.h" +#import "freerdp/client/cmdline.h" +#import "freerdp/rail/rail.h" +#import "freerdp/rail.h" +#import "freerdp/utils/rail.h" + +#ifdef HAVE_RAIL +#import "MRDPWindow.h" +#endif + // RAIL_TODO DELETE WHEN DONE TESTING #define MRDP_DRAW_INDIVIDUAL_RECTS + + +/****************************************** + Forward declarations + ******************************************/ + + +void mf_Pointer_New(rdpContext* context, rdpPointer* pointer); +void mf_Pointer_Free(rdpContext* context, rdpPointer* pointer); +void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer); +void mf_Pointer_SetNull(rdpContext* context); +void mf_Pointer_SetDefault(rdpContext* context); +// int rdp_connect(void); +BOOL mac_pre_connect(freerdp* instance); +BOOL mac_post_connect(freerdp* instance); +BOOL mac_authenticate(freerdp* instance, char** username, char** password, char** domain); +void mac_context_new(freerdp* instance, rdpContext* context); +void mac_context_free(freerdp* instance, rdpContext* context); +void mac_set_bounds(rdpContext* context, rdpBounds* bounds); +void mac_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap); +void mac_begin_paint(rdpContext* context); +void mac_end_paint(rdpContext* context); +void mac_save_state_info(freerdp* instance, rdpContext* context); +void skt_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void* data, void* info); +void channel_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void* data, void* info); +int register_fds(int* fds, int count, void* instance); +int invoke_draw_rect(rdpContext* context); +int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data); +int receive_channel_data(freerdp* instance, int chan_id, BYTE* data, int size, int flags, int total_size); +void process_cliprdr_event(freerdp* instance, wMessage* event); +void cliprdr_process_cb_format_list_event(freerdp* instance, RDP_CB_FORMAT_LIST_EVENT* event); +void cliprdr_send_data_request(freerdp* instance, UINT32 format); +void cliprdr_process_cb_monitor_ready_event(freerdp* inst); +void cliprdr_process_cb_data_response_event(freerdp* instance, RDP_CB_DATA_RESPONSE_EVENT* event); +void cliprdr_process_text(freerdp* instance, BYTE* data, int len); +void cliprdr_send_supported_format_list(freerdp* instance); +int register_channel_fds(int* fds, int count, void* instance); + +void mac_process_rail_event(freerdp* instance, wMessage* event); +void mac_rail_register_callbacks(freerdp* instance, rdpRail* rail); +void mac_rail_CreateWindow(rdpRail* rail, rdpWindow* window); +void mac_rail_MoveWindow(rdpRail* rail, rdpWindow* window); +void mac_rail_ShowWindow(rdpRail* rail, rdpWindow* window, BYTE state); +void mac_rail_SetWindowText(rdpRail* rail, rdpWindow* window); +void mac_rail_SetWindowIcon(rdpRail* rail, rdpWindow* window, rdpIcon* icon); +void mac_rail_SetWindowRects(rdpRail* rail, rdpWindow* window); +void mac_rail_SetWindowVisibilityRects(rdpRail* rail, rdpWindow* window); +void mac_rail_DestroyWindow(rdpRail* rail, rdpWindow* window); +void mac_process_rail_get_sysparams_event(rdpChannels* channels, wMessage* event); +void mac_send_rail_client_event(rdpChannels* channels, UINT16 event_type, void* param); +void mac_on_free_rail_client_event(wMessage* event); +void mac_process_rail_server_sysparam_event(rdpChannels* channels, wMessage* event); +void mac_process_rail_exec_result_event(rdpChannels* channels, wMessage* event); +void mac_rail_enable_remoteapp_mode(void); +void mac_process_rail_server_minmaxinfo_event(rdpChannels* channels, wMessage* event); +void mac_process_rail_server_localmovesize_event(freerdp* instance, wMessage* event); +void apple_center_window(NSRect* r); +void apple_to_windowMove(NSRect* r, RAIL_WINDOW_MOVE_ORDER * windowMove); + +struct mac_context +{ + // *must* have this - do not delete + rdpContext _p; +}; + +struct cursor +{ + rdpPointer* pointer; + BYTE* cursor_data; + void* bmiRep; /* NSBitmapImageRep */ + void* nsCursor; /* NSCursor */ + void* nsImage; /* NSImage */ +}; + +struct rgba_data +{ + char red; + char green; + char blue; + char alpha; +}; + + + + + + @implementation MRDPView MRDPView *g_mrdpview; @@ -71,6 +175,41 @@ const char* error_code_names[] = "RAIL_EXEC_E_SESSION_LOCKED" }; +//int rdp_connect() +- (int) rdpConnect +{ + int status; + freerdp* instance; + + freerdp_channels_global_init(); + + instance = freerdp_new(); + instance->PreConnect = mac_pre_connect; + instance->PostConnect = mac_post_connect; + instance->context_size = sizeof(struct mac_context); + instance->ContextNew = mac_context_new; + instance->ContextFree = mac_context_free; + instance->ReceiveChannelData = receive_channel_data; + instance->Authenticate = mac_authenticate; + freerdp_context_new(instance); + + status = freerdp_connect(instance); + + if (status) + { + freerdp_check_fds(instance); + [g_mrdpview setIs_connected:1]; + return 0; + } + + [g_mrdpview setIs_connected:0]; + [g_mrdpview rdpConnectError]; + + return -1; +} + + + /************************************************************************ methods we override ************************************************************************/ @@ -108,16 +247,19 @@ const char* error_code_names[] = [[self window] setAcceptsMouseMovedEvents:YES]; cursors = [[NSMutableArray alloc] initWithCapacity:10]; - + +#ifdef HAVE_RAIL firstCreateWindow = TRUE; skipResizeOnce = YES; windows = [[NSMutableArray alloc] initWithCapacity:10]; - + +#endif + // setup a mouse tracking area NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil]; //[self addTrackingArea:trackingArea]; - + // windows in RemoteApp (RAIL) mode cannot have title bars NSArray * args = [[NSProcessInfo processInfo] arguments]; for (NSString * str in args) @@ -132,6 +274,7 @@ const char* error_code_names[] = [self addTrackingArea:trackingArea]; mouseInClientArea = YES; + } /** ********************************************************************* @@ -170,7 +313,7 @@ const char* error_code_names[] = y = height - y; // send mouse motion event to RDP server - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y); + ((freerdp*)rdp_instance)->input->MouseEvent(((freerdp*)rdp_instance)->input, PTR_FLAGS_MOVE, x, y); } /** ********************************************************************* @@ -190,7 +333,7 @@ const char* error_code_names[] = y = height - y; - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y); + ((freerdp*)rdp_instance)->input->MouseEvent(((freerdp*)rdp_instance)->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y); } /** ********************************************************************* @@ -210,7 +353,7 @@ const char* error_code_names[] = y = height - y; - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON1, x, y); + ((freerdp*)rdp_instance)->input->MouseEvent(((freerdp*)rdp_instance)->input, PTR_FLAGS_BUTTON1, x, y); } /** ********************************************************************* @@ -230,7 +373,7 @@ const char* error_code_names[] = y = height - y; - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y); + ((freerdp*)rdp_instance)->input->MouseEvent(((freerdp*)rdp_instance)->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y); } /** ********************************************************************* @@ -250,7 +393,7 @@ const char* error_code_names[] = y = height - y; - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON2, x, y); + ((freerdp*)rdp_instance)->input->MouseEvent(((freerdp*)rdp_instance)->input, PTR_FLAGS_BUTTON2, x, y); } /** ********************************************************************* @@ -270,7 +413,7 @@ const char* error_code_names[] = y = height - y; - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y); + ((freerdp*)rdp_instance)->input->MouseEvent(((freerdp*)rdp_instance)->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y); } /** ********************************************************************* @@ -290,7 +433,7 @@ const char* error_code_names[] = y = height - y; - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON3, x, y); + ((freerdp*)rdp_instance)->input->MouseEvent(((freerdp*)rdp_instance)->input, PTR_FLAGS_BUTTON3, x, y); } - (void) scrollWheel:(NSEvent *)event @@ -318,7 +461,7 @@ const char* error_code_names[] = x += (int) [event deltaX]; y += (int) [event deltaY]; - rdp_instance->input->MouseEvent(rdp_instance->input, flags, x, y); + ((freerdp*)rdp_instance)->input->MouseEvent(((freerdp*)rdp_instance)->input, flags, x, y); } /** ********************************************************************* @@ -337,6 +480,7 @@ const char* error_code_names[] = int x = (int) loc.x; int y = (int) loc.y; +#ifdef HAVE_RAIL // RAIL_TODO delete this if not reqd if ((isRemoteApp) && (isMoveSizeInProgress)) { @@ -356,11 +500,12 @@ const char* error_code_names[] = r.origin.y += newY; [[g_mrdpview window] setFrame:r display:YES]; } - +#endif + y = height - y; // send mouse motion event to RDP server - rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y); + ((freerdp*)rdp_instance)->input->MouseEvent(((freerdp*)rdp_instance)->input, PTR_FLAGS_MOVE, x, y); } /** ********************************************************************* @@ -383,7 +528,7 @@ const char* error_code_names[] = scancode = GetVirtualScanCodeFromVirtualKeyCode(vkcode, 4); extended = (scancode & KBDEXT) ? KBDEXT : 0; - rdp_instance->input->KeyboardEvent(rdp_instance->input, extended | KBD_FLAGS_DOWN, scancode & 0xFF); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, extended | KBD_FLAGS_DOWN, scancode & 0xFF); } /** ********************************************************************* @@ -406,7 +551,7 @@ const char* error_code_names[] = scancode = GetVirtualScanCodeFromVirtualKeyCode(vkcode, 4); extended = (scancode & KBDEXT) ? KBDEXT : 0; - rdp_instance->input->KeyboardEvent(rdp_instance->input, extended | KBD_FLAGS_RELEASE, scancode & 0xFF); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, extended | KBD_FLAGS_RELEASE, scancode & 0xFF); } /** ********************************************************************* @@ -432,96 +577,96 @@ const char* error_code_names[] = // left shift if ((kdlshift == 0) && ((mf & 2) != 0)) { // left shift went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x2a); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, KBD_FLAGS_DOWN, 0x2a); kdlshift = 1; } if ((kdlshift != 0) && ((mf & 2) == 0)) { // left shift went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x2a); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, KBD_FLAGS_RELEASE, 0x2a); kdlshift = 0; } // right shift if ((kdrshift == 0) && ((mf & 4) != 0)) { // right shift went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x36); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, KBD_FLAGS_DOWN, 0x36); kdrshift = 1; } if ((kdrshift != 0) && ((mf & 4) == 0)) { // right shift went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x36); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, KBD_FLAGS_RELEASE, 0x36); kdrshift = 0; } // left ctrl if ((kdlctrl == 0) && ((mf & 1) != 0)) { // left ctrl went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x1d); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, KBD_FLAGS_DOWN, 0x1d); kdlctrl = 1; } if ((kdlctrl != 0) && ((mf & 1) == 0)) { // left ctrl went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x1d); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, KBD_FLAGS_RELEASE, 0x1d); kdlctrl = 0; } // right ctrl if ((kdrctrl == 0) && ((mf & 0x2000) != 0)) { // right ctrl went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x1d); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, 1 | KBD_FLAGS_DOWN, 0x1d); kdrctrl = 1; } if ((kdrctrl != 0) && ((mf & 0x2000) == 0)) { // right ctrl went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x1d); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, 1 | KBD_FLAGS_RELEASE, 0x1d); kdrctrl = 0; } // left alt if ((kdlalt == 0) && ((mf & 0x20) != 0)) { // left alt went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x38); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, KBD_FLAGS_DOWN, 0x38); kdlalt = 1; } if ((kdlalt != 0) && ((mf & 0x20) == 0)) { // left alt went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x38); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, KBD_FLAGS_RELEASE, 0x38); kdlalt = 0; } // right alt if ((kdralt == 0) && ((mf & 0x40) != 0)) { // right alt went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x38); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, 1 | KBD_FLAGS_DOWN, 0x38); kdralt = 1; } if ((kdralt != 0) && ((mf & 0x40) == 0)) { // right alt went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x38); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, 1 | KBD_FLAGS_RELEASE, 0x38); kdralt = 0; } // left meta if ((kdlmeta == 0) && ((mf & 0x08) != 0)) { // left meta went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5b); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, 1 | KBD_FLAGS_DOWN, 0x5b); kdlmeta = 1; } if ((kdlmeta != 0) && ((mf & 0x08) == 0)) { // left meta went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5b); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, 1 | KBD_FLAGS_RELEASE, 0x5b); kdlmeta = 0; } // right meta if ((kdrmeta == 0) && ((mf & 0x10) != 0)) { // right meta went down - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5c); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, 1 | KBD_FLAGS_DOWN, 0x5c); kdrmeta = 1; } if ((kdrmeta != 0) && ((mf & 0x10) == 0)) { // right meta went up - rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5c); + ((freerdp*)rdp_instance)->input->KeyboardEvent(((freerdp*)rdp_instance)->input, 1 | KBD_FLAGS_RELEASE, 0x5c); kdrmeta = 0; } } @@ -536,12 +681,14 @@ const char* error_code_names[] = free(argv[i]); } +#ifdef HAVE_RAIL for (MRDPWindow * w in windows) { [w setWindow:nil]; [w setView:nil]; } - +#endif + if (!is_connected) return; @@ -566,9 +713,11 @@ const char* error_code_names[] = if (!rdp_context) return; +#ifdef HAVE_RAIL if (g_mrdpview->isRemoteApp && g_mrdpview->currentWindow) return; - +#endif + if(g_mrdpview->bitmap_context) { CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; @@ -595,7 +744,7 @@ const char* error_code_names[] = * save state info for use by other methods later on ***********************************************************************/ -- (void) saveStateInfo:(freerdp *) instance :(rdpContext *) context +- (void) saveStateInfo:(void *) instance :(void *) context { rdp_instance = instance; rdp_context = context; @@ -755,9 +904,11 @@ const char* error_code_names[] = [[g_mrdpview window] orderOut:g_mrdpview]; } +#ifdef HAVE_RAIL // RAIL_TODO is this func required - (void) windowDidResize:(NSNotification*) notification { + RAIL_WINDOW_MOVE_ORDER windowMove; printf("RAIL_TODO: MRDPView: windowDidResize() - not yet implemented\n"); @@ -786,8 +937,9 @@ const char* error_code_names[] = printf("----- LK_TODO: MRDPView:windowDidResize windowID=%d left=%d top=%d right=%d bottom=x%d width=%f height=%f\n", [currentWindow windowID], windowMove.left, windowMove.top, windowMove.right, windowMove.bottom, r.size.width, r.size.height); - //mac_send_rail_client_event(g_mrdpview->rdp_instance->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &windowMove); + //mac_send_rail_client_event(g_mrdpview->((freerdp*)rdp_instance)->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &windowMove); } +#endif /************************************************************************ * * @@ -801,37 +953,6 @@ const char* error_code_names[] = * @return 0 on success, -1 on failure ***********************************************************************/ -int rdp_connect() -{ - int status; - freerdp* instance; - - freerdp_channels_global_init(); - - instance = freerdp_new(); - instance->PreConnect = mac_pre_connect; - instance->PostConnect = mac_post_connect; - instance->context_size = sizeof(struct mac_context); - instance->ContextNew = mac_context_new; - instance->ContextFree = mac_context_free; - instance->ReceiveChannelData = receive_channel_data; - instance->Authenticate = mac_authenticate; - freerdp_context_new(instance); - - status = freerdp_connect(instance); - - if (status) - { - freerdp_check_fds(instance); - [g_mrdpview setIs_connected:1]; - return 0; - } - - [g_mrdpview setIs_connected:0]; - [g_mrdpview rdpConnectError]; - - return -1; -} /** ********************************************************************* * a callback given to freerdp_connect() to process the pre-connect operations. @@ -1038,12 +1159,14 @@ BOOL mac_post_connect(freerdp* instance) register_channel_fds(fds, rd_count, instance); freerdp_channels_post_connect(instance->context->channels, instance); - + +#ifdef HAVE_RAIL /* setup RemoteApp */ instance->context->rail = rail_new(instance->settings); rail_register_update_callbacks(instance->context->rail, instance->update); mac_rail_register_callbacks(instance, instance->context->rail); - +#endif + /* setup pasteboard (aka clipboard) for copy operations (write only) */ g_mrdpview->pasteboard_wr = [NSPasteboard generalPasteboard]; @@ -1281,14 +1404,16 @@ void mac_end_paint(rdpContext* context) if (context->gdi->drawing != context->gdi->primary) return; - gdi = g_mrdpview->rdp_context->gdi; + gdi = ((rdpContext*)g_mrdpview->rdp_context)->gdi; +#ifdef HAVE_RAIL if (g_mrdpview->isRemoteApp && g_mrdpview->currentWindow) { [[g_mrdpview->currentWindow view] updateDisplay]; return; } - +#endif + for (i = 0; i < gdi->primary->hdc->hwnd->ninvalid; i++) { drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x; @@ -1333,10 +1458,11 @@ void channel_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, { switch (GetMessageClass(event->id)) { +#ifdef HAVE_RAIL case RailChannel_Class: mac_process_rail_event(instance, event); break; - +#endif case CliprdrChannel_Class: process_cliprdr_event(instance, event); break; @@ -1617,6 +1743,9 @@ void cliprdr_send_supported_format_list(freerdp* instance) freerdp_channels_send_event(instance->context->channels, (wMessage*) event); } + +#ifdef HAVE_RAIL + /**************************************************************************************** * * * * @@ -1715,7 +1844,7 @@ void mac_rail_CreateWindow(rdpRail* rail, rdpWindow* window) RAIL_WINDOW_MOVE_ORDER windowMove; apple_to_windowMove(&winFrame, &windowMove); windowMove.windowId = window->windowId; - mac_send_rail_client_event(g_mrdpview->rdp_instance->context->channels, RailChannel_ClientWindowMove, &windowMove); + mac_send_rail_client_event(((freerdp*)g_mrdpview->rdp_instance)->context->channels, RailChannel_ClientWindowMove, &windowMove); } /* create MRDPRailView and add to above window */ @@ -2031,6 +2160,8 @@ void mac_rail_enable_remoteapp_mode() g_mrdpview->isRemoteApp = TRUE; } +#endif + /** * given a rect with 0,0 at the bottom left (apple cords) * convert it to a rect with 0,0 at the top left (windows cords) @@ -2057,6 +2188,7 @@ void apple_center_window(NSRect* r) r->origin.y = (g_mrdpview->height - r->size.height) / 2; } +#ifdef HAVE_RAIL void apple_to_windowMove(NSRect* r, RAIL_WINDOW_MOVE_ORDER* windowMove) { windowMove->left = (UINT16) r->origin.x; // x-cord of top left corner @@ -2064,5 +2196,7 @@ void apple_to_windowMove(NSRect* r, RAIL_WINDOW_MOVE_ORDER* windowMove) windowMove->right = (UINT16) (windowMove->left + r->size.width); // x-cord of bottom right corner windowMove->bottom = (UINT16) (windowMove->top + r->size.height); // y-cord of bottom right corner } +#endif + @end diff --git a/client/Mac/PasswordDialog.h b/client/Mac/PasswordDialog.h index d95783ab2..3e22de7dd 100644 --- a/client/Mac/PasswordDialog.h +++ b/client/Mac/PasswordDialog.h @@ -20,7 +20,15 @@ #import @interface PasswordDialog : NSWindowController - +{ +@public + NSTextField* usernameText; + NSTextField* passwordText; + NSTextField* messageLabel; + NSString* serverHostname; + NSString* username; + NSString* password; +} @property (retain) IBOutlet NSTextField* usernameText; @property (retain) IBOutlet NSTextField* passwordText; @property (retain) IBOutlet NSTextField* messageLabel; diff --git a/client/Mac/README.txt b/client/Mac/README.txt deleted file mode 100644 index 39fe93f73..000000000 --- a/client/Mac/README.txt +++ /dev/null @@ -1,140 +0,0 @@ - -------------------------------------------------------------------------- - Building FreeRDP on Mac OS X -------------------------------------------------------------------------- - -Platform: Lion with Xcode 4.3.2 - ------------------- - installing cmake ------------------- - -first install macports by googling for it, the run the following command -sudo port install cmake - ----------------- - installing gcc ----------------- -Click on Xcode->Preferences->Downloads -Click on Components -Click on Install Command line tools - -You will be prompted for your Apple Developer userid and password - ----------------------------------------- - download FreeRDP source code using git ----------------------------------------- - -mkdir ~/projects/A8 -cd ~/projects/A8 -git clone git://github.com/FreeRDP/FreeRDP.git - ------------------- - building FreeRDP ------------------- - -cd ~projects/A8/FreeRDP -cmake -DWITH_MACAUDIO=ON -DCMAKE_INSTALL_PREFIX="" -make -make install - ------------------------- - creating Xcode project ------------------------- - -Start xcode -Select 'Create a new xcode project' -In 'Choose a template for your new project', click on Mac OS X -> application -Click on 'Cocoa Application' -Click on next -I used the following: -Product Name: Mac -Company Identifier: com.freerdp -Check 'Automatic Reference Counting' -Create the project in your directory of choice - -------------------------------- - Adding files to your projects -------------------------------- - -Add the following files to your project: - -cd ~/projects/A8/FreeRDP/client/Mac/MRDPCursor.h -cd ~/projects/A8/FreeRDP/client/Mac/MRDPCursor.m -cd ~/projects/A8/FreeRDP/client/Mac/MRDPView.h -cd ~/projects/A8/FreeRDP/client/Mac/MRDPView.m - -This is what your AppDelegate.h file should like like - -#import -#import "MRDPView.h" - -@interface AppDelegate : NSObject - -@property (assign) IBOutlet NSWindow *window; -@property (assign) IBOutlet MRDPView *mrdpView; - -int rdp_connect(); - -@end - -This is what your AppDelegate.m file should like like - -#import "AppDelegate.h" - -@implementation AppDelegate - -@synthesize window = _window; -@synthesize mrdpView; - -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification -{ - rdp_connect(); -} - -- (void) applicationWillTerminate:(NSNotification *)notification -{ - [mrdpView releaseResources]; -} - -@end - ----------------------------------- - Modifying your MainMenu.xib file ----------------------------------- - -In your project select MainMenu.xib and drag a NSView object into the main window -Name the class MRDPView -In Interface Builder, select the Application Delegate and tie the mrdpview outlet to the NSView -Set the default size of the main window to 1024x768. This is FreeRDP's default resolution - ----------------------------- - Configuring build settings ----------------------------- - -In Project Navigator, click on Mac -Click on Targets -> Mac -Click on Build Phases -Click on 'Link Binary With Libraries' and click on the + button, then click on the 'Add Other' button to add the following dynamic libraries -~/projects/A8/FreeRDP/libfreerdp-core/libfreerdp-core.dylib -~/projects/A8/FreeRDP/libfreerdp-channels/libfreerdp-channels.dylilb -~/projects/A8/FreeRDP/libfreerdp-utils/libfreerdp-utils.dylib -~/projects/A8/FreeRDP/libfreerdp-codec/libfreerdp-codec.dylib -~/projects/A8/FreeRDP/libfreerdp-cache/libfreerdp-cache.dylib -~/projects/A8/FreeRDP/libfreerdp-gdi/libfreerdp-gdi.dylib - -Click on 'Build Settings' -In 'Search Paths -> Library Search Paths' set the following - Header Search Path Debug: ~/projects/A8/FreeRDP/include - Header Search Path Release: ~/projects/A8/FreeRDP/include - -TODO: in build settings, set strip build product to yes when done debugging - ---------------------------- - To deploy the application ---------------------------- - -in xcode, click on Product->Archive -Click on Distribute button -Select Export As -> application - diff --git a/client/Mac/cli/AppDelegate.h b/client/Mac/cli/AppDelegate.h new file mode 100644 index 000000000..b24cbeeab --- /dev/null +++ b/client/Mac/cli/AppDelegate.h @@ -0,0 +1,22 @@ +// +// AppDelegate.h +// MacClient2 +// +// Created by Benoît et Kathy on 2013-05-08. +// +// + +#import +#import + +@interface AppDelegate : NSObject +{ +@public + NSWindow* window; + MRDPView* mrdpView; +} + +@property (assign) IBOutlet NSWindow *window; +@property (assign) IBOutlet MRDPView *mrdpView; + +@end diff --git a/client/Mac/cli/AppDelegate.m b/client/Mac/cli/AppDelegate.m new file mode 100644 index 000000000..8fca18cb7 --- /dev/null +++ b/client/Mac/cli/AppDelegate.m @@ -0,0 +1,32 @@ +// +// AppDelegate.m +// MacClient2 +// +// Created by Benoît et Kathy on 2013-05-08. +// +// + +#import "AppDelegate.h" + +@implementation AppDelegate + +- (void)dealloc +{ + [super dealloc]; +} + +@synthesize window = window; + +@synthesize mrdpView = mrdpView; + +- (void)applicationDidFinishLaunching:(NSNotification*)aNotification +{ + [mrdpView rdpConnect]; +} + +- (void) applicationWillTerminate:(NSNotification*)notification +{ + [mrdpView releaseResources]; +} + +@end diff --git a/client/Mac/cli/CMakeLists.txt b/client/Mac/cli/CMakeLists.txt new file mode 100644 index 000000000..789bd5cde --- /dev/null +++ b/client/Mac/cli/CMakeLists.txt @@ -0,0 +1,127 @@ +project(MacFreeRDP-client) + +set(MODULE_NAME "MacFreeRDP-client") +set(MODULE_PREFIX "FREERDP_CLIENT_MAC_CLIENT") +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.4") + +# Import libraries +find_library(FOUNDATION_LIBRARY Foundation) +find_library(COCOA_LIBRARY Cocoa) +find_library(APPKIT_LIBRARY AppKit) +find_library(FREERDP_LIBRARY NAMES MacFreeRDP-library PATHS ${CMAKE_CURRENT_BINARY_DIR}/../${CONFIGURATION}) + +set(MACOSX_BUNDLE_INFO_STRING "MacFreeRDP-client") +set(MACOSX_BUNDLE_ICON_FILE "FreeRDP.icns") +set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.freerdp.mac") +set(MACOSX_BUNDLE_BUNDLE_IDENTIFIER "FreeRDP-client.Mac") +set(MACOSX_BUNDLE_LONG_VERSION_STRING "MacFreeRDP Client Version 1.1.0") +set(MACOSX_BUNDLE_BUNDLE_NAME "MacFreeRDP") +set(MACOSX_BUNDLE_SHORT_VERSION_STRING 1.1.0) +set(MACOSX_BUNDLE_BUNDLE_VERSION 1.1.0) +set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2012. All Rights Reserved.") + +set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "MainMenu") +set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication") + +mark_as_advanced(COCOA_LIBRARY FOUNDATION_LIBRARY APPKIT_LIBRARY) +set(APP_TYPE MACOSX_BUNDLE) + +# OS X Interface Builder files +file(GLOB ${MODULE_NAME}_XIBS *.xib) + +set(${MODULE_NAME}_RESOURCES ${MACOSX_BUNDLE_ICON_FILE}) + +# Include XIB file in Xcode resources. +if("${CMAKE_GENERATOR}" MATCHES "Xcode") + message(STATUS "Adding Xcode XIB resources for ${MODULE_NAME}") + set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_RESOURCES} ${${MODULE_NAME}_XIBS}) +endif("${CMAKE_GENERATOR}" MATCHES "Xcode") + +# Headers +file(GLOB ${MODULE_NAME}_HEADERS *.h) + +# Source +file(GLOB ${MODULE_NAME}_SOURCES *.m) + +add_executable(${MODULE_NAME} + ${APP_TYPE} + ${${MODULE_NAME}_HEADERS} + ${${MODULE_NAME}_SOURCES} + ${${MODULE_NAME}_RESOURCES}) + +# This is necessary for the xib file part below +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) + +# This allows for automatic xib to nib ibitool +set_target_properties(${MODULE_NAME} PROPERTIES RESOURCE "${${MODULE_NAME}_RESOURCES}") + +# Automatic ref counting +# temporary turn off for x86_64 build issue +# set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES) + +# Support for automatic reference counting requires non-fragile abi. +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -v -fobjc-nonfragile-abi") + +# Tell the compiler where to look for the FreeRDP framework +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v -F../") + +# Tell XCode where to look for the MacFreeRDP-library framework +set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS + "${XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS} ${CMAKE_CURRENT_BINARY_DIR}/../$(CONFIGURATION)") + + +# XCode project architecture to native architecture of build machine +# ----------------------------------------------------------------------------------------------------- +# Issue: Had some issues with FreeRDP project building only 64 bit and +# MacFreeRDP attempting to link to both 32 and 64 for dual target. +# In the future the FreeRDP Xcode project should be pulled in for a couple of reasons: +# 1) better step-into debugging 2) automatic dependency compilation and multi-arch compilation + linkage +# If you know the solutions for 1 and 2, please add below. +set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)") + +# Set the info plist to the custom instance +set_target_properties(${MODULE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) + +# Disable transitive linking +# ${FREERDP_LIBRARY} +target_link_libraries(${MODULE_NAME} ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY} MacFreeRDP-library) + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Mac") + +# Embed the FreeRDP framework into the app bundle +add_custom_command(TARGET ${MODULE_NAME} POST_BUILD + COMMAND mkdir ARGS -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Frameworks + COMMAND ditto ${CMAKE_CURRENT_BINARY_DIR}/../$(CONFIGURATION)/MacFreeRDP-library.framework ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Frameworks/MacFreeRDP-library.framework + COMMAND install_name_tool -change "@executable_path/../../Frameworks/MacFreeRDP-library.framework/Versions/1.1.0/MacFreeRDP-library" "@executable_path/../Frameworks/MacFreeRDP-library.framework/Versions/Current/MacFreeRDP-library" "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/MacOS/${MODULE_NAME}" + COMMENT Setting install name for MacFreeRDP-library + + ) + + +# Add post-build NIB file generation in unix makefiles. XCode handles this implicitly. +if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") + message(STATUS "Adding post-build NIB file generation event for ${MODULE_NAME}") + + # Make sure we can find the 'ibtool' program. If we can NOT find it we + # skip generation of this project + find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin") + if (${IBTOOL} STREQUAL "IBTOOL-NOTFOUND") + message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with + the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin") + endif() + + # Make sure the 'Resources' Directory is correctly created before we build + add_custom_command (TARGET ${MODULE_NAME} PRE_BUILD + COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources) + + # Compile the .xib files using the 'ibtool' program with the destination being the app package + foreach(xib ${${MODULE_NAME}_XIBS}) + get_filename_component(XIB_WE ${xib} NAME_WE) + + add_custom_command (TARGET ${MODULE_NAME} POST_BUILD + COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text + --compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources/${XIB_WE}.nib ${xib} + COMMENT "Compiling ${xib}") + endforeach() + +endif("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") \ No newline at end of file diff --git a/client/Mac/FreeRDP.icns b/client/Mac/cli/FreeRDP.icns similarity index 100% rename from client/Mac/FreeRDP.icns rename to client/Mac/cli/FreeRDP.icns diff --git a/client/Mac/cli/Info.plist b/client/Mac/cli/Info.plist new file mode 100644 index 000000000..cb6976502 --- /dev/null +++ b/client/Mac/cli/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + + CFBundleIconFile + FreeRDP + CFBundleIdentifier + FreeRDP.Mac + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + + NSHumanReadableCopyright + Copyright © 2012 __MyCompanyName__. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/client/Mac/cli/MacClient2-Info.plist b/client/Mac/cli/MacClient2-Info.plist new file mode 100644 index 000000000..6efd7bddc --- /dev/null +++ b/client/Mac/cli/MacClient2-Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + awakecoding.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + ${MACOSX_DEPLOYMENT_TARGET} + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/client/Mac/cli/MacClient2-Prefix.pch b/client/Mac/cli/MacClient2-Prefix.pch new file mode 100644 index 000000000..f81d50593 --- /dev/null +++ b/client/Mac/cli/MacClient2-Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'MacClient2' target in the 'MacClient2' project +// + +#ifdef __OBJC__ + #import +#endif diff --git a/client/Mac/MainMenu.xib b/client/Mac/cli/MainMenu.xib similarity index 98% rename from client/Mac/MainMenu.xib rename to client/Mac/cli/MainMenu.xib index e535cbe12..90e992462 100755 --- a/client/Mac/MainMenu.xib +++ b/client/Mac/cli/MainMenu.xib @@ -2,10 +2,10 @@ 1070 - 12C60 + 12D78 3084 - 1187.34 - 625.00 + 1187.37 + 626.00 com.apple.InterfaceBuilder.CocoaPlugin 3084 @@ -375,7 +375,7 @@ - 565 + 569 @@ -383,7 +383,7 @@ - 567 + 570 @@ -736,7 +736,7 @@ - 568 + 570 @@ -770,6 +770,14 @@ ./Classes/MRDPView.h + + NSLayoutConstraint + NSObject + + IBProjectSource + ./Classes/NSLayoutConstraint.h + + 0 diff --git a/client/Mac/cli/en.lproj/Credits.rtf b/client/Mac/cli/en.lproj/Credits.rtf new file mode 100644 index 000000000..46576ef21 --- /dev/null +++ b/client/Mac/cli/en.lproj/Credits.rtf @@ -0,0 +1,29 @@ +{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} +{\colortbl;\red255\green255\blue255;} +\paperw9840\paperh8400 +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\b\fs24 \cf0 Engineering: +\b0 \ + Some people\ +\ + +\b Human Interface Design: +\b0 \ + Some other people\ +\ + +\b Testing: +\b0 \ + Hopefully not nobody\ +\ + +\b Documentation: +\b0 \ + Whoever\ +\ + +\b With special thanks to: +\b0 \ + Mom\ +} diff --git a/client/Mac/cli/en.lproj/InfoPlist.strings b/client/Mac/cli/en.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/client/Mac/cli/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/client/Mac/cli/en.lproj/MainMenu.xib b/client/Mac/cli/en.lproj/MainMenu.xib new file mode 100644 index 000000000..dd4e1905e --- /dev/null +++ b/client/Mac/cli/en.lproj/MainMenu.xib @@ -0,0 +1,3299 @@ + + + + 1080 + 12D78 + 3084 + 1187.37 + 626.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 3084 + + + IBNSLayoutConstraint + NSCustomObject + NSCustomView + NSMenu + NSMenuItem + NSView + NSWindowTemplate + + + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + + + MacClient2 + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + MacClient2 + + + + About MacClient2 + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Preferences… + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide MacClient2 + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit MacClient2 + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + File + + + + New + n + 1048576 + 2147483647 + + + + + + Open… + o + 1048576 + 2147483647 + + + + + + Open Recent + + 1048576 + 2147483647 + + + submenuAction: + + Open Recent + + + + Clear Menu + + 1048576 + 2147483647 + + + + + _NSRecentDocumentsMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + Save… + s + 1048576 + 2147483647 + + + + + + Revert to Saved + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup... + P + 1179648 + 2147483647 + + + + + + + Print… + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + Edit + + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Paste and Match Style + V + 1572864 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + Find + + + + Find… + f + 1048576 + 2147483647 + + + 1 + + + + Find and Replace… + f + 1572864 + 2147483647 + + + 12 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + Spelling and Grammar + + + + Show Spelling and Grammar + : + 1048576 + 2147483647 + + + + + + Check Document Now + ; + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + Correct Spelling Automatically + + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + Substitutions + + + + Show Substitutions + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Dashes + + 2147483647 + + + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + Text Replacement + + 2147483647 + + + + + + + + + Transformations + + 2147483647 + + + submenuAction: + + Transformations + + + + Make Upper Case + + 2147483647 + + + + + + Make Lower Case + + 2147483647 + + + + + + Capitalize + + 2147483647 + + + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + Speech + + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Format + + 2147483647 + + + submenuAction: + + Format + + + + Font + + 2147483647 + + + submenuAction: + + Font + + + + Show Fonts + t + 1048576 + 2147483647 + + + + + + Bold + b + 1048576 + 2147483647 + + + 2 + + + + Italic + i + 1048576 + 2147483647 + + + 1 + + + + Underline + u + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Bigger + + + 1048576 + 2147483647 + + + 3 + + + + Smaller + - + 1048576 + 2147483647 + + + 4 + + + + YES + YES + + + 2147483647 + + + + + + Kern + + 2147483647 + + + submenuAction: + + Kern + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Tighten + + 2147483647 + + + + + + Loosen + + 2147483647 + + + + + + + + + Ligatures + + 2147483647 + + + submenuAction: + + Ligatures + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Use All + + 2147483647 + + + + + + + + + Baseline + + 2147483647 + + + submenuAction: + + Baseline + + + + Use Default + + 2147483647 + + + + + + Superscript + + 2147483647 + + + + + + Subscript + + 2147483647 + + + + + + Raise + + 2147483647 + + + + + + Lower + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Colors + C + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Copy Style + c + 1572864 + 2147483647 + + + + + + Paste Style + v + 1572864 + 2147483647 + + + + + _NSFontMenu + + + + + Text + + 2147483647 + + + submenuAction: + + Text + + + + Align Left + { + 1048576 + 2147483647 + + + + + + Center + | + 1048576 + 2147483647 + + + + + + Justify + + 2147483647 + + + + + + Align Right + } + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Writing Direction + + 2147483647 + + + submenuAction: + + Writing Direction + + + + YES + Paragraph + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + YES + Selection + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Ruler + + 2147483647 + + + + + + Copy Ruler + c + 1310720 + 2147483647 + + + + + + Paste Ruler + v + 1310720 + 2147483647 + + + + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + View + + + + Show Toolbar + t + 1572864 + 2147483647 + + + + + + Customize Toolbar… + + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 2147483647 + + + submenuAction: + + Help + + + + MacClient2 Help + ? + 1048576 + 2147483647 + + + + + _NSHelpMenu + + + + _NSMainMenu + + + 15 + 2 + {{335, 390}, {480, 360}} + 1954021376 + MacClient2 + NSWindow + + + + + 256 + + + + 268 + {480, 360} + + _NS:9 + MRDPView + + + {480, 360} + + + + {{0, 0}, {1440, 878}} + {10000000000000, 10000000000000} + YES + + + AppDelegate + + + NSFontManager + + + + + + + terminate: + + + + 449 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + delegate + + + + 495 + + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + clearRecentDocuments: + + + + 127 + + + + performClose: + + + + 193 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + saveDocument: + + + + 362 + + + + revertDocumentToSaved: + + + + 364 + + + + runToolbarCustomizationPalette: + + + + 365 + + + + toggleToolbarShown: + + + + 366 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + newDocument: + + + + 373 + + + + openDocument: + + + + 374 + + + + raiseBaseline: + + + + 426 + + + + lowerBaseline: + + + + 427 + + + + copyFont: + + + + 428 + + + + subscript: + + + + 429 + + + + superscript: + + + + 430 + + + + tightenKerning: + + + + 431 + + + + underline: + + + + 432 + + + + orderFrontColorPanel: + + + + 433 + + + + useAllLigatures: + + + + 434 + + + + loosenKerning: + + + + 435 + + + + pasteFont: + + + + 436 + + + + unscript: + + + + 437 + + + + useStandardKerning: + + + + 438 + + + + useStandardLigatures: + + + + 439 + + + + turnOffLigatures: + + + + 440 + + + + turnOffKerning: + + + + 441 + + + + toggleAutomaticSpellingCorrection: + + + + 456 + + + + orderFrontSubstitutionsPanel: + + + + 458 + + + + toggleAutomaticDashSubstitution: + + + + 461 + + + + toggleAutomaticTextReplacement: + + + + 463 + + + + uppercaseWord: + + + + 464 + + + + capitalizeWord: + + + + 467 + + + + lowercaseWord: + + + + 468 + + + + pasteAsPlainText: + + + + 486 + + + + performFindPanelAction: + + + + 487 + + + + performFindPanelAction: + + + + 488 + + + + performFindPanelAction: + + + + 489 + + + + showHelp: + + + + 493 + + + + alignCenter: + + + + 518 + + + + pasteRuler: + + + + 519 + + + + toggleRuler: + + + + 520 + + + + alignRight: + + + + 521 + + + + copyRuler: + + + + 522 + + + + alignJustified: + + + + 523 + + + + alignLeft: + + + + 524 + + + + makeBaseWritingDirectionNatural: + + + + 525 + + + + makeBaseWritingDirectionLeftToRight: + + + + 526 + + + + makeBaseWritingDirectionRightToLeft: + + + + 527 + + + + makeTextWritingDirectionNatural: + + + + 528 + + + + makeTextWritingDirectionLeftToRight: + + + + 529 + + + + makeTextWritingDirectionRightToLeft: + + + + 530 + + + + performFindPanelAction: + + + + 535 + + + + addFontTrait: + + + + 421 + + + + addFontTrait: + + + + 422 + + + + modifyFont: + + + + 423 + + + + orderFrontFontPanel: + + + + 424 + + + + modifyFont: + + + + 425 + + + + mrdpView + + + + 549 + + + + window + + + + 550 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + + + + + + + + + + + + 19 + + + + + + + + 56 + + + + + + + + 217 + + + + + + + + 83 + + + + + + + + 81 + + + + + + + + + + + + + + + + + 75 + + + + + 78 + + + + + 72 + + + + + 82 + + + + + 124 + + + + + + + + 77 + + + + + 73 + + + + + 79 + + + + + 112 + + + + + 74 + + + + + 125 + + + + + + + + 126 + + + + + 205 + + + + + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + + + + + + 216 + + + + + + + + 200 + + + + + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 57 + + + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + + + 144 + + + + + 129 + + + + + 143 + + + + + 236 + + + + + 131 + + + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + + + + + + 296 + + + + + + + + + 297 + + + + + 298 + + + + + 211 + + + + + + + + 212 + + + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + + + + + + 349 + + + + + + + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 371 + + + + + + + + 372 + + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + 4 + 0 + + 4 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 3 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + + + + 375 + + + + + + + + 376 + + + + + + + + + 377 + + + + + + + + 388 + + + + + + + + + + + + + + + + + + + + + + + 389 + + + + + 390 + + + + + 391 + + + + + 392 + + + + + 393 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + + + + + + 398 + + + + + + + + 399 + + + + + + + + 400 + + + + + 401 + + + + + 402 + + + + + 403 + + + + + 404 + + + + + 405 + + + + + + + + + + + + 406 + + + + + 407 + + + + + 408 + + + + + 409 + + + + + 410 + + + + + 411 + + + + + + + + + + 412 + + + + + 413 + + + + + 414 + + + + + 415 + + + + + + + + + + + 416 + + + + + 417 + + + + + 418 + + + + + 419 + + + + + 420 + + + + + 450 + + + + + + + + 451 + + + + + + + + + + 452 + + + + + 453 + + + + + 454 + + + + + 457 + + + + + 459 + + + + + 460 + + + + + 462 + + + + + 465 + + + + + 466 + + + + + 485 + + + + + 490 + + + + + + + + 491 + + + + + + + + 492 + + + + + 494 + + + + + 496 + + + + + + + + 497 + + + + + + + + + + + + + + + + + 498 + + + + + 499 + + + + + 500 + + + + + 501 + + + + + 502 + + + + + 503 + + + + + + + + 504 + + + + + 505 + + + + + 506 + + + + + 507 + + + + + 508 + + + + + + + + + + + + + + + + 509 + + + + + 510 + + + + + 511 + + + + + 512 + + + + + 513 + + + + + 514 + + + + + 515 + + + + + 516 + + + + + 517 + + + + + 534 + + + + + 536 + + + + + 542 + + + + + 544 + + + + + 545 + + + + + 546 + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{380, 496}, {480, 360}} + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 550 + + + 0 + IBCocoaFramework + YES + 3 + + {11, 11} + {10, 3} + + YES + + diff --git a/client/Mac/cli/main.m b/client/Mac/cli/main.m new file mode 100644 index 000000000..b1ed1e5f4 --- /dev/null +++ b/client/Mac/cli/main.m @@ -0,0 +1,16 @@ +// +// main.m +// MacClient2 +// +// Created by Benoît et Kathy on 2013-05-08. +// +// + +#import +#import + +int main(int argc, char *argv[]) +{ + [MRDPView class]; + return NSApplicationMain(argc, (const char **)argv); +} diff --git a/client/Mac/en.lproj/InfoPlist.strings b/client/Mac/en.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/client/Mac/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/client/Windows/wf_interface.c b/client/Windows/wf_interface.c index 0eeb0d61f..4cac2a003 100644 --- a/client/Windows/wf_interface.c +++ b/client/Windows/wf_interface.c @@ -920,6 +920,21 @@ int freerdp_client_stop(wfInfo* wfi) return 0; } +HANDLE freerdp_client_get_thread(wfInfo* cfi) +{ + return cfi->thread; +} + +freerdp* freerdp_client_get_instance(wfInfo* cfi) +{ + return cfi->instance; +} + +rdpClient* freerdp_client_get_interface(wfInfo* cfi) +{ + return cfi->client; +} + int freerdp_client_focus_in(wfInfo* wfi) { PostThreadMessage(wfi->mainThreadId, WM_SETFOCUS, 0, 1); @@ -1172,4 +1187,4 @@ void wf_size_scrollbars(wfInfo* wfi, int client_width, int client_height) wfi->disablewindowtracking = FALSE; wf_update_canvas_diff(wfi); -} \ No newline at end of file +} diff --git a/client/Windows/wf_interface.h b/client/Windows/wf_interface.h index accf9632a..669e606f2 100644 --- a/client/Windows/wf_interface.h +++ b/client/Windows/wf_interface.h @@ -165,6 +165,10 @@ FREERDP_API int freerdp_client_global_uninit(); FREERDP_API int freerdp_client_start(wfInfo* cfi); FREERDP_API int freerdp_client_stop(wfInfo* cfi); +FREERDP_API HANDLE freerdp_client_get_thread(wfInfo* cfi); +FREERDP_API freerdp* freerdp_client_get_instance(wfInfo* cfi); +FREERDP_API rdpClient* freerdp_client_get_interface(wfInfo* cfi); + FREERDP_API int freerdp_client_focus_in(wfInfo* cfi); FREERDP_API int freerdp_client_focus_out(wfInfo* cfi); diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index 7d08ea670..f1d8ba08f 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -30,6 +30,10 @@ set(${MODULE_PREFIX}_SRCS xf_tsmf.h xf_event.c xf_event.h + xf_input.c + xf_input.h + xf_channels.c + xf_channels.h xf_cliprdr.c xf_cliprdr.h xf_monitor.c @@ -53,6 +57,7 @@ if(WITH_CLIENT_INTERFACE) else() set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/xfreerdp.c cli/xfreerdp.h) add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp") endif() set(${MODULE_PREFIX}_LIBS @@ -94,11 +99,21 @@ set(XV_FEATURE_TYPE "RECOMMENDED") set(XV_FEATURE_PURPOSE "video") set(XV_FEATURE_DESCRIPTION "X11 video extension") +set(XI_FEATURE_TYPE "RECOMMENDED") +set(XI_FEATURE_PURPOSE "input") +set(XI_FEATURE_DESCRIPTION "X11 input extension") + +set(XRENDER_FEATURE_TYPE "RECOMMENDED") +set(XRENDER_FEATURE_PURPOSE "rendering") +set(XRENDER_FEATURE_DESCRIPTION "X11 render extension") + find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION}) find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION}) find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DESCRIPTION}) find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSOR_FEATURE_DESCRIPTION}) find_feature(Xv ${XV_FEATURE_TYPE} ${XV_FEATURE_PURPOSE} ${XV_FEATURE_DESCRIPTION}) +find_feature(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_FEATURE_DESCRIPTION}) +find_feature(Xrender ${XRENDER_FEATURE_TYPE} ${XRENDER_FEATURE_PURPOSE} ${XRENDER_FEATURE_DESCRIPTION}) if(WITH_XINERAMA) add_definitions(-DWITH_XINERAMA) @@ -124,6 +139,18 @@ if(WITH_XV) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XV_LIBRARIES}) endif() +if(WITH_XI) + add_definitions(-DWITH_XI) + include_directories(${XI_INCLUDE_DIRS}) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XI_LIBRARIES}) +endif() + +if(WITH_XRENDER) + add_definitions(-DWITH_XRENDER) + include_directories(${XRENDER_INCLUDE_DIRS}) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRENDER_LIBRARIES}) +endif() + include_directories(${CMAKE_SOURCE_DIR}/resources) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client) @@ -135,7 +162,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHI target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) if(WITH_IPP) - target_link_libraries(xfreerdp ${IPP_LIBRARY_LIST}) + target_link_libraries(${MODULE_NAME} ${IPP_LIBRARY_LIST}) endif() if(WITH_CLIENT_INTERFACE) diff --git a/client/X11/cli/CMakeLists.txt b/client/X11/cli/CMakeLists.txt index b4d27b5d7..ccd38e1d1 100644 --- a/client/X11/cli/CMakeLists.txt +++ b/client/X11/cli/CMakeLists.txt @@ -15,16 +15,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(MODULE_NAME "xfreerdp") +set(MODULE_NAME "xfreerdp-cli") set(MODULE_PREFIX "FREERDP_CLIENT_X11") include_directories(..) set(${MODULE_PREFIX}_SRCS - xfreerdp.c - xfreerdp.h) + xfreerdp.c) add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp" RUNTIME_OUTPUT_DIRECTORY "..") set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} xfreerdp-client) diff --git a/client/X11/cli/xfreerdp.c b/client/X11/cli/xfreerdp.c index b242c11ee..0fa20b98b 100644 --- a/client/X11/cli/xfreerdp.c +++ b/client/X11/cli/xfreerdp.c @@ -41,6 +41,12 @@ int main(int argc, char* argv[]) freerdp_client_global_init(); xfi = freerdp_client_new(argc, argv); + + if (xfi == NULL) + { + return 1; + } + instance = xfi->instance; freerdp_client_start(xfi); @@ -49,8 +55,7 @@ int main(int argc, char* argv[]) GetExitCodeThread(xfi->thread, &dwExitCode); - freerdp_context_free(instance); - freerdp_free(instance); + freerdp_client_free(xfi); freerdp_client_global_uninit(); diff --git a/client/X11/xf_channels.c b/client/X11/xf_channels.c new file mode 100644 index 000000000..84a70b106 --- /dev/null +++ b/client/X11/xf_channels.c @@ -0,0 +1,44 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * X11 Client Channels + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf_channels.h" + +#include "xf_interface.h" +#include "xfreerdp.h" + +int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface) +{ + xfInfo* xfi = ((xfContext*) instance->context)->xfi; + + if (strcmp(name, RDPEI_DVC_CHANNEL_NAME) == 0) + { + xfi->rdpei = (RdpeiClientContext*) pInterface; + } + + return 0; +} + +int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface) +{ + return 0; +} diff --git a/client/Mac/MRDPWindow.h b/client/X11/xf_channels.h similarity index 60% rename from client/Mac/MRDPWindow.h rename to client/X11/xf_channels.h index 0e7e26b97..1aeaf1a66 100644 --- a/client/Mac/MRDPWindow.h +++ b/client/X11/xf_channels.h @@ -1,8 +1,8 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * MacFreeRDP + * X11 Client Channels * - * Copyright 2012 Thomas Goddard + * Copyright 2013 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,17 +17,14 @@ * limitations under the License. */ -#import -#import "MRDPRailView.h" -#import "MRDPRailWindow.h" +#ifndef __XF_CHANNELS_H +#define __XF_CHANNELS_H -@interface MRDPWindow : NSObject -{ -} +#include +#include +#include -@property (assign) int windowID; -@property (retain) MRDPRailWindow* window; -@property (retain) MRDPRailView* view; - -@end +int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface); +int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface); +#endif diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index c2acee2ac..d7e0e44f1 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -30,6 +30,7 @@ #include #include +#include #include "xf_cliprdr.h" @@ -89,7 +90,7 @@ struct clipboard_context int incr_data_length; }; -void xf_cliprdr_init(xfInfo* xfi, rdpChannels* chanman) +void xf_cliprdr_init(xfInfo* xfi, rdpChannels* channels) { int n; UINT32 id; @@ -100,7 +101,7 @@ void xf_cliprdr_init(xfInfo* xfi, rdpChannels* chanman) xfi->clipboard_context = cb; - cb->channels = chanman; + cb->channels = channels; cb->request_index = -1; cb->root_window = DefaultRootWindow(xfi->display); @@ -928,29 +929,26 @@ static void xf_cliprdr_process_dib(clipboardContext* cb, BYTE* data, int size) return; } - s = stream_new(0); - stream_attach(s, data, size); - stream_seek(s, 14); - stream_read_UINT16(s, bpp); - stream_read_UINT32(s, ncolors); + s = Stream_New(data, size); + Stream_Seek(s, 14); + Stream_Read_UINT16(s, bpp); + Stream_Read_UINT32(s, ncolors); offset = 14 + 40 + (bpp <= 8 ? (ncolors == 0 ? (1 << bpp) : ncolors) * 4 : 0); - stream_detach(s); - stream_free(s); + Stream_Free(s, FALSE); DEBUG_X11_CLIPRDR("offset=%d bpp=%d ncolors=%d", offset, bpp, ncolors); - s = stream_new(14 + size); - stream_write_BYTE(s, 'B'); - stream_write_BYTE(s, 'M'); - stream_write_UINT32(s, 14 + size); - stream_write_UINT32(s, 0); - stream_write_UINT32(s, offset); - stream_write(s, data, size); + s = Stream_New(NULL, 14 + size); + Stream_Write_UINT8(s, 'B'); + Stream_Write_UINT8(s, 'M'); + Stream_Write_UINT32(s, 14 + size); + Stream_Write_UINT32(s, 0); + Stream_Write_UINT32(s, offset); + Stream_Write(s, data, size); - cb->data = stream_get_head(s); - cb->data_length = stream_get_length(s); - stream_detach(s); - stream_free(s); + cb->data = Stream_Buffer(s); + cb->data_length = Stream_GetPosition(s); + Stream_Free(s, FALSE); } static void xf_cliprdr_process_html(clipboardContext* cb, BYTE* data, int size) diff --git a/client/X11/xf_cliprdr.h b/client/X11/xf_cliprdr.h index ead887606..f2ee57dfd 100644 --- a/client/X11/xf_cliprdr.h +++ b/client/X11/xf_cliprdr.h @@ -21,6 +21,7 @@ #define __XF_CLIPRDR_H #include "xf_interface.h" +#include "xfreerdp.h" void xf_cliprdr_init(xfInfo* xfi, rdpChannels* chanman); void xf_cliprdr_uninit(xfInfo* xfi); diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index f8ebbf110..95b7a423d 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -29,6 +29,7 @@ #include "xf_rail.h" #include "xf_window.h" #include "xf_cliprdr.h" +#include "xf_input.h" #include "xf_event.h" @@ -95,7 +96,15 @@ static BOOL xf_event_Expose(xfInfo* xfi, XEvent* event, BOOL app) if (!app) { - XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); + if (xfi->scale != 1.0) + { + xf_draw_screen_scaled(xfi); + } + else + { + XCopyArea(xfi->display, xfi->primary, + xfi->window->handle, xfi->gc, x, y, w, h, x, y); + } } else { @@ -123,8 +132,8 @@ static BOOL xf_event_VisibilityNotify(xfInfo* xfi, XEvent* event, BOOL app) static BOOL xf_event_MotionNotify(xfInfo* xfi, XEvent* event, BOOL app) { - rdpInput* input; int x, y; + rdpInput* input; Window childWindow; input = xfi->instance->input; @@ -151,6 +160,13 @@ static BOOL xf_event_MotionNotify(xfInfo* xfi, XEvent* event, BOOL app) x, y, &x, &y, &childWindow); } + if (xfi->scale != 1.0) + { + /* Take scaling in to consideration */ + x = (int) (x * (1.0 / xfi->scale)); + y = (int) (y * (1.0 / xfi->scale)); + } + input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); if (xfi->fullscreen) @@ -165,10 +181,10 @@ static BOOL xf_event_ButtonPress(xfInfo* xfi, XEvent* event, BOOL app) { int x, y; int flags; - Window childWindow; BOOL wheel; BOOL extended; rdpInput* input; + Window childWindow; input = xfi->instance->input; @@ -254,6 +270,13 @@ static BOOL xf_event_ButtonPress(xfInfo* xfi, XEvent* event, BOOL app) x, y, &x, &y, &childWindow); } + if (xfi->scale != 1.0) + { + /* Take scaling in to consideration */ + x = (int) (x * (1.0 / xfi->scale)); + y = (int) (y * (1.0 / xfi->scale)); + } + if (extended) input->ExtendedMouseEvent(input, flags, x, y); else @@ -268,9 +291,9 @@ static BOOL xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, BOOL app) { int x, y; int flags; - Window childWindow; BOOL extended; rdpInput* input; + Window childWindow; input = xfi->instance->input; @@ -337,6 +360,13 @@ static BOOL xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, BOOL app) x, y, &x, &y, &childWindow); } + if (xfi->scale != 1.0) + { + /* Take scaling in to consideration */ + x = (int) (x * (1.0 / xfi->scale)); + y = (int) (y * (1.0 / xfi->scale)); + } + if (extended) input->ExtendedMouseEvent(input, flags, x, y); else @@ -523,6 +553,15 @@ static BOOL xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, BOOL app) rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; + if (xfi->width != event->xconfigure.width) + { + xfi->scale = (double) event->xconfigure.width / (double) xfi->originalWidth; + xfi->currentWidth = event->xconfigure.width; + xfi->currentHeight = event->xconfigure.width; + + xf_draw_screen_scaled(xfi); + } + window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window); if (window != NULL) @@ -977,6 +1016,8 @@ BOOL xf_event_process(freerdp* instance, XEvent* event) break; } + xf_input_handle_event(xfi, event); + XSync(xfi->display, FALSE); return status; diff --git a/client/X11/xf_event.h b/client/X11/xf_event.h index 722a7a56e..93e0c7732 100644 --- a/client/X11/xf_event.h +++ b/client/X11/xf_event.h @@ -23,6 +23,7 @@ #include "xf_keyboard.h" #include "xf_interface.h" +#include "xfreerdp.h" BOOL xf_event_process(freerdp* instance, XEvent* event); void xf_event_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int numArgs, ...); diff --git a/client/X11/xf_gdi.h b/client/X11/xf_gdi.h index b3ac75df9..64e98d0cb 100644 --- a/client/X11/xf_gdi.h +++ b/client/X11/xf_gdi.h @@ -23,6 +23,7 @@ #include #include "xf_interface.h" +#include "xfreerdp.h" void xf_gdi_register_update_callbacks(rdpUpdate* update); diff --git a/client/X11/xf_graphics.h b/client/X11/xf_graphics.h index 9d8cfd62f..60bbba6bf 100644 --- a/client/X11/xf_graphics.h +++ b/client/X11/xf_graphics.h @@ -21,6 +21,7 @@ #define __XF_GRAPHICS_H #include "xf_interface.h" +#include "xfreerdp.h" void xf_register_graphics(rdpGraphics* graphics); diff --git a/client/X11/xf_input.c b/client/X11/xf_input.c new file mode 100644 index 000000000..9db6b4dff --- /dev/null +++ b/client/X11/xf_input.c @@ -0,0 +1,439 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * X11 Input + * + * Copyright 2013 Corey Clayton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WITH_XI +#include +#endif + +#include + +#include "xf_input.h" + +#ifdef WITH_XI + +#define MAX_CONTACTS 2 + +typedef struct touch_contact +{ + int id; + int count; + double pos_x; + double pos_y; + double last_x; + double last_y; + +} touchContact; + +touchContact contacts[MAX_CONTACTS]; + +int active_contacts; +XIDeviceEvent lastEvent; +double firstDist = -1.0; +double lastDist; +double z_vector; +int xinput_opcode; +int scale_cnt; + +int xf_input_init(xfInfo* xfi, Window window) +{ + int i, j; + int nmasks; + int ndevices; + int major = 2; + int minor = 2; + Status xstatus; + XIDeviceInfo* info; + XIEventMask evmasks[8]; + int opcode, event, error; + BYTE masks[8][XIMaskLen(XI_LASTEVENT)]; + + nmasks = 0; + ndevices = 0; + active_contacts = 0; + ZeroMemory(contacts, sizeof(touchContact) * MAX_CONTACTS); + + if (!XQueryExtension(xfi->display, "XInputExtension", &opcode, &event, &error)) + { + printf("XInput extension not available.\n"); + return -1; + } + + xfi->XInputOpcode = opcode; + + XIQueryVersion(xfi->display, &major, &minor); + + if (major * 1000 + minor < 2002) + { + printf("Server does not support XI 2.2\n"); + return -1; + } + + info = XIQueryDevice(xfi->display, XIAllDevices, &ndevices); + + for (i = 0; i < ndevices; i++) + { + XIDeviceInfo* dev = &info[i]; + + for (j = 0; j < dev->num_classes; j++) + { + XIAnyClassInfo* class = dev->classes[j]; + XITouchClassInfo* t = (XITouchClassInfo*) class; + + if (class->type != XITouchClass) + continue; + + if (t->mode != XIDirectTouch) + continue; + + if (strcmp(dev->name, "Virtual core pointer") == 0) + continue; + + printf("%s %s touch device (id: %d, mode: %d), supporting %d touches.\n", + dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent", + dev->deviceid, t->mode, t->num_touches); + + evmasks[nmasks].mask = masks[nmasks]; + evmasks[nmasks].mask_len = sizeof(masks[0]); + ZeroMemory(masks[nmasks], sizeof(masks[0])); + evmasks[nmasks].deviceid = dev->deviceid; + + XISetMask(masks[nmasks], XI_TouchBegin); + XISetMask(masks[nmasks], XI_TouchUpdate); + XISetMask(masks[nmasks], XI_TouchEnd); + nmasks++; + } + } + + if (nmasks > 0) + xstatus = XISelectEvents(xfi->display, window, evmasks, nmasks); + + return 0; +} + +BOOL xf_input_is_duplicate(XIDeviceEvent* event) +{ + if ( (lastEvent.time == event->time) && + (lastEvent.detail == event->detail) && + (lastEvent.event_x == event->event_x) && + (lastEvent.event_y == event->event_y) ) + { + return TRUE; + } + + return FALSE; +} + +void xf_input_save_last_event(XIDeviceEvent* event) +{ + lastEvent.time = event->time; + lastEvent.detail = event->detail; + lastEvent.event_x = event->event_x; + lastEvent.event_y = event->event_y; +} + +void xf_input_detect_pinch(xfInfo* xfi) +{ + double dist; + double zoom; + double delta; + + if (active_contacts != 2) + { + firstDist = -1.0; + return; + } + + /* first calculate the distance */ + dist = sqrt(pow(contacts[1].pos_x - contacts[0].last_x, 2.0) + + pow(contacts[1].pos_y - contacts[0].last_y, 2.0)); + + /* if this is the first 2pt touch */ + if (firstDist <= 0) + { + firstDist = dist; + lastDist = firstDist; + scale_cnt = 0; + z_vector = 0; + } + else + { + delta = lastDist - dist; + + /* compare the current distance to the first one */ + zoom = (dist / firstDist); + + z_vector += delta; + //printf("d: %.2f\n", delta); + + lastDist = dist; + + if (z_vector > 10) + { + xfi->scale -= 0.05; + + if (xfi->scale < 0.5) + xfi->scale = 0.5; + + XResizeWindow(xfi->display, xfi->window->handle, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale); + IFCALL(xfi->client->OnResizeWindow, xfi->instance, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale); + + z_vector = 0; + } + + if (z_vector < -10) + { + xfi->scale += 0.05; + + if (xfi->scale > 1.5) + xfi->scale = 1.5; + + XResizeWindow(xfi->display, xfi->window->handle, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale); + IFCALL(xfi->client->OnResizeWindow, xfi->instance, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale); + + z_vector = 0; + } + } +} + +void xf_input_touch_begin(xfInfo* xfi, XIDeviceEvent* event) +{ + int i; + + for (i = 0; i < MAX_CONTACTS; i++) + { + if (contacts[i].id == 0) + { + contacts[i].id = event->detail; + contacts[i].count = 1; + contacts[i].pos_x = event->event_x; + contacts[i].pos_y = event->event_y; + + active_contacts++; + break; + } + } +} + +void xf_input_touch_update(xfInfo* xfi, XIDeviceEvent* event) +{ + int i; + + for (i = 0; i < MAX_CONTACTS; i++) + { + if (contacts[i].id == event->detail) + { + contacts[i].count++; + contacts[i].last_x = contacts[i].pos_x; + contacts[i].last_y = contacts[i].pos_y; + contacts[i].pos_x = event->event_x; + contacts[i].pos_y = event->event_y; + + xf_input_detect_pinch(xfi); + + break; + } + } +} + +void xf_input_touch_end(xfInfo* xfi, XIDeviceEvent* event) +{ + int i; + + for (i = 0; i < MAX_CONTACTS; i++) + { + if (contacts[i].id == event->detail) + { + contacts[i].id = 0; + contacts[i].count = 0; + //contacts[i].pos_x = (int)event->event_x; + //contacts[i].pos_y = (int)event->event_y; + + active_contacts--; + break;printf("TouchBegin\n"); + } + } +} + +int xf_input_handle_event_local(xfInfo* xfi, XEvent* event) +{ + XGenericEventCookie* cookie = &event->xcookie; + + XGetEventData(xfi->display, cookie); + + if ((cookie->type == GenericEvent) && (cookie->extension == xfi->XInputOpcode)) + { + switch (cookie->evtype) + { + case XI_TouchBegin: + if (xf_input_is_duplicate(cookie->data) == FALSE) + xf_input_touch_begin(xfi, cookie->data); + xf_input_save_last_event(cookie->data); + break; + + case XI_TouchUpdate: + if (xf_input_is_duplicate(cookie->data) == FALSE) + xf_input_touch_update(xfi, cookie->data); + xf_input_save_last_event(cookie->data); + break; + + case XI_TouchEnd: + if (xf_input_is_duplicate(cookie->data) == FALSE) + xf_input_touch_end(xfi, cookie->data); + xf_input_save_last_event(cookie->data); + break; + + default: + printf("unhandled xi type= %d\n", cookie->evtype); + break; + } + } + + XFreeEventData(xfi->display,cookie); + + return 0; +} + +char* xf_input_touch_state_string(DWORD flags) +{ + if (flags & CONTACT_FLAG_DOWN) + return "TouchBegin"; + else if (flags & CONTACT_FLAG_UPDATE) + return "TouchUpdate"; + else if (flags & CONTACT_FLAG_UP) + return "TouchEnd"; + else + return "TouchUnknown"; +} + +int xf_input_touch_remote(xfInfo* xfi, XIDeviceEvent* event, DWORD flags) +{ + int x, y; + int touchId; + RDPINPUT_CONTACT_DATA contact; + RdpeiClientContext* rdpei = xfi->rdpei; + + if (!rdpei) + return 0; + + touchId = event->detail; + x = (int) event->event_x; + y = (int) event->event_y; + ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA)); + + contact.fieldsPresent = 0; + contact.x = x; + contact.y = y; + contact.contactFlags = flags; + + if (flags & CONTACT_FLAG_DOWN) + { + contact.contactId = rdpei->ContactBegin(rdpei, touchId); + contact.contactFlags |= CONTACT_FLAG_INRANGE; + contact.contactFlags |= CONTACT_FLAG_INCONTACT; + } + else if (flags & CONTACT_FLAG_UPDATE) + { + contact.contactId = rdpei->ContactUpdate(rdpei, touchId); + contact.contactFlags |= CONTACT_FLAG_INRANGE; + contact.contactFlags |= CONTACT_FLAG_INCONTACT; + } + else if (flags & CONTACT_FLAG_UP) + { + contact.contactId = rdpei->ContactEnd(rdpei, touchId); + } + + rdpei->AddContact(rdpei, &contact); + + return 0; +} + +int xf_input_handle_event_remote(xfInfo* xfi, XEvent* event) +{ + XGenericEventCookie* cookie = &event->xcookie; + + XGetEventData(xfi->display, cookie); + + if ((cookie->type == GenericEvent) && (cookie->extension == xfi->XInputOpcode)) + { + switch (cookie->evtype) + { + case XI_TouchBegin: + xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_DOWN); + break; + + case XI_TouchUpdate: + xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_UPDATE); + break; + + case XI_TouchEnd: + xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_UP); + break; + + default: + break; + } + } + + XFreeEventData(xfi->display,cookie); + + return 0; +} + +#else + +int xf_input_init(xfInfo* xfi, Window window) +{ + return 0; +} + +#endif + +void xf_process_rdpei_event(xfInfo* xfi, wMessage* event) +{ + switch (GetMessageType(event->id)) + { + case RdpeiChannel_ServerReady: + break; + + case RdpeiChannel_SuspendTouch: + break; + + case RdpeiChannel_ResumeTouch: + break; + } +} + +int xf_input_handle_event(xfInfo* xfi, XEvent* event) +{ +#ifdef WITH_XI + if (xfi->settings->MultiTouchInput) + { + return xf_input_handle_event_remote(xfi, event); + } + + if (xfi->enableScaling) + return xf_input_handle_event_local(xfi, event); +#endif + + return 0; +} diff --git a/client/Mac/AppDelegate.m b/client/X11/xf_input.h similarity index 61% rename from client/Mac/AppDelegate.m rename to client/X11/xf_input.h index 029d055d1..9803193bd 100644 --- a/client/Mac/AppDelegate.m +++ b/client/X11/xf_input.h @@ -1,8 +1,8 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * MacFreeRDP + * X11 Input * - * Copyright 2012 Thomas Goddard + * Copyright 2013 Corey Clayton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,22 +17,19 @@ * limitations under the License. */ -#import "AppDelegate.h" +#ifndef __XF_INPUT_H +#define __XF_INPUT_H -@implementation AppDelegate +#include "xf_interface.h" +#include "xfreerdp.h" -@synthesize window = _window; +#ifdef WITH_XI +#include +#endif -@synthesize mrdpView; +int xf_input_init(xfInfo* xfi, Window window); -- (void)applicationDidFinishLaunching:(NSNotification*)aNotification -{ - rdp_connect(); -} +int xf_input_handle_event(xfInfo* xfi, XEvent* event); +void xf_process_rdpei_event(xfInfo* xfi, wMessage* event); -- (void) applicationWillTerminate:(NSNotification*)notification -{ - //[mrdpView releaseResources]; -} - -@end +#endif diff --git a/client/X11/xf_interface.c b/client/X11/xf_interface.c index c2d6d0a60..13ac4d9ac 100644 --- a/client/X11/xf_interface.c +++ b/client/X11/xf_interface.c @@ -32,6 +32,14 @@ #include #endif +#ifdef WITH_XI +#include +#endif + +#ifdef WITH_XRENDER +#include +#endif + #include #include #include @@ -44,6 +52,7 @@ #include #include +#include #include #include #include @@ -69,14 +78,49 @@ #include "xf_rail.h" #include "xf_tsmf.h" #include "xf_event.h" +#include "xf_input.h" #include "xf_cliprdr.h" #include "xf_monitor.h" #include "xf_graphics.h" #include "xf_keyboard.h" +#include "xf_channels.h" + +#include "xfreerdp.h" static long xv_port = 0; static const size_t password_size = 512; +void xf_draw_screen_scaled(xfInfo* xfi) +{ +#ifdef WITH_XRENDER + XTransform transform; + Picture windowPicture; + Picture primaryPicture; + XRenderPictureAttributes pa; + XRenderPictFormat* picFormat; + + picFormat = XRenderFindStandardFormat(xfi->display, PictStandardRGB24); + pa.subwindow_mode = IncludeInferiors; + primaryPicture = XRenderCreatePicture(xfi->display, xfi->primary, picFormat, CPSubwindowMode, &pa); + windowPicture = XRenderCreatePicture(xfi->display, xfi->window->handle, picFormat, CPSubwindowMode, &pa); + + transform.matrix[0][0] = XDoubleToFixed(1); + transform.matrix[0][1] = XDoubleToFixed(0); + transform.matrix[0][2] = XDoubleToFixed(0); + + transform.matrix[1][0] = XDoubleToFixed(0); + transform.matrix[1][1] = XDoubleToFixed(1); + transform.matrix[1][2] = XDoubleToFixed(0); + + transform.matrix[2][0] = XDoubleToFixed(0); + transform.matrix[2][1] = XDoubleToFixed(0); + transform.matrix[2][2] = XDoubleToFixed(xfi->scale); + + XRenderSetPictureTransform(xfi->display, primaryPicture, &transform); + XRenderComposite(xfi->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, 0, 0, xfi->currentWidth, xfi->currentHeight); +#endif +} + void xf_context_new(freerdp* instance, rdpContext* context) { context->channels = freerdp_channels_new(); @@ -104,9 +148,9 @@ void xf_sw_end_paint(rdpContext* context) xfi = ((xfContext*) context)->xfi; gdi = context->gdi; - if (xfi->remote_app != TRUE) + if (!xfi->remote_app) { - if (xfi->complex_regions != TRUE) + if (!xfi->complex_regions) { if (gdi->primary->hdc->hwnd->invalid->null) return; @@ -119,7 +163,15 @@ void xf_sw_end_paint(rdpContext* context) xf_lock_x11(xfi, FALSE); XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h); - XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); + + if (xfi->scale != 1.0) + { + xf_draw_screen_scaled(xfi); + } + else + { + XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); + } xf_unlock_x11(xfi, FALSE); } @@ -145,7 +197,15 @@ void xf_sw_end_paint(rdpContext* context) h = cinvalid[i].h; XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h); - XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); + + if (xfi->scale != 1.0) + { + xf_draw_screen_scaled(xfi); + } + else + { + XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); + } } XFlush(xfi->display); @@ -181,7 +241,7 @@ void xf_sw_desktop_resize(rdpContext* context) xf_lock_x11(xfi, TRUE); - if (xfi->fullscreen != TRUE) + if (!xfi->fullscreen) { rdpGdi* gdi = context->gdi; gdi_resize(gdi, xfi->width, xfi->height); @@ -229,7 +289,14 @@ void xf_hw_end_paint(rdpContext* context) xf_lock_x11(xfi, FALSE); - XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, w, h, x, y); + if (xfi->scale != 1.0) + { + xf_draw_screen_scaled(xfi); + } + else + { + XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, w, h, x, y); + } xf_unlock_x11(xfi, FALSE); } @@ -254,7 +321,14 @@ void xf_hw_end_paint(rdpContext* context) w = cinvalid[i].w; h = cinvalid[i].h; - XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, w, h, x, y); + if (xfi->scale != 1.0) + { + xf_draw_screen_scaled(xfi); + } + else + { + XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, w, h, x, y); + } } XFlush(xfi->display); @@ -291,7 +365,7 @@ void xf_hw_desktop_resize(rdpContext* context) xf_lock_x11(xfi, TRUE); - if (xfi->fullscreen != TRUE) + if (!xfi->fullscreen) { xfi->width = settings->DesktopWidth; xfi->height = settings->DesktopHeight; @@ -436,6 +510,9 @@ void xf_toggle_fullscreen(xfInfo* xfi) XFreePixmap(xfi->display, contents); xf_unlock_x11(xfi, TRUE); + + IFCALL(xfi->client->OnWindowStateChange, xfi->instance, + xfi->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0); } void xf_lock_x11(xfInfo* xfi, BOOL display) @@ -592,6 +669,7 @@ int _xf_error_handler(Display* d, XErrorEvent* ev) BOOL xf_pre_connect(freerdp* instance) { xfInfo* xfi; + rdpChannels* channels; rdpSettings* settings; xfi = ((xfContext*) instance->context)->xfi; @@ -603,13 +681,17 @@ BOOL xf_pre_connect(freerdp* instance) xfi->context->settings = instance->settings; xfi->instance = instance; settings = instance->settings; + channels = instance->context->channels; + + instance->OnChannelConnected = xf_on_channel_connected; + instance->OnChannelDisconnected = xf_on_channel_disconnected; //if (status < 0) // exit(XF_EXIT_PARSE_ARGUMENTS); - freerdp_client_load_addins(instance->context->channels, instance->settings); + freerdp_client_load_addins(channels, instance->settings); - freerdp_channels_pre_connect(xfi->_context->channels, instance); + freerdp_channels_pre_connect(channels, instance); if (settings->AuthenticationOnly) { @@ -642,7 +724,7 @@ BOOL xf_pre_connect(freerdp* instance) xfi->display = XOpenDisplay(NULL); - if (xfi->display == NULL) + if (!xfi->display) { fprintf(stderr, "xf_pre_connect: failed to open display: %s\n", XDisplayName(NULL)); fprintf(stderr, "Please check that the $DISPLAY environment variable is properly set.\n"); @@ -763,6 +845,12 @@ BOOL xf_post_connect(freerdp* instance) } } + xfi->originalWidth = settings->DesktopWidth; + xfi->originalHeight = settings->DesktopHeight; + xfi->currentWidth = xfi->originalWidth; + xfi->currentHeight = xfi->originalWidth; + xfi->scale = 1.0; + xfi->width = settings->DesktopWidth; xfi->height = settings->DesktopHeight; @@ -946,6 +1034,10 @@ void xf_process_channel_event(rdpChannels* channels, freerdp* instance) xf_process_cliprdr_event(xfi, event); break; + case RdpeiChannel_Class: + xf_process_rdpei_event(xfi, event); + break; + default: break; } @@ -1020,6 +1112,7 @@ void xf_window_free(xfInfo* xfi) } freerdp_clrconv_free(xfi->clrconv); + xfi->clrconv = NULL; if (xfi->hdc) gdi_DeleteDC(xfi->hdc); @@ -1186,11 +1279,9 @@ void* xf_thread(void* param) if (!status) { - freerdp_client_free(xfi); exit_code = XF_EXIT_CONN_FAILED; ExitThread(exit_code); } - channels = instance->context->channels; settings = instance->context->settings; @@ -1219,6 +1310,11 @@ void* xf_thread(void* param) rcount = 0; wcount = 0; + if (freerdp_focus_required(instance)) + { + xf_kbd_focus_in(xfi); + } + if (!async_transport) { if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) @@ -1382,9 +1478,6 @@ void* xf_thread(void* param) freerdp_channels_free(channels); freerdp_disconnect(instance); gdi_free(instance); - freerdp_client_free(xfi); - - exit_code = 123; ExitThread(exit_code); } @@ -1431,6 +1524,14 @@ int freerdp_client_global_uninit() int freerdp_client_start(xfInfo* xfi) { + rdpSettings* settings = xfi->settings; + + if (!settings->ServerHostname) + { + fprintf(stderr, "error: server hostname was not specified with /v:[:port]\n"); + return -1; + } + xfi->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_thread, (void*) xfi->instance, 0, NULL); return 0; @@ -1452,6 +1553,35 @@ int freerdp_client_stop(xfInfo* xfi) return 0; } +freerdp* freerdp_client_get_instance(cfInfo* cfi) +{ + return cfi->instance; +} + +HANDLE freerdp_client_get_thread(cfInfo* cfi) +{ + return cfi->thread; +} + +rdpClient* freerdp_client_get_interface(cfInfo* cfi) +{ + return cfi->client; +} + +double freerdp_client_get_scale(xfInfo* xfi) +{ + return xfi->scale; +} + +void freerdp_client_reset_scale(xfInfo* xfi) +{ + xfi->scale = 1.0; + + XResizeWindow(xfi->display, xfi->window->handle, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale); + IFCALL(xfi->client->OnResizeWindow, xfi->instance, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale); + xf_draw_screen_scaled(xfi); +} + xfInfo* freerdp_client_new(int argc, char** argv) { int index; @@ -1475,8 +1605,6 @@ xfInfo* freerdp_client_new(int argc, char** argv) freerdp_context_new(instance); instance->context->argc = argc; - instance->context->argv = argv; - instance->context->argv = (char**) malloc(sizeof(char*) * argc); for (index = 0; index < argc; index++) @@ -1494,6 +1622,13 @@ xfInfo* freerdp_client_new(int argc, char** argv) status = freerdp_client_parse_command_line_arguments(instance->context->argc, instance->context->argv, settings); + if (status < 0) + { + freerdp_context_free(xfi->instance); + freerdp_free(xfi->instance); + free(xfi); + return NULL; + } if (settings->ConnectionFile) { @@ -1537,6 +1672,11 @@ xfInfo* freerdp_client_new(int argc, char** argv) settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; + if (settings->ListMonitors) + { + xf_list_monitors(xfi); + } + return xfi; } @@ -1544,12 +1684,25 @@ void freerdp_client_free(xfInfo* xfi) { if (xfi) { + int index; + rdpContext* context; + xf_window_free(xfi); free(xfi->bmp_codec_none); XCloseDisplay(xfi->display); + context = (rdpContext*) xfi->context; + + for (index = 0; index < context->argc; index++) + free(context->argv[index]); + + free(context->argv); + + freerdp_context_free(xfi->instance); + freerdp_free(xfi->instance); + free(xfi); } } diff --git a/client/X11/xf_interface.h b/client/X11/xf_interface.h index 9f4483fc8..34c2c2870 100644 --- a/client/X11/xf_interface.h +++ b/client/X11/xf_interface.h @@ -36,196 +36,10 @@ typedef struct xf_info xfInfo; -#include "xf_window.h" -#include "xf_monitor.h" - #ifdef __cplusplus extern "C" { #endif -struct xf_WorkArea -{ - UINT32 x; - UINT32 y; - UINT32 width; - UINT32 height; -}; -typedef struct xf_WorkArea xfWorkArea; - -struct xf_pointer -{ - rdpPointer pointer; - Cursor cursor; -}; -typedef struct xf_pointer xfPointer; - -struct xf_bitmap -{ - rdpBitmap bitmap; - Pixmap pixmap; -}; -typedef struct xf_bitmap xfBitmap; - -struct xf_glyph -{ - rdpGlyph glyph; - Pixmap pixmap; -}; -typedef struct xf_glyph xfGlyph; - -struct xf_context -{ - rdpContext _p; - - xfInfo* xfi; - rdpSettings* settings; -}; -typedef struct xf_context xfContext; - -struct xf_info -{ - freerdp* instance; - xfContext* context; - rdpContext* _context; - - rdpClient* client; - rdpSettings* settings; - - GC gc; - int bpp; - int xfds; - int depth; - int width; - int height; - int srcBpp; - GC gc_mono; - Screen* screen; - XImage* image; - Pixmap primary; - Pixmap drawing; - Visual* visual; - Display* display; - Drawable drawable; - Pixmap bitmap_mono; - Colormap colormap; - int screen_number; - int scanline_pad; - BOOL big_endian; - BOOL fullscreen; - BOOL grab_keyboard; - BOOL unobscured; - BOOL debug; - xfWindow* window; - xfWorkArea workArea; - int current_desktop; - BOOL remote_app; - BOOL disconnect; - HCLRCONV clrconv; - HANDLE mutex; - HANDLE thread; - BOOL UseXThreads; - - HGDI_DC hdc; - BYTE* primary_buffer; - - BOOL frame_begin; - UINT16 frame_x1; - UINT16 frame_y1; - UINT16 frame_x2; - UINT16 frame_y2; - - BOOL focused; - BOOL mouse_active; - BOOL suppress_output; - BOOL fullscreen_toggle; - UINT32 keyboard_layout_id; - BOOL pressed_keys[256]; - XModifierKeymap* modifier_map; - XSetWindowAttributes attribs; - BOOL complex_regions; - VIRTUAL_SCREEN vscreen; - BYTE* bmp_codec_none; - BYTE* bmp_codec_nsc; - void* rfx_context; - void* nsc_context; - void* xv_context; - void* clipboard_context; - - Atom _NET_WM_ICON; - Atom _MOTIF_WM_HINTS; - Atom _NET_CURRENT_DESKTOP; - Atom _NET_WORKAREA; - - Atom _NET_WM_STATE; - Atom _NET_WM_STATE_FULLSCREEN; - Atom _NET_WM_STATE_SKIP_TASKBAR; - Atom _NET_WM_STATE_SKIP_PAGER; - - Atom _NET_WM_WINDOW_TYPE; - Atom _NET_WM_WINDOW_TYPE_NORMAL; - Atom _NET_WM_WINDOW_TYPE_DIALOG; - Atom _NET_WM_WINDOW_TYPE_UTILITY; - Atom _NET_WM_WINDOW_TYPE_POPUP; - Atom _NET_WM_WINDOW_TYPE_DROPDOWN_MENU; - - Atom _NET_WM_MOVERESIZE; - Atom _NET_MOVERESIZE_WINDOW; - - Atom WM_STATE; - Atom WM_PROTOCOLS; - Atom WM_DELETE_WINDOW; -}; - -void xf_create_window(xfInfo* xfi); -void xf_toggle_fullscreen(xfInfo* xfi); -BOOL xf_post_connect(freerdp* instance); - -enum XF_EXIT_CODE -{ - /* section 0-15: protocol-independent codes */ - XF_EXIT_SUCCESS = 0, - XF_EXIT_DISCONNECT = 1, - XF_EXIT_LOGOFF = 2, - XF_EXIT_IDLE_TIMEOUT = 3, - XF_EXIT_LOGON_TIMEOUT = 4, - XF_EXIT_CONN_REPLACED = 5, - XF_EXIT_OUT_OF_MEMORY = 6, - XF_EXIT_CONN_DENIED = 7, - XF_EXIT_CONN_DENIED_FIPS = 8, - XF_EXIT_USER_PRIVILEGES = 9, - XF_EXIT_FRESH_CREDENTIALS_REQUIRED = 10, - XF_EXIT_DISCONNECT_BY_USER = 11, - - /* section 16-31: license error set */ - XF_EXIT_LICENSE_INTERNAL = 16, - XF_EXIT_LICENSE_NO_LICENSE_SERVER = 17, - XF_EXIT_LICENSE_NO_LICENSE = 18, - XF_EXIT_LICENSE_BAD_CLIENT_MSG = 19, - XF_EXIT_LICENSE_HWID_DOESNT_MATCH = 20, - XF_EXIT_LICENSE_BAD_CLIENT = 21, - XF_EXIT_LICENSE_CANT_FINISH_PROTOCOL = 22, - XF_EXIT_LICENSE_CLIENT_ENDED_PROTOCOL = 23, - XF_EXIT_LICENSE_BAD_CLIENT_ENCRYPTION = 24, - XF_EXIT_LICENSE_CANT_UPGRADE = 25, - XF_EXIT_LICENSE_NO_REMOTE_CONNECTIONS = 26, - - /* section 32-127: RDP protocol error set */ - XF_EXIT_RDP = 32, - - /* section 128-254: xfreerdp specific exit codes */ - XF_EXIT_PARSE_ARGUMENTS = 128, - XF_EXIT_MEMORY = 129, - XF_EXIT_PROTOCOL = 130, - XF_EXIT_CONN_FAILED = 131, - - XF_EXIT_UNKNOWN = 255, -}; - -void xf_lock_x11(xfInfo* xfi, BOOL display); -void xf_unlock_x11(xfInfo* xfi, BOOL display); - -DWORD xf_exit_code_from_disconnect_reason(DWORD reason); - /** * Client Interface */ @@ -238,6 +52,12 @@ FREERDP_API int freerdp_client_global_uninit(); FREERDP_API int freerdp_client_start(cfInfo* cfi); FREERDP_API int freerdp_client_stop(cfInfo* cfi); +FREERDP_API freerdp* freerdp_client_get_instance(cfInfo* cfi); +FREERDP_API HANDLE freerdp_client_get_thread(cfInfo* cfi); +FREERDP_API rdpClient* freerdp_client_get_interface(cfInfo* cfi); +FREERDP_API double freerdp_client_get_scale(xfInfo* xfi); +FREERDP_API void freerdp_client_reset_scale(xfInfo* xfi); + FREERDP_API cfInfo* freerdp_client_new(int argc, char** argv); FREERDP_API void freerdp_client_free(cfInfo* cfi); diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 73ae107da..a7ff67ce0 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -191,15 +191,16 @@ void xf_kbd_focus_in(xfInfo* xfi) { rdpInput* input; UINT32 syncFlags; + int dummy, mouseX, mouseY; + Window wdummy; + UINT32 state = 0; input = xfi->instance->input; - /* on focus in send a tab up like mstsc.exe */ - input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x0F); - - /* synchronize toggle keys */ syncFlags = xf_kbd_get_toggle_keys_state(xfi); - input->SynchronizeEvent(input, syncFlags); + XQueryPointer(xfi->display, xfi->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state); + + input->FocusInEvent(input, syncFlags, mouseX, mouseY); } BOOL xf_kbd_handle_special_keys(xfInfo* xfi, KeySym keysym) diff --git a/client/X11/xf_keyboard.h b/client/X11/xf_keyboard.h index 01ec6111a..493a67cb5 100644 --- a/client/X11/xf_keyboard.h +++ b/client/X11/xf_keyboard.h @@ -23,6 +23,7 @@ #include #include "xf_interface.h" +#include "xfreerdp.h" void xf_kbd_init(xfInfo* xfi); void xf_kbd_clear(xfInfo* xfi); diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c index aad52dd12..0667e354c 100644 --- a/client/X11/xf_monitor.c +++ b/client/X11/xf_monitor.c @@ -37,9 +37,57 @@ /* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071 */ +int xf_list_monitors(xfInfo* xfi) +{ +#ifdef WITH_XINERAMA + Display* display; + int i, nmonitors = 0; + int ignored, ignored2; + XineramaScreenInfo* screen = NULL; + + display = XOpenDisplay(NULL); + + if (XineramaQueryExtension(display, &ignored, &ignored2)) + { + if (XineramaIsActive(display)) + { + screen = XineramaQueryScreens(display, &nmonitors); + + for (i = 0; i < nmonitors; i++) + { + printf(" %s [%d] %dx%d\t+%d+%d\n", + (i == 0) ? "*" : " ", i, + screen[i].width, screen[i].height, + screen[i].x_org, screen[i].y_org); + } + + XFree(screen); + } + } + + XCloseDisplay(display); +#else + Screen* screen; + Display* display; + + display = XOpenDisplay(NULL); + + screen = ScreenOfDisplay(display, DefaultScreen(display)); + printf(" * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen), HeightOfScreen(screen), 0, 0); + + XCloseDisplay(display); +#endif + + return 0; +} + BOOL xf_detect_monitors(xfInfo* xfi, rdpSettings* settings) { - int i; + int i, j; + int nmonitors; + int primaryMonitor; + int vWidth, vHeight; + int maxWidth, maxHeight; VIRTUAL_SCREEN* vscreen; #ifdef WITH_XINERAMA @@ -49,33 +97,6 @@ BOOL xf_detect_monitors(xfInfo* xfi, rdpSettings* settings) vscreen = &xfi->vscreen; - if (xf_GetWorkArea(xfi) != TRUE) - { - xfi->workArea.x = 0; - xfi->workArea.y = 0; - xfi->workArea.width = WidthOfScreen(xfi->screen); - xfi->workArea.height = HeightOfScreen(xfi->screen); - } - - if (settings->Fullscreen) - { - settings->DesktopWidth = WidthOfScreen(xfi->screen); - settings->DesktopHeight = HeightOfScreen(xfi->screen); - } - else if (settings->Workarea) - { - settings->DesktopWidth = xfi->workArea.width; - settings->DesktopHeight = xfi->workArea.height; - } - else if (settings->PercentScreen) - { - settings->DesktopWidth = (xfi->workArea.width * settings->PercentScreen) / 100; - settings->DesktopHeight = (xfi->workArea.height * settings->PercentScreen) / 100; - } - - if (settings->Fullscreen != TRUE && settings->Workarea != TRUE) - return TRUE; - #ifdef WITH_XINERAMA if (XineramaQueryExtension(xfi->display, &ignored, &ignored2)) { @@ -108,32 +129,124 @@ BOOL xf_detect_monitors(xfInfo* xfi, rdpSettings* settings) } #endif - settings->MonitorCount = vscreen->nmonitors; + if (!xf_GetWorkArea(xfi)) + { + xfi->workArea.x = 0; + xfi->workArea.y = 0; + xfi->workArea.width = WidthOfScreen(xfi->screen); + xfi->workArea.height = HeightOfScreen(xfi->screen); + } + + if (settings->Fullscreen) + { + settings->DesktopWidth = WidthOfScreen(xfi->screen); + settings->DesktopHeight = HeightOfScreen(xfi->screen); + maxWidth = settings->DesktopWidth; + maxHeight = settings->DesktopHeight; + } + else if (settings->Workarea) + { + settings->DesktopWidth = xfi->workArea.width; + settings->DesktopHeight = xfi->workArea.height; + maxWidth = settings->DesktopWidth; + maxHeight = settings->DesktopHeight; + } + else if (settings->PercentScreen) + { + settings->DesktopWidth = (xfi->workArea.width * settings->PercentScreen) / 100; + settings->DesktopHeight = (xfi->workArea.height * settings->PercentScreen) / 100; + maxWidth = settings->DesktopWidth; + maxHeight = settings->DesktopHeight; + } + else + { + maxWidth = WidthOfScreen(xfi->screen); + maxHeight = HeightOfScreen(xfi->screen); + } + + if (!settings->Fullscreen && !settings->Workarea && !settings->UseMultimon) + return TRUE; + + if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors) || + (settings->Workarea && !settings->RemoteApplicationMode)) + { + /* Select a single monitor */ + + if (settings->NumMonitorIds != 1) + { + settings->NumMonitorIds = 1; + settings->MonitorIds = (UINT32*) malloc(sizeof(UINT32) * settings->NumMonitorIds); + settings->MonitorIds[0] = 0; + + for (i = 0; i < vscreen->nmonitors; i++) + { + if (vscreen->monitors[i].primary) + { + settings->MonitorIds[0] = i; + break; + } + } + } + } + + nmonitors = 0; + primaryMonitor = 0; for (i = 0; i < vscreen->nmonitors; i++) { - settings->MonitorDefArray[i].x = vscreen->monitors[i].area.left; - settings->MonitorDefArray[i].y = vscreen->monitors[i].area.top; - settings->MonitorDefArray[i].width = vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1; - settings->MonitorDefArray[i].height = vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1; - settings->MonitorDefArray[i].is_primary = vscreen->monitors[i].primary; + if (settings->NumMonitorIds) + { + BOOL found = FALSE; - vscreen->area.left = MIN(vscreen->monitors[i].area.left, vscreen->area.left); - vscreen->area.right = MAX(vscreen->monitors[i].area.right, vscreen->area.right); - vscreen->area.top = MIN(vscreen->monitors[i].area.top, vscreen->area.top); - vscreen->area.bottom = MAX(vscreen->monitors[i].area.bottom, vscreen->area.bottom); + for (j = 0; j < settings->NumMonitorIds; j++) + { + if (settings->MonitorIds[j] == i) + found = TRUE; + } + + if (!found) + continue; + } + + settings->MonitorDefArray[nmonitors].x = vscreen->monitors[i].area.left; + settings->MonitorDefArray[nmonitors].y = vscreen->monitors[i].area.top; + settings->MonitorDefArray[nmonitors].width = MIN(vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1, settings->DesktopWidth); + settings->MonitorDefArray[nmonitors].height = MIN(vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1, settings->DesktopHeight); + settings->MonitorDefArray[nmonitors].is_primary = vscreen->monitors[i].primary; + + primaryMonitor |= vscreen->monitors[i].primary; + nmonitors++; } - /* if no monitor information is present then make sure variables are set accordingly */ - if (settings->MonitorCount == 0) + settings->MonitorCount = nmonitors; + + vWidth = vHeight = 0; + settings->DesktopPosX = maxWidth - 1; + settings->DesktopPosY = maxHeight - 1; + + for (i = 0; i < settings->MonitorCount; i++) { - vscreen->area.left = 0; - vscreen->area.right = settings->DesktopWidth -1; - vscreen->area.top = 0; - vscreen->area.bottom = settings->DesktopHeight - 1; - } - + settings->DesktopPosX = MIN(settings->DesktopPosX, settings->MonitorDefArray[i].x); + settings->DesktopPosY = MIN(settings->DesktopPosY, settings->MonitorDefArray[i].y); + vWidth += settings->MonitorDefArray[i].width; + vHeight = MAX(vHeight, settings->MonitorDefArray[i].height); + } + + vscreen->area.left = 0; + vscreen->area.right = vWidth - 1; + vscreen->area.top = 0; + vscreen->area.bottom = vHeight - 1; + + if (settings->Workarea) + { + vscreen->area.top = xfi->workArea.y; + vscreen->area.bottom = (vHeight - (vHeight - (xfi->workArea.height + xfi->workArea.y))) - 1; + } + + if (nmonitors && !primaryMonitor) + settings->MonitorDefArray[0].is_primary = TRUE; + if (settings->MonitorCount) { settings->DesktopWidth = vscreen->area.right - vscreen->area.left + 1; diff --git a/client/X11/xf_monitor.h b/client/X11/xf_monitor.h index 1020817e6..4f3b1de8e 100644 --- a/client/X11/xf_monitor.h +++ b/client/X11/xf_monitor.h @@ -41,7 +41,9 @@ struct _VIRTUAL_SCREEN typedef struct _VIRTUAL_SCREEN VIRTUAL_SCREEN; #include "xf_interface.h" +#include "xfreerdp.h" +int xf_list_monitors(xfInfo* xfi); BOOL xf_detect_monitors(xfInfo* xfi, rdpSettings* settings); #endif /* __XF_MONITOR_H */ diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h index e395681c9..29e24b8e9 100644 --- a/client/X11/xf_rail.h +++ b/client/X11/xf_rail.h @@ -21,6 +21,7 @@ #define __XF_RAIL_H #include "xf_interface.h" +#include "xfreerdp.h" void xf_rail_paint(xfInfo* xfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom); void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail); diff --git a/client/X11/xf_tsmf.h b/client/X11/xf_tsmf.h index db2395204..65d7838d8 100644 --- a/client/X11/xf_tsmf.h +++ b/client/X11/xf_tsmf.h @@ -21,6 +21,7 @@ #define __XF_TSMF_H #include "xf_interface.h" +#include "xfreerdp.h" void xf_tsmf_init(xfInfo* xfi, long xv_port); void xf_tsmf_uninit(xfInfo* xfi); diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index fd6631c33..780125455 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -42,6 +42,12 @@ #include #endif +#ifdef WITH_XI +#include +#endif + +#include "xf_input.h" + #ifdef WITH_DEBUG_X11 #define DEBUG_X11(fmt, ...) DEBUG_CLASS(X11, fmt, ## __VA_ARGS__) #else @@ -136,9 +142,11 @@ void xf_SetWindowFullscreen(xfInfo* xfi, xfWindow* window, BOOL fullscreen) { if (fullscreen) { + rdpSettings* settings = xfi->instance->settings; + xf_SetWindowDecorations(xfi, window, FALSE); - XMoveResizeWindow(xfi->display, window->handle, 0, 0, window->width, window->height); + XMoveResizeWindow(xfi->display, window->handle, settings->DesktopPosX, settings->DesktopPosY, window->width, window->height); XMapRaised(xfi->display, window->handle); window->fullscreen = TRUE; @@ -323,9 +331,11 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, { xfWindow* window; XEvent xevent; + rdpSettings* settings; window = (xfWindow*) malloc(sizeof(xfWindow)); ZeroMemory(window, sizeof(xfWindow)); + settings = xfi->instance->settings; if (window) { @@ -403,6 +413,8 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, XClearWindow(xfi->display, window->handle); XMapWindow(xfi->display, window->handle); + xf_input_init(xfi, window->handle); + /* * NOTE: This must be done here to handle reparenting the window, * so that we don't miss the event and hang waiting for the next one @@ -420,8 +432,13 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, */ if (xfi->instance->settings->RemoteApplicationMode) + { XMoveWindow(xfi->display, window->handle, 0, 0); - + } + else if (settings->DesktopPosX || settings->DesktopPosY) + { + XMoveWindow(xfi->display, window->handle, settings->DesktopPosX, settings->DesktopPosY); + } } xf_SetWindowText(xfi, window, name); diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index 257515925..96d08be50 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -28,6 +28,7 @@ typedef struct xf_localmove xfLocalMove; typedef struct xf_window xfWindow; #include "xf_interface.h" +#include "xfreerdp.h" // Extended ICCM flags http://standards.freedesktop.org/wm-spec/wm-spec-latest.html #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h new file mode 100644 index 000000000..3b530a529 --- /dev/null +++ b/client/X11/xfreerdp.h @@ -0,0 +1,224 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * X11 Client + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XFREERDP_H +#define __XFREERDP_H + +#include "xf_window.h" +#include "xf_monitor.h" +#include "xf_channels.h" + +struct xf_WorkArea +{ + UINT32 x; + UINT32 y; + UINT32 width; + UINT32 height; +}; +typedef struct xf_WorkArea xfWorkArea; + +struct xf_pointer +{ + rdpPointer pointer; + Cursor cursor; +}; +typedef struct xf_pointer xfPointer; + +struct xf_bitmap +{ + rdpBitmap bitmap; + Pixmap pixmap; +}; +typedef struct xf_bitmap xfBitmap; + +struct xf_glyph +{ + rdpGlyph glyph; + Pixmap pixmap; +}; +typedef struct xf_glyph xfGlyph; + +struct xf_context +{ + rdpContext _p; + + xfInfo* xfi; + rdpSettings* settings; +}; +typedef struct xf_context xfContext; + +struct xf_info +{ + freerdp* instance; + xfContext* context; + rdpContext* _context; + + rdpClient* client; + rdpSettings* settings; + + GC gc; + int bpp; + int xfds; + int depth; + int width; + int height; + int srcBpp; + GC gc_mono; + Screen* screen; + XImage* image; + Pixmap primary; + Pixmap drawing; + Visual* visual; + Display* display; + Drawable drawable; + Pixmap bitmap_mono; + Colormap colormap; + int screen_number; + int scanline_pad; + BOOL big_endian; + BOOL fullscreen; + BOOL grab_keyboard; + BOOL unobscured; + BOOL debug; + xfWindow* window; + xfWorkArea workArea; + int current_desktop; + BOOL remote_app; + BOOL disconnect; + HCLRCONV clrconv; + HANDLE mutex; + HANDLE thread; + BOOL UseXThreads; + + HGDI_DC hdc; + BYTE* primary_buffer; + + BOOL frame_begin; + UINT16 frame_x1; + UINT16 frame_y1; + UINT16 frame_x2; + UINT16 frame_y2; + + double scale; + int originalWidth; + int originalHeight; + int currentWidth; + int currentHeight; + int XInputOpcode; + BOOL enableScaling; + + BOOL focused; + BOOL mouse_active; + BOOL suppress_output; + BOOL fullscreen_toggle; + UINT32 keyboard_layout_id; + BOOL pressed_keys[256]; + XModifierKeymap* modifier_map; + XSetWindowAttributes attribs; + BOOL complex_regions; + VIRTUAL_SCREEN vscreen; + BYTE* bmp_codec_none; + BYTE* bmp_codec_nsc; + void* rfx_context; + void* nsc_context; + void* xv_context; + void* clipboard_context; + + Atom _NET_WM_ICON; + Atom _MOTIF_WM_HINTS; + Atom _NET_CURRENT_DESKTOP; + Atom _NET_WORKAREA; + + Atom _NET_WM_STATE; + Atom _NET_WM_STATE_FULLSCREEN; + Atom _NET_WM_STATE_SKIP_TASKBAR; + Atom _NET_WM_STATE_SKIP_PAGER; + + Atom _NET_WM_WINDOW_TYPE; + Atom _NET_WM_WINDOW_TYPE_NORMAL; + Atom _NET_WM_WINDOW_TYPE_DIALOG; + Atom _NET_WM_WINDOW_TYPE_UTILITY; + Atom _NET_WM_WINDOW_TYPE_POPUP; + Atom _NET_WM_WINDOW_TYPE_DROPDOWN_MENU; + + Atom _NET_WM_MOVERESIZE; + Atom _NET_MOVERESIZE_WINDOW; + + Atom WM_STATE; + Atom WM_PROTOCOLS; + Atom WM_DELETE_WINDOW; + + /* Channels */ + RdpeiClientContext* rdpei; +}; + +void xf_create_window(xfInfo* xfi); +void xf_toggle_fullscreen(xfInfo* xfi); +BOOL xf_post_connect(freerdp* instance); + +enum XF_EXIT_CODE +{ + /* section 0-15: protocol-independent codes */ + XF_EXIT_SUCCESS = 0, + XF_EXIT_DISCONNECT = 1, + XF_EXIT_LOGOFF = 2, + XF_EXIT_IDLE_TIMEOUT = 3, + XF_EXIT_LOGON_TIMEOUT = 4, + XF_EXIT_CONN_REPLACED = 5, + XF_EXIT_OUT_OF_MEMORY = 6, + XF_EXIT_CONN_DENIED = 7, + XF_EXIT_CONN_DENIED_FIPS = 8, + XF_EXIT_USER_PRIVILEGES = 9, + XF_EXIT_FRESH_CREDENTIALS_REQUIRED = 10, + XF_EXIT_DISCONNECT_BY_USER = 11, + + /* section 16-31: license error set */ + XF_EXIT_LICENSE_INTERNAL = 16, + XF_EXIT_LICENSE_NO_LICENSE_SERVER = 17, + XF_EXIT_LICENSE_NO_LICENSE = 18, + XF_EXIT_LICENSE_BAD_CLIENT_MSG = 19, + XF_EXIT_LICENSE_HWID_DOESNT_MATCH = 20, + XF_EXIT_LICENSE_BAD_CLIENT = 21, + XF_EXIT_LICENSE_CANT_FINISH_PROTOCOL = 22, + XF_EXIT_LICENSE_CLIENT_ENDED_PROTOCOL = 23, + XF_EXIT_LICENSE_BAD_CLIENT_ENCRYPTION = 24, + XF_EXIT_LICENSE_CANT_UPGRADE = 25, + XF_EXIT_LICENSE_NO_REMOTE_CONNECTIONS = 26, + + /* section 32-127: RDP protocol error set */ + XF_EXIT_RDP = 32, + + /* section 128-254: xfreerdp specific exit codes */ + XF_EXIT_PARSE_ARGUMENTS = 128, + XF_EXIT_MEMORY = 129, + XF_EXIT_PROTOCOL = 130, + XF_EXIT_CONN_FAILED = 131, + + XF_EXIT_UNKNOWN = 255, +}; + +void xf_lock_x11(xfInfo* xfi, BOOL display); +void xf_unlock_x11(xfInfo* xfi, BOOL display); + +void xf_draw_screen_scaled(xfInfo* xfi); + +DWORD xf_exit_code_from_disconnect_reason(DWORD reason); + +#endif /* __XFREERDP_H */ + diff --git a/client/common/cmdline.c b/client/common/cmdline.c index e495383af..188c871ec 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -48,8 +48,10 @@ COMMAND_LINE_ARGUMENT_A args[] = { "kbd-subtype", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Keyboard subtype" }, { "kbd-fn-key", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Keyboard function key count" }, { "admin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "console", "Admin (or console) session" }, - { "multimon", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Multi-monitor" }, - { "workarea", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Work area" }, + { "multimon", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Use multiple monitors" }, + { "workarea", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Use available work area" }, + { "monitors", COMMAND_LINE_VALUE_REQUIRED, "<0,1,2...>", NULL, NULL, -1, NULL, "Select monitors to use" }, + { "monitor-list", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT, NULL, NULL, NULL, -1, NULL, "List detected monitors" }, { "t", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, "title", "Window title" }, { "decorations", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueTrue, -1, NULL, "Window decorations" }, { "smart-sizing", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Scale remote desktop to window size" }, @@ -63,6 +65,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "gu", COMMAND_LINE_VALUE_REQUIRED, "[<domain>\\]<user> or <user>[@<domain>]", NULL, NULL, -1, NULL, "Gateway username" }, { "gp", COMMAND_LINE_VALUE_REQUIRED, "<password>", NULL, NULL, -1, NULL, "Gateway password" }, { "gd", COMMAND_LINE_VALUE_REQUIRED, "<domain>", NULL, NULL, -1, NULL, "Gateway domain" }, + { "load-balance-info", COMMAND_LINE_VALUE_REQUIRED, "<info string>", NULL, NULL, -1, NULL, "Load balance info" }, { "app", COMMAND_LINE_VALUE_REQUIRED, "||<alias> or <executable path>", NULL, NULL, -1, NULL, "Remote application program" }, { "app-name", COMMAND_LINE_VALUE_REQUIRED, "<app name>", NULL, NULL, -1, NULL, "Remote application name for user interface" }, { "app-icon", COMMAND_LINE_VALUE_REQUIRED, "<icon path>", NULL, NULL, -1, NULL, "Remote application icon for user interface" }, @@ -84,8 +87,9 @@ COMMAND_LINE_ARGUMENT_A args[] = { "serial", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, "tty", "Redirect serial device" }, { "parallel", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect parallel device" }, { "smartcard", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect smartcard device" }, - { "printer", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect printer device" }, + { "printer", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect printer device" }, { "usb", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect USB device" }, + { "multitouch", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect multitouch input" }, { "echo", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "echo", "Echo channel" }, { "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Smooth fonts (ClearType)" }, { "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueFalse, -1, NULL, "Desktop composition" }, @@ -287,14 +291,16 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p { RDPDR_PRINTER* printer; - if (count < 2) + if (count < 1) return -1; printer = (RDPDR_PRINTER*) malloc(sizeof(RDPDR_PRINTER)); ZeroMemory(printer, sizeof(RDPDR_PRINTER)); printer->Type = RDPDR_DTYP_PRINT; - printer->Name = _strdup(params[1]); + + if (count > 1) + printer->Name = _strdup(params[1]); if (count > 2) printer->DriverName = _strdup(params[2]); @@ -543,15 +549,28 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT } CommandLineSwitchCase(arg, "printer") { - char** p; - int count; + if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) + { + char** p; + int count; - p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value, &count); - p[0] = "printer"; + p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value, &count); + p[0] = "printer"; - freerdp_client_add_device_channel(settings, count, p); + freerdp_client_add_device_channel(settings, count, p); - free(p); + free(p); + } + else + { + char* p[1]; + int count; + + count = 1; + p[0] = "printer"; + + freerdp_client_add_device_channel(settings, count, p); + } } CommandLineSwitchCase(arg, "usb") { @@ -565,6 +584,16 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT free(p); } + CommandLineSwitchCase(arg, "multitouch") + { + char* p[1]; + int count = 1; + + settings->MultiTouchInput = TRUE; + + p[0] = "rdpei"; + freerdp_client_add_dynamic_channel(settings, count, p); + } CommandLineSwitchCase(arg, "echo") { char* p[1]; @@ -985,6 +1014,13 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin printf("\n"); } + arg = CommandLineFindArgumentA(args, "monitor-list"); + + if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) + { + settings->ListMonitors = TRUE; + } + return COMMAND_LINE_STATUS_PRINT; } @@ -992,8 +1028,8 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin if (!settings->ConnectionFile && !(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) { - fprintf(stderr, "error: server hostname was not specified with /v:<server>[:port]\n"); - return COMMAND_LINE_ERROR_MISSING_ARGUMENT; + //fprintf(stderr, "error: server hostname was not specified with /v:<server>[:port]\n"); + //return COMMAND_LINE_ERROR_MISSING_ARGUMENT; } arg = args; @@ -1089,6 +1125,28 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin { settings->Workarea = TRUE; } + CommandLineSwitchCase(arg, "monitors") + { + if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) + { + char** p; + int i, count = 0; + + p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count); + + settings->NumMonitorIds = count; + settings->MonitorIds = (UINT32*) malloc(sizeof(UINT32) * settings->NumMonitorIds); + + for (i = 0; i < settings->NumMonitorIds; i++) + { + settings->MonitorIds[i] = atoi(p[i]); + } + } + } + CommandLineSwitchCase(arg, "monitor-list") + { + settings->ListMonitors = TRUE; + } CommandLineSwitchCase(arg, "t") { settings->WindowTitle = _strdup(arg->Value); @@ -1220,6 +1278,11 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin settings->DisableWallpaper = TRUE; settings->DisableFullWindowDrag = TRUE; } + CommandLineSwitchCase(arg, "load-balance-info") + { + settings->LoadBalanceInfo = (BYTE*) _strdup(arg->Value); + settings->LoadBalanceInfoLength = strlen((char*) settings->LoadBalanceInfo); + } CommandLineSwitchCase(arg, "app-name") { settings->RemoteApplicationName = _strdup(arg->Value); @@ -1619,9 +1682,15 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) if ((freerdp_static_channel_collection_find(settings, "rdpsnd")) || (freerdp_dynamic_channel_collection_find(settings, "tsmf"))) { + settings->DeviceRedirection = TRUE; /* rdpsnd requires rdpdr to be registered */ settings->AudioPlayback = TRUE; /* Both rdpsnd and tsmf require this flag to be set */ } + if (freerdp_dynamic_channel_collection_find(settings, "audin")) + { + settings->AudioCapture = TRUE; + } + if (settings->RedirectDrives) { settings->DeviceRedirection = TRUE; diff --git a/client/common/file.c b/client/common/file.c index f3fe41e70..a383259a3 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -308,7 +308,7 @@ BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, BYTE* buffer, siz line = strtok_s((char*) buffer, "\r\n", &context); - while (line != NULL) + while (line) { length = strlen(line); @@ -458,8 +458,7 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name) if (file_size < 1) return FALSE; - buffer = (BYTE*) malloc(file_size); - + buffer = (BYTE*) malloc(file_size + 2); read_size = fread(buffer, file_size, 1, fp); if (!read_size) @@ -475,6 +474,9 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name) return FALSE; } + buffer[file_size] = '\0'; + buffer[file_size + 1] = '\0'; + return freerdp_client_parse_rdp_file_buffer(file, buffer, file_size); } @@ -701,6 +703,12 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* if (~((size_t) file->ShellWorkingDirectory)) freerdp_set_param_string(settings, FreeRDP_ShellWorkingDirectory, file->ShellWorkingDirectory); + if (~((size_t) file->LoadBalanceInfo)) + { + settings->LoadBalanceInfo = (BYTE*) _strdup(file->LoadBalanceInfo); + settings->LoadBalanceInfoLength = strlen((char*) settings->LoadBalanceInfo); + } + if (~file->ConnectionType) freerdp_set_param_uint32(settings, FreeRDP_ConnectionType, file->ConnectionType); diff --git a/client/iOS/Controllers/AdvancedBookmarkEditorController.m b/client/iOS/Controllers/AdvancedBookmarkEditorController.m index 17b9750ba..a0357d9e6 100644 --- a/client/iOS/Controllers/AdvancedBookmarkEditorController.m +++ b/client/iOS/Controllers/AdvancedBookmarkEditorController.m @@ -13,6 +13,7 @@ #import "EditorSelectionController.h" #import "ScreenSelectionController.h" #import "PerformanceEditorController.h" +#import "BookmarkGatewaySettingsController.h" @interface AdvancedBookmarkEditorController () @@ -68,7 +69,7 @@ switch (section) { case SECTION_ADVANCED_SETTINGS: // advanced settings - return 7; + return 9; default: break; } @@ -100,23 +101,29 @@ { switch([indexPath row]) { - case 0: // 3G Settings + case 0: // Enable/Disable TSG Settings cellType = TableCellIdentifierYesNo; break; - case 1: // 3G screen/color depth - cellType = TableCellIdentifierSelection; - break; - case 2: // 3G performance settings + case 1: // TS Gateway Settings cellType = TableCellIdentifierSubEditor; break; - case 3: // security mode + case 2: // 3G Settings + cellType = TableCellIdentifierYesNo; + break; + case 3: // 3G screen/color depth cellType = TableCellIdentifierSelection; break; - case 4: // remote program - case 5: // work dir + case 4: // 3G performance settings + cellType = TableCellIdentifierSubEditor; + break; + case 5: // security mode + cellType = TableCellIdentifierSelection; + break; + case 6: // remote program + case 7: // work dir cellType = TableCellIdentifierText; break; - case 6: // console mode + case 8: // console mode cellType = TableCellIdentifierYesNo; break; default: @@ -153,6 +160,24 @@ switch(indexPath.row) { case 0: + { + EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell; + [[flagCell label] setText:NSLocalizedString(@"Enable TS Gateway", @"'Enable TS Gateway': Bookmark enable TSG settings")]; + [[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)]; + [[flagCell toggle] setOn:[_params boolForKey:@"enable_tsg_settings"]]; + [[flagCell toggle] addTarget:self action:@selector(toggleSettingValue:) forControlEvents:UIControlEventValueChanged]; + break; + } + case 1: + { + BOOL enable_tsg_settings = [_params boolForKey:@"enable_tsg_settings"]; + EditSubEditTableViewCell* editCell = (EditSubEditTableViewCell*)cell; + [[editCell label] setText:NSLocalizedString(@"TS Gateway Settings", @"'TS Gateway Settings': Bookmark TS Gateway Settings")]; + [[editCell label] setEnabled:enable_tsg_settings]; + [editCell setSelectionStyle:enable_tsg_settings ? UITableViewCellSelectionStyleBlue : UITableViewCellSelectionStyleNone]; + break; + } + case 2: { EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell; [[flagCell label] setText:NSLocalizedString(@"3G Settings", @"'3G Settings': Bookmark enable 3G settings")]; @@ -161,7 +186,7 @@ [[flagCell toggle] addTarget:self action:@selector(toggleSettingValue:) forControlEvents:UIControlEventValueChanged]; break; } - case 1: + case 3: { EditSelectionTableViewCell* selCell = (EditSelectionTableViewCell*)cell; [[selCell label] setText:NSLocalizedString(@"3G Screen", @"'3G Screen': Bookmark 3G Screen settings")]; @@ -172,8 +197,8 @@ [[selCell selection] setEnabled:enable_3G_settings]; [selCell setSelectionStyle:enable_3G_settings ? UITableViewCellSelectionStyleBlue : UITableViewCellSelectionStyleNone]; break; - } - case 2: + } + case 4: { EditSubEditTableViewCell* editCell = (EditSubEditTableViewCell*)cell; [[editCell label] setText:NSLocalizedString(@"3G Performance", @"'3G Performance': Bookmark 3G Performance Settings")]; @@ -181,14 +206,14 @@ [editCell setSelectionStyle:enable_3G_settings ? UITableViewCellSelectionStyleBlue : UITableViewCellSelectionStyleNone]; break; } - case 3: + case 5: { EditSelectionTableViewCell* selCell = (EditSelectionTableViewCell*)cell; [[selCell label] setText:NSLocalizedString(@"Security", @"'Security': Bookmark protocl security settings")]; [[selCell selection] setText:ProtocolSecurityDescription([_params intForKey:@"security"])]; break; } - case 4: + case 6: { EditTextTableViewCell* textCell = (EditTextTableViewCell*)cell; [[textCell label] setText:NSLocalizedString(@"Remote Program", @"'Remote Program': Bookmark remote program settings")]; @@ -198,7 +223,7 @@ [self adjustEditTextTableViewCell:textCell]; break; } - case 5: + case 7: { EditTextTableViewCell* textCell = (EditTextTableViewCell*)cell; [[textCell label] setText:NSLocalizedString(@"Working Directory", @"'Working Directory': Bookmark working directory settings")]; @@ -208,7 +233,7 @@ [self adjustEditTextTableViewCell:textCell]; break; } - case 6: + case 8: { EditFlagTableViewCell* flagCell = (EditFlagTableViewCell*)cell; [[flagCell label] setText:NSLocalizedString(@"Console Mode", @"'Console Mode': Bookmark console mode settings")]; @@ -233,14 +258,18 @@ switch ([indexPath row]) { case 1: + if ([_params boolForKey:@"enable_tsg_settings"]) + viewCtrl = [[[BookmarkGatewaySettingsController alloc] initWithBookmark:_bookmark] autorelease]; + break; + case 3: if ([_params boolForKey:@"enable_3g_settings"]) viewCtrl = [[[ScreenSelectionController alloc] initWithConnectionParams:_params keyPath:@"settings_3g"] autorelease]; break; - case 2: + case 4: if ([_params boolForKey:@"enable_3g_settings"]) viewCtrl = [[[PerformanceEditorController alloc] initWithConnectionParams:_params keyPath:@"settings_3g"] autorelease]; break; - case 3: + case 5: viewCtrl = [[[EditorSelectionController alloc] initWithConnectionParams:_params entries:[NSArray arrayWithObject:@"security"] selections:[NSArray arrayWithObject:SelectionForSecuritySetting()]] autorelease]; break; default: @@ -267,13 +296,13 @@ switch(textField.tag) { // update remote program/work dir settings - case GET_TAG(SECTION_ADVANCED_SETTINGS, 4): + case GET_TAG(SECTION_ADVANCED_SETTINGS, 6): { [_params setValue:[textField text] forKey:@"remote_program"]; break; } - case GET_TAG(SECTION_ADVANCED_SETTINGS, 5): + case GET_TAG(SECTION_ADVANCED_SETTINGS, 7): { [_params setValue:[textField text] forKey:@"working_dir"]; break; @@ -293,12 +322,22 @@ switch(valueSwitch.tag) { case GET_TAG(SECTION_ADVANCED_SETTINGS, 0): - [_params setBool:[valueSwitch isOn] forKey:@"enable_3g_settings"]; + { + [_params setBool:[valueSwitch isOn] forKey:@"enable_tsg_settings"]; NSArray* indexPaths = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:1 inSection:SECTION_ADVANCED_SETTINGS], [NSIndexPath indexPathForRow:2 inSection:SECTION_ADVANCED_SETTINGS], nil]; [[self tableView] reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone]; break; + } + + case GET_TAG(SECTION_ADVANCED_SETTINGS, 2): + { + [_params setBool:[valueSwitch isOn] forKey:@"enable_3g_settings"]; + NSArray* indexPaths = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:3 inSection:SECTION_ADVANCED_SETTINGS], [NSIndexPath indexPathForRow:2 inSection:SECTION_ADVANCED_SETTINGS], nil]; + [[self tableView] reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone]; + break; + } - case GET_TAG(SECTION_ADVANCED_SETTINGS, 6): + case GET_TAG(SECTION_ADVANCED_SETTINGS, 8): [_params setBool:[valueSwitch isOn] forKey:@"console"]; break; diff --git a/client/iOS/Controllers/BookmarkGatewaySettingsController.h b/client/iOS/Controllers/BookmarkGatewaySettingsController.h new file mode 100644 index 000000000..e2c8d5c01 --- /dev/null +++ b/client/iOS/Controllers/BookmarkGatewaySettingsController.h @@ -0,0 +1,25 @@ +/* + Controller to edit ts gateway bookmark settings + + Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz + + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#import "EditorBaseController.h" + +@class ComputerBookmark; +@class ConnectionParams; + +@interface BookmarkGatewaySettingsController : EditorBaseController +{ +@private + ComputerBookmark* _bookmark; + ConnectionParams* _params; +} + +// init for the given bookmark +- (id)initWithBookmark:(ComputerBookmark*)bookmark; + +@end diff --git a/client/iOS/Controllers/BookmarkGatewaySettingsController.m b/client/iOS/Controllers/BookmarkGatewaySettingsController.m new file mode 100644 index 000000000..586ead7c2 --- /dev/null +++ b/client/iOS/Controllers/BookmarkGatewaySettingsController.m @@ -0,0 +1,236 @@ +// +// BookmarkGatewaySettingsController.m +// FreeRDP +// +// Created by Thinstuff Developer on 4/30/13. +// +// + +#import "BookmarkGatewaySettingsController.h" +#import "Bookmark.h" +#import "Utils.h" +#import "EditorSelectionController.h" + +#define SECTION_TSGATEWAY_SETTINGS 0 +#define SECTION_COUNT 1 + +@interface BookmarkGatewaySettingsController () + +@end + +@implementation BookmarkGatewaySettingsController + +- (id)initWithBookmark:(ComputerBookmark*)bookmark +{ + if ((self = [super initWithStyle:UITableViewStyleGrouped])) + { + // set additional settings state according to bookmark data + _bookmark = [bookmark retain]; + _params = [bookmark params]; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + [self setTitle:NSLocalizedString(@"TS Gateway Settings", @"TS Gateway Settings title")]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + // we need to reload the table view data here to have up-to-date data for the + // advanced settings accessory items (like for resolution/color mode settings) + [[self tableView] reloadData]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; +} + +- (void)dealloc +{ + [super dealloc]; + [_bookmark release]; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + // Return the number of sections. + return SECTION_COUNT; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + // Return the number of rows in the section. + switch (section) + { + case SECTION_TSGATEWAY_SETTINGS: // ts gateway settings + return 5; + default: + break; + } + + return 0; +} + +// set section headers +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + switch(section) + { + case SECTION_TSGATEWAY_SETTINGS: + return NSLocalizedString(@"TS Gateway", @"'TS Gateway': ts gateway settings header"); + } + return @"unknown"; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + // determine the required cell type + NSString* cellType = nil; + switch([indexPath section]) + { + case SECTION_TSGATEWAY_SETTINGS: // advanced settings + { + switch([indexPath row]) + { + case 0: // hostname + case 1: // port + case 2: // username + case 4: // domain + cellType = TableCellIdentifierText; + break; + case 3: // password + cellType = TableCellIdentifierSecretText; + break; + default: + break; + } + break; + } + } + NSAssert(cellType != nil, @"Couldn't determine cell type"); + + // get the table view cell + UITableViewCell *cell = [self tableViewCellFromIdentifier:cellType]; + NSAssert(cell, @"Invalid cell"); + + // set cell values + switch([indexPath section]) + { + // advanced settings + case SECTION_TSGATEWAY_SETTINGS: + [self initGatewaySettings:indexPath cell:cell]; + break; + + default: + break; + } + + return cell; +} + +// updates server settings in the UI +- (void)initGatewaySettings:(NSIndexPath*)indexPath cell:(UITableViewCell*)cell +{ + EditTextTableViewCell* textCell = (EditTextTableViewCell*)cell; + [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)]; + switch([indexPath row]) + { + case 0: + { + [[textCell label] setText:NSLocalizedString(@"Host", @"'Host': Bookmark hostname")]; + [[textCell textfield] setText:[_params StringForKey:@"tsg_hostname"]]; + [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")]; + break; + } + case 1: + { + int port = [_params intForKey:@"tsg_port"]; + if (port == 0) port = 443; + [[textCell label] setText:NSLocalizedString(@"Port", @"'Port': Bookmark port")]; + [[textCell textfield] setText:[NSString stringWithFormat:@"%d", port]]; + [[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad]; + break; + } + case 2: + { + [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)]; + [[textCell label] setText:NSLocalizedString(@"Username", @"'Username': Bookmark username")]; + [[textCell textfield] setText:[_params StringForKey:@"tsg_username"]]; + [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")]; + break; + } + case 3: + { + [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)]; + [[textCell label] setText:NSLocalizedString(@"Password", @"'Password': Bookmark password")]; + [[textCell textfield] setText:[_params StringForKey:@"tsg_password"]]; + [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")]; + break; + } + case 4: + { + [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)]; + [[textCell label] setText:NSLocalizedString(@"Domain", @"'Domain': Bookmark domain")]; + [[textCell textfield] setText:[_params StringForKey:@"tsg_domain"]]; + [[textCell textfield] setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")]; + break; + } + default: + NSLog(@"Invalid row index in settings table!"); + break; + } + + [self adjustEditTextTableViewCell:textCell]; +} + + +#pragma mark - +#pragma mark Text Field delegate + +- (BOOL)textFieldShouldReturn:(UITextField*)textField +{ + [textField resignFirstResponder]; + return NO; +} + +- (BOOL)textFieldShouldEndEditing:(UITextField *)textField +{ + switch(textField.tag) + { + // update server settings + case GET_TAG(SECTION_TSGATEWAY_SETTINGS, 0): + [_params setValue:[textField text] forKey:@"tsg_hostname"]; + break; + + case GET_TAG(SECTION_TSGATEWAY_SETTINGS, 1): + [_params setInt:[[textField text] intValue] forKey:@"tsg_port"]; + break; + + case GET_TAG(SECTION_TSGATEWAY_SETTINGS, 2): + [_params setValue:[textField text] forKey:@"tsg_username"]; + break; + + case GET_TAG(SECTION_TSGATEWAY_SETTINGS, 3): + [_params setValue:[textField text] forKey:@"tsg_password"]; + break; + + case GET_TAG(SECTION_TSGATEWAY_SETTINGS, 4): + [_params setValue:[textField text] forKey:@"tsg_domain"]; + break; + + default: + break; + } + return YES; +} + + +@end diff --git a/client/iOS/Controllers/CredentialsEditorController.m b/client/iOS/Controllers/CredentialsEditorController.m index 21e328ad5..a029ad3b6 100644 --- a/client/iOS/Controllers/CredentialsEditorController.m +++ b/client/iOS/Controllers/CredentialsEditorController.m @@ -56,6 +56,12 @@ return YES; } +- (void)dealloc +{ + [super dealloc]; + [_bookmark release]; +} + #pragma mark - #pragma mark Table view data source diff --git a/client/iOS/Controllers/EncryptionController.m b/client/iOS/Controllers/EncryptionController.m index 089e87a44..0f1ae7987 100644 --- a/client/iOS/Controllers/EncryptionController.m +++ b/client/iOS/Controllers/EncryptionController.m @@ -9,6 +9,7 @@ #import "EncryptionController.h" #import "SFHFKeychainUtils.h" +#import "TSXAdditions.h" @interface EncryptionController (Private) @@ -109,7 +110,14 @@ static EncryptionController* _shared_encryption_controller = nil; - (NSString*)keychainDefaultPassword { - return [[UIDevice currentDevice] uniqueIdentifier]; + NSString* password = [[NSUserDefaults standardUserDefaults] stringForKey:@"UUID"]; + if ([password length] == 0) + { + password = [NSString stringWithUUID]; + [[NSUserDefaults standardUserDefaults] setObject:password forKey:@"UUID"]; + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"TSXMasterPasswordVerification"]; + } + return password; } #pragma mark - diff --git a/client/iOS/Controllers/PerformanceEditorController.m b/client/iOS/Controllers/PerformanceEditorController.m index 104b13c13..2e1d4e0eb 100644 --- a/client/iOS/Controllers/PerformanceEditorController.m +++ b/client/iOS/Controllers/PerformanceEditorController.m @@ -56,6 +56,12 @@ return key; } +- (void)dealloc +{ + [super dealloc]; + [_params release]; +} + #pragma mark - #pragma mark Table view data source diff --git a/client/iOS/Controllers/RDPSessionViewController.h b/client/iOS/Controllers/RDPSessionViewController.h index 996c2915f..0c68386e5 100644 --- a/client/iOS/Controllers/RDPSessionViewController.h +++ b/client/iOS/Controllers/RDPSessionViewController.h @@ -57,6 +57,7 @@ AdvancedKeyboardView* _advanced_keyboard_view; BOOL _advanced_keyboard_visible; BOOL _requesting_advanced_keyboard; + CGFloat _keyboard_height_delta; // delayed mouse move event sending NSTimer* _mouse_move_event_timer; diff --git a/client/iOS/Controllers/RDPSessionViewController.m b/client/iOS/Controllers/RDPSessionViewController.m index c431d8c51..436be3fab 100644 --- a/client/iOS/Controllers/RDPSessionViewController.m +++ b/client/iOS/Controllers/RDPSessionViewController.m @@ -50,7 +50,8 @@ _advanced_keyboard_view = nil; _advanced_keyboard_visible = NO; - _requesting_advanced_keyboard = NO; + _requesting_advanced_keyboard = NO; + _keyboard_height_delta = 0; _session_toolbar_visible = NO; @@ -227,8 +228,7 @@ { for(int i = 0 ; i < [string length] ; i++) { - NSString *characterTyped = [string substringWithRange:NSMakeRange(i, 1)]; - unichar curChar = [characterTyped characterAtIndex:0]; + unichar curChar = [string characterAtIndex:i]; // special handling for return/enter key if(curChar == '\n') @@ -581,14 +581,20 @@ #pragma mark iOS Keyboard Notification Handlers - (void)keyboardWillShow:(NSNotification *)notification -{ +{ CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGRect keyboardFrame = [[self view] convertRect:keyboardEndFrame toView:nil]; + + CGFloat newHeightDelta = (keyboardFrame.size.height - _keyboard_height_delta); + if (newHeightDelta < 0.1 && newHeightDelta > -0.1) + return; // nothing changed [UIView beginAnimations:nil context:NULL]; [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]]; CGRect frame = [_session_scrollview frame]; - frame.size.height -= [[self view] convertRect:keyboardEndFrame toView:nil].size.height; + frame.size.height -= newHeightDelta; + _keyboard_height_delta += newHeightDelta; [_session_scrollview setFrame:frame]; [_touchpointer_view setFrame:frame]; [UIView commitAnimations]; @@ -618,6 +624,7 @@ [_session_scrollview setFrame:frame]; [_touchpointer_view setFrame:frame]; [UIView commitAnimations]; + _keyboard_height_delta = 0; } - (void)keyboardDidHide:(NSNotification*)notification diff --git a/client/iOS/Defaults.plist b/client/iOS/Defaults.plist index a60e3be19..801082384 100644 --- a/client/iOS/Defaults.plist +++ b/client/iOS/Defaults.plist @@ -65,6 +65,18 @@ <string></string> <key>console</key> <false/> + <key>enable_tsg_settings</key> + <false/> + <key>tsg_hostname</key> + <string></string> + <key>tsg_port</key> + <integer>443</integer> + <key>tsg_username</key> + <string></string> + <key>tsg_password</key> + <string></string> + <key>tsg_domain</key> + <string></string> </dict> <key>ui.auto_scroll_touchpointer</key> <true/> diff --git a/client/iOS/FreeRDP/ios_freerdp.m b/client/iOS/FreeRDP/ios_freerdp.m index ae3f1e084..ee0cdddc0 100644 --- a/client/iOS/FreeRDP/ios_freerdp.m +++ b/client/iOS/FreeRDP/ios_freerdp.m @@ -221,7 +221,9 @@ ios_run_freerdp(freerdp * instance) [pool release]; pool = nil; } - + + CGContextRelease(mfi->bitmap_context); + mfi->bitmap_context = NULL; mfi->connection_state = TSXConnectionDisconnected; // Cleanup diff --git a/client/iOS/Models/ConnectionParams.m b/client/iOS/Models/ConnectionParams.m index 030216af7..3d1a8605a 100644 --- a/client/iOS/Models/ConnectionParams.m +++ b/client/iOS/Models/ConnectionParams.m @@ -28,16 +28,21 @@ _connection_params = [dict mutableDeepCopy]; - if ([[_connection_params objectForKey:@"password"] isKindOfClass:[NSData class]]) - { - NSString* plaintext_password = [[[EncryptionController sharedEncryptionController] decryptor] decryptString:[_connection_params objectForKey:@"password"]]; - - [self setValue:plaintext_password forKey:@"password"]; - } + [self decryptPasswordForKey:@"password"]; + [self decryptPasswordForKey:@"tsg_password"]; return self; } +- (void)decryptPasswordForKey:(NSString*)key +{ + if ([[_connection_params objectForKey:key] isKindOfClass:[NSData class]]) + { + NSString* plaintext_password = [[[EncryptionController sharedEncryptionController] decryptor] decryptString:[_connection_params objectForKey:key]]; + [self setValue:plaintext_password forKey:key]; + } +} + - (id)initWithBaseDefaultParameters { return [self initWithDictionary:[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"TSXDefaultComputerBookmarkSettings"]]; @@ -89,19 +94,23 @@ [serializable_params setObject:[_connection_params objectForKey:k] forKey:k]; if ([serializable_params objectForKey:@"password"] != nil) - { - NSData* encrypted_password = [[[EncryptionController sharedEncryptionController] encryptor] encryptString:[serializable_params objectForKey:@"password"]]; - - if (encrypted_password) - [serializable_params setObject:encrypted_password forKey:@"password"]; - else - [serializable_params removeObjectForKey:@"password"]; - } + [self serializeDecryptedForKey:@"password" forParams:serializable_params]; + if ([serializable_params objectForKey:@"tsg_password"] != nil) + [self serializeDecryptedForKey:@"tsg_password" forParams:serializable_params]; [coder encodeObject:serializable_params forKey:@"connectionParams"]; [serializable_params release]; } +- (void)serializeDecryptedForKey:(NSString*)key forParams:(NSMutableDictionary*)params +{ + NSData* encrypted_password = [[[EncryptionController sharedEncryptionController] encryptor] encryptString:[params objectForKey:key]]; + + if (encrypted_password) + [params setObject:encrypted_password forKey:key]; + else + [params removeObjectForKey:key]; +} #pragma mark - #pragma mark NSKeyValueCoding diff --git a/client/iOS/Models/RDPKeyboard.m b/client/iOS/Models/RDPKeyboard.m index 17aa66543..f43ed9e5d 100644 --- a/client/iOS/Models/RDPKeyboard.m +++ b/client/iOS/Models/RDPKeyboard.m @@ -238,7 +238,7 @@ if(isupper(character) && _shift_pressed == NO) { character = tolower(character); - [self sendVirtualKey:VK_SHIFT up:NO]; + [self sendVirtualKey:VK_LSHIFT up:NO]; shift_was_sent = YES; } @@ -253,7 +253,7 @@ // send the missing shift up if we had a shift down if(shift_was_sent) - [self sendVirtualKey:VK_SHIFT up:YES]; + [self sendVirtualKey:VK_LSHIFT up:YES]; } - (void)handleSpecialKey:(int)character diff --git a/client/iOS/Models/RDPSession.m b/client/iOS/Models/RDPSession.m index af400bb61..d43f27959 100644 --- a/client/iOS/Models/RDPSession.m +++ b/client/iOS/Models/RDPSession.m @@ -164,6 +164,18 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect" break; } + // ts gateway settings + if ([_params boolForKey:@"enable_tsg_settings"]) + { + settings->GatewayHostname = strdup([_params UTF8StringForKey:@"tsg_hostname"]); + settings->GatewayPort = [_params intForKey:@"tsg_port"]; + settings->GatewayUsername = strdup([_params UTF8StringForKey:@"tsg_username"]); + settings->GatewayPassword = strdup([_params UTF8StringForKey:@"tsg_password"]); + settings->GatewayDomain = strdup([_params UTF8StringForKey:@"tsg_domain"]); + settings->GatewayUsageMethod = TRUE; + settings->GatewayUseSameCredentials = FALSE; + } + // Remote keyboard layout settings->KeyboardLayout = 0x409; @@ -190,7 +202,7 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect" - (CGContextRef)bitmapContext { - return [self mfi]->bitmap_context; + return [self mfi]->bitmap_context; } #pragma mark - diff --git a/client/iOS/iFreeRDP.plist b/client/iOS/iFreeRDP.plist index 8727f716b..d01a583b8 100644 --- a/client/iOS/iFreeRDP.plist +++ b/client/iOS/iFreeRDP.plist @@ -24,11 +24,11 @@ <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> - <string>1.0.0</string> + <string>1.0.1</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>0</string> + <string>1</string> <key>LSRequiresIPhoneOS</key> <true/> <key>NSMainNibFile</key> diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index 07dfdc823..c40e93a0a 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -36,10 +36,11 @@ else() option(WITH_IPP "Use Intel Performance Primitives." OFF) endif() endif() + option(WITH_JPEG "Use JPEG decoding." OFF) -if(APPLE) - option(WITH_CLANG "Build using clang" OFF) +if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_COMPILER_IS_CLANG 1) endif() if(MSVC) @@ -76,7 +77,8 @@ endif() option(WITH_THIRD_PARTY "Build third-party components" OFF) -option(WITH_SERVER_INTERFACE "Build server as a library with an interface" OFF) +option(WITH_CLIENT_INTERFACE "Build clients as a library with an interface" ON) +option(WITH_SERVER_INTERFACE "Build servers as a library with an interface" ON) option(WITH_DEBUG_ALL "Print all debug messages." OFF) diff --git a/cmake/FindNPP.cmake b/cmake/FindNPP.cmake new file mode 100644 index 000000000..7b04ee43a --- /dev/null +++ b/cmake/FindNPP.cmake @@ -0,0 +1,119 @@ +############################################################################### +# +# FindNPP.cmake +# +# NPP_LIBRARY_ROOT_DIR -- Path to the NPP dorectory. +# NPP_INCLUDES -- NPP Include directories. +# NPP_LIBRARIES -- NPP libraries. +# NPP_VERSION -- NPP version in format "major.minor.build". +# +# If not found automatically, please set NPP_LIBRARY_ROOT_DIR +# in CMake or set enviroment varivabe $NPP_ROOT +# +# Author: Anatoly Baksheev, Itseez Ltd. +# +# The MIT License +# +# License for the specific language governing rights and limitations under +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +############################################################################### + +cmake_policy(PUSH) +cmake_minimum_required(VERSION 2.8.0) +cmake_policy(POP) + +if(NOT "${NPP_LIBRARY_ROOT_DIR}" STREQUAL "${NPP_LIBRARY_ROOT_DIR_INTERNAL}") + unset(NPP_INCLUDES CACHE) + unset(NPP_LIBRARIES CACHE) +endif() + +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + if (UNIX OR APPLE) + set(NPP_SUFFIX "32") + else() + set(NPP_SUFFIX "-mt") + endif() +else(CMAKE_SIZEOF_VOID_P EQUAL 4) + if (UNIX OR APPLE) + set(NPP_SUFFIX "64") + else() + set(NPP_SUFFIX "-mt-x64") + endif() +endif(CMAKE_SIZEOF_VOID_P EQUAL 4) + +find_path(CUDA_ROOT_DIR "doc/CUDA_Toolkit_Release_Notes.txt" + PATHS "/Developer/NVIDIA" + PATH_SUFFIXES "CUDA-5.0" + DOC "CUDA root directory") + +find_path(NPP_INCLUDES "npp.h" + PATHS "${CUDA_ROOT_DIR}" + PATH_SUFFIXES "include" + DOC "NPP include directory") +mark_as_advanced(NPP_INCLUDES) + +find_library(NPP_LIBRARIES + NAMES "npp" "libnpp" "npp${NPP_SUFFIX}" "libnpp${NPP_SUFFIX}" + PATHS "${CUDA_ROOT_DIR}" + PATH_SUFFIXES "lib" + DOC "NPP library") +mark_as_advanced(NPP_LIBRARIES) + +if(EXISTS ${NPP_INCLUDES}/nppversion.h) + file(STRINGS ${NPP_INCLUDES}/nppversion.h npp_major REGEX "#define NPP_VERSION_MAJOR.*") + file(STRINGS ${NPP_INCLUDES}/nppversion.h npp_minor REGEX "#define NPP_VERSION_MINOR.*") + file(STRINGS ${NPP_INCLUDES}/nppversion.h npp_build REGEX "#define NPP_VERSION_BUILD.*") + + string(REGEX REPLACE "#define NPP_VERSION_MAJOR[ \t]+|//.*" "" npp_major ${npp_major}) + string(REGEX REPLACE "#define NPP_VERSION_MINOR[ \t]+|//.*" "" npp_minor ${npp_minor}) + string(REGEX REPLACE "#define NPP_VERSION_BUILD[ \t]+|//.*" "" npp_build ${npp_build}) + + string(REGEX MATCH "[0-9]+" npp_major ${npp_major}) + string(REGEX MATCH "[0-9]+" npp_minor ${npp_minor}) + string(REGEX MATCH "[0-9]+" npp_build ${npp_build}) + set(NPP_VERSION "${npp_major}.${npp_minor}.${npp_build}") +endif() + +if(NOT EXISTS ${NPP_LIBRARIES} OR NOT EXISTS ${NPP_INCLUDES}/npp.h) + set(NPP_FOUND FALSE) + message(WARNING "NPP headers/libraries are not found. Please specify NPP_LIBRARY_ROOT_DIR in CMake or set $NPP_ROOT_DIR.") +endif() + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(NPP + REQUIRED_VARS + NPP_INCLUDES + NPP_LIBRARIES + NPP_VERSION) + +if(APPLE) + # We need to add the path to cudart to the linker using rpath, since the library name for the cuda libraries is prepended with @rpath. + get_filename_component(_cuda_path_to_npp "${NPP_LIBRARIES}" PATH) + if(_cuda_path_to_npp) + list(APPEND NPP_LIBRARIES -Wl,-rpath "-Wl,${_cuda_path_to_npp}") + endif() +endif() + +set(NPP_FOUND TRUE) + +set(NPP_LIBRARY_ROOT_DIR_INTERNAL "${NPP_LIBRARY_ROOT_DIR}" CACHE INTERNAL + "This is the value of the last time NPP_LIBRARY_ROOT_DIR was set successfully." FORCE) + diff --git a/cmake/FindPAM.cmake b/cmake/FindPAM.cmake new file mode 100644 index 000000000..1fdaa6cae --- /dev/null +++ b/cmake/FindPAM.cmake @@ -0,0 +1,40 @@ +# - Try to find the PAM libraries +# Once done this will define +# +# PAM_FOUND - system has pam +# PAM_INCLUDE_DIR - the pam include directory +# PAM_LIBRARIES - libpam library + +if (PAM_INCLUDE_DIR AND PAM_LIBRARY) + set(PAM_FIND_QUIETLY TRUE) +endif (PAM_INCLUDE_DIR AND PAM_LIBRARY) + +find_path(PAM_INCLUDE_DIR NAMES security/pam_appl.h pam/pam_appl.h) +find_library(PAM_LIBRARY pam) +find_library(DL_LIBRARY dl) + +if (PAM_INCLUDE_DIR AND PAM_LIBRARY) + set(PAM_FOUND TRUE) + if (DL_LIBRARY) + set(PAM_LIBRARIES ${PAM_LIBRARY} ${DL_LIBRARY}) + else (DL_LIBRARY) + set(PAM_LIBRARIES ${PAM_LIBRARY}) + endif (DL_LIBRARY) + + if (EXISTS ${PAM_INCLUDE_DIR}/pam/pam_appl.h) + set(HAVE_PAM_PAM_APPL_H 1) + endif (EXISTS ${PAM_INCLUDE_DIR}/pam/pam_appl.h) +endif (PAM_INCLUDE_DIR AND PAM_LIBRARY) + +if (PAM_FOUND) + if (NOT PAM_FIND_QUIETLY) + message(STATUS "Found PAM: ${PAM_LIBRARIES}") + endif (NOT PAM_FIND_QUIETLY) +else (PAM_FOUND) + if (PAM_FIND_REQUIRED) + message(FATAL_ERROR "PAM was not found") + endif(PAM_FIND_REQUIRED) +endif (PAM_FOUND) + +mark_as_advanced(PAM_INCLUDE_DIR PAM_LIBRARY DL_LIBRARY) + diff --git a/cmake/FindXi.cmake b/cmake/FindXi.cmake new file mode 100644 index 000000000..d01f4002b --- /dev/null +++ b/cmake/FindXi.cmake @@ -0,0 +1,56 @@ +# - Find Xi +# Find the Xi libraries +# +# This module defines the following variables: +# XI_FOUND - true if XI_INCLUDE_DIR & XI_LIBRARY are found +# XI_LIBRARIES - Set when XI_LIBRARY is found +# XI_INCLUDE_DIRS - Set when XI_INCLUDE_DIR is found +# +# XI_INCLUDE_DIR - where to find XInput2.h, etc. +# XI_LIBRARY - the Xi library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br> +# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +include(CheckSymbolExists) + +find_path(XI_INCLUDE_DIR NAMES X11/extensions/XInput2.h + DOC "The Xi include directory") + +find_library(XI_LIBRARY NAMES Xi + DOC "The Xi library") + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xi DEFAULT_MSG XI_LIBRARY XI_INCLUDE_DIR) + +if(XI_FOUND) + check_symbol_exists(XITouchClass "${XI_INCLUDE_DIR}/X11/extensions/XInput2.h" HAVE_XI_TOUCH_CLASS) + + if (NOT HAVE_XI_TOUCH_CLASS) + set(XI_FOUND 0) + endif() +endif() + +if(XI_FOUND) + set(XI_LIBRARIES ${XI_LIBRARY}) + set(XI_INCLUDE_DIRS ${XI_INCLUDE_DIR}) +endif() + +mark_as_advanced(XI_INCLUDE_DIR XI_LIBRARY) + diff --git a/cmake/FindXrender.cmake b/cmake/FindXrender.cmake new file mode 100644 index 000000000..5264604df --- /dev/null +++ b/cmake/FindXrender.cmake @@ -0,0 +1,44 @@ +# - Find Xrender +# Find the Xrender libraries +# +# This module defines the following variables: +# Xrender_FOUND - true if Xrender_INCLUDE_DIR & Xrender_LIBRARY are found +# Xrender_LIBRARIES - Set when Xrender_LIBRARY is found +# Xrender_INCLUDE_DIRS - Set when Xrender_INCLUDE_DIR is found +# +# Xrender_INCLUDE_DIR - where to find Xrendernput2.h, etc. +# Xrender_LIBRARY - the Xrender library +# + +#============================================================================= +# Copyright 2013 Corey Clayton <can.of.tuna@gmail.com> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(Xrender_INCLUDE_DIR NAMES X11/extensions/Xrender.h + DOC "The Xrender include directory") + +find_library(Xrender_LIBRARY NAMES Xrender + DOC "The Xrender library") + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xrender DEFAULT_MSG Xrender_LIBRARY Xrender_INCLUDE_DIR) + +if(Xrender_FOUND) + set(XRENDER_LIBRARIES ${Xrender_LIBRARY}) + set(XRENDER_INCLUDE_DIRS ${Xrender_INCLUDE_DIR}) +endif() + +mark_as_advanced(XRENDER_INCLUDE_DIRS XRENDER_LIBRARIES) + diff --git a/cunit/test_freerdp.c b/cunit/test_freerdp.c index f9a9644a5..636da91c9 100644 --- a/cunit/test_freerdp.c +++ b/cunit/test_freerdp.c @@ -70,7 +70,7 @@ void assert_stream(wStream* s, BYTE* data, int length, const char* func, int lin BYTE* actual_data; actual_data = s->buffer; - actual_length = stream_get_length(s); + actual_length = Stream_GetPosition(s); if (actual_length != length) { diff --git a/cunit/test_mcs.c b/cunit/test_mcs.c index f9a0e9dba..b33d7fa71 100644 --- a/cunit/test_mcs.c +++ b/cunit/test_mcs.c @@ -111,5 +111,5 @@ void test_mcs_write_connect_initial(void) ASSERT_STREAM(s, (BYTE*) mcs_connect_initial_expected, sizeof(mcs_connect_initial_expected)); - stream_free(s); + Stream_Free(s, TRUE); } diff --git a/cunit/test_nsc.c b/cunit/test_nsc.c index 5376c4a31..4ec74aa64 100644 --- a/cunit/test_nsc.c +++ b/cunit/test_nsc.c @@ -363,11 +363,11 @@ void test_nsc_encode(void) for (i = 0; i < 30000; i++) { - stream_set_pos(enc_stream, 0); + Stream_SetPosition(enc_stream, 0); nsc_compose_message(context, enc_stream, rgb_data, 64, 64, 64 * 3); } - /*winpr_HexDump(stream_get_head(enc_stream), stream_get_length(enc_stream));*/ - nsc_process_message(context, 32, 64, 64, stream_get_head(enc_stream), stream_get_length(enc_stream)); + /*winpr_HexDump(Stream_Buffer(enc_stream), Stream_GetPosition(enc_stream));*/ + nsc_process_message(context, 32, 64, 64, Stream_Buffer(enc_stream), Stream_GetPosition(enc_stream)); /*winpr_HexDump(context->bmpdata, 64 * 64 * 4);*/ stream_free(enc_stream); diff --git a/cunit/test_orders.c b/cunit/test_orders.c index 08d030a65..2f6d2b82d 100644 --- a/cunit/test_orders.c +++ b/cunit/test_orders.c @@ -91,7 +91,7 @@ void test_read_dstblt_order(void) CU_ASSERT(dstblt.nHeight == 311); CU_ASSERT(dstblt.bRop == 0); - CU_ASSERT(stream_get_length(s) == (sizeof(dstblt_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(dstblt_order) - 1)); } BYTE patblt_order[] = "\x1a\x00\xc3\x01\x0d\x00\x0d\x00\xf0\xff\xff\x00\x5b\xef\x00\x81"; @@ -121,7 +121,7 @@ void test_read_patblt_order(void) CU_ASSERT(patblt.brush.y == 0); CU_ASSERT(patblt.brush.style == (BMF_1BPP | CACHED_BRUSH)); - CU_ASSERT(stream_get_length(s) == (sizeof(patblt_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(patblt_order) - 1)); } BYTE scrblt_order[] = "\x07\x00\xa1\x01\xf1\x00\xcc\x2f\x01\x8e\x00"; @@ -148,7 +148,7 @@ void test_read_scrblt_order(void) CU_ASSERT(scrblt.nXSrc == 303); CU_ASSERT(scrblt.nYSrc == 142); - CU_ASSERT(stream_get_length(s) == (sizeof(scrblt_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(scrblt_order) - 1)); } BYTE opaque_rect_order[] = "\x00\x04\x00\x03\x73\x02\x06"; @@ -173,7 +173,7 @@ void test_read_opaque_rect_order(void) CU_ASSERT(opaque_rect.nHeight == 768); CU_ASSERT(opaque_rect.color == 0x00060273); - CU_ASSERT(stream_get_length(s) == (sizeof(opaque_rect_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(opaque_rect_order) - 1)); } BYTE draw_nine_grid_order[] = "\xfb\xf9\x0d\x00"; @@ -202,7 +202,7 @@ void test_read_draw_nine_grid_order(void) CU_ASSERT(draw_nine_grid.srcBottom == 33); CU_ASSERT(draw_nine_grid.bitmapId == 13); - CU_ASSERT(stream_get_length(s) == (sizeof(draw_nine_grid_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(draw_nine_grid_order) - 1)); } @@ -253,7 +253,7 @@ void test_read_multi_opaque_rect_order(void) CU_ASSERT(multi_opaque_rect.rectangles[4].width == 241); CU_ASSERT(multi_opaque_rect.rectangles[4].height == 1); - CU_ASSERT(stream_get_length(s) == (sizeof(multi_opaque_rect_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(multi_opaque_rect_order) - 1)); } BYTE line_to_order[] = "\x03\xb1\x0e\xa6\x5b\xef\x00"; @@ -288,7 +288,7 @@ void test_read_line_to_order(void) CU_ASSERT(line_to.penWidth == 0); CU_ASSERT(line_to.penColor == 0x00EF5B); - CU_ASSERT(stream_get_length(s) == (sizeof(line_to_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(line_to_order) - 1)); } BYTE polyline_order[] = @@ -357,7 +357,7 @@ void test_read_polyline_order(void) CU_ASSERT(polyline.points[31].x == -153); CU_ASSERT(polyline.points[32].x == 0); - CU_ASSERT(stream_get_length(s) == (sizeof(polyline_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(polyline_order) - 1)); } BYTE glyph_index_order_1[] = @@ -387,7 +387,7 @@ void test_read_glyph_index_order(void) CU_ASSERT(glyph_index.bkRight == 618); - CU_ASSERT(stream_get_length(s) == (sizeof(glyph_index_order_1) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(glyph_index_order_1) - 1)); s->pointer = s->buffer = glyph_index_order_2; @@ -412,7 +412,7 @@ void test_read_glyph_index_order(void) CU_ASSERT(glyph_index.x == 524); CU_ASSERT(glyph_index.y == 377); - CU_ASSERT(stream_get_length(s) == (sizeof(glyph_index_order_2) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(glyph_index_order_2) - 1)); } BYTE fast_index_order[] = @@ -450,7 +450,7 @@ void test_read_fast_index_order(void) CU_ASSERT(fast_index.x == -32768); CU_ASSERT(fast_index.y == 124); - CU_ASSERT(stream_get_length(s) == (sizeof(fast_index_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(fast_index_order) - 1)); } BYTE fast_glyph_order[] = @@ -486,7 +486,7 @@ void test_read_fast_glyph_order(void) CU_ASSERT(fast_glyph.x == -32768); CU_ASSERT(fast_glyph.y == 187); - CU_ASSERT(stream_get_length(s) == (sizeof(fast_glyph_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(fast_glyph_order) - 1)); } BYTE polygon_cb_order[] = @@ -520,7 +520,7 @@ void test_read_polygon_cb_order(void) CU_ASSERT(polygon_cb.numPoints == 3); CU_ASSERT(polygon_cb.cbData == 5); - CU_ASSERT(stream_get_length(s) == (sizeof(polygon_cb_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(polygon_cb_order) - 1)); } BYTE cache_bitmap_order[] = "\x00\x00\x10\x01\x08\x01\x00\x00\x00\x10"; @@ -546,7 +546,7 @@ void test_read_cache_bitmap_order(void) CU_ASSERT(cache_bitmap.bitmapLength == 1); CU_ASSERT(cache_bitmap.cacheIndex == 0); - CU_ASSERT(stream_get_length(s) == (sizeof(cache_bitmap_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(cache_bitmap_order) - 1)); } BYTE cache_bitmap_v2_order[] = @@ -588,7 +588,7 @@ void test_read_cache_bitmap_v2_order(void) CU_ASSERT(cache_bitmap_v2.bitmapLength == 220); CU_ASSERT(cache_bitmap_v2.cacheIndex == 32767); - CU_ASSERT(stream_get_length(s) == (sizeof(cache_bitmap_v2_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(cache_bitmap_v2_order) - 1)); } BYTE cache_bitmap_v3_order[] = @@ -622,7 +622,7 @@ void test_read_cache_bitmap_v3_order(void) CU_ASSERT(cache_bitmap_v3.bitmapData.height == 2); CU_ASSERT(cache_bitmap_v3.bitmapData.length == 40); - CU_ASSERT(stream_get_length(s) == (sizeof(cache_bitmap_v3_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(cache_bitmap_v3_order) - 1)); } BYTE cache_brush_order[] = "\x00\x01\x08\x08\x81\x08\xaa\x55\xaa\x55\xaa\x55\xaa\x55"; @@ -646,7 +646,7 @@ void test_read_cache_brush_order(void) CU_ASSERT(cache_brush.style == 0x81); CU_ASSERT(cache_brush.length == 8); - CU_ASSERT(stream_get_length(s) == (sizeof(cache_brush_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(cache_brush_order) - 1)); } BYTE create_offscreen_bitmap_order[] = "\x00\x80\x60\x01\x10\x00\x01\x00\x02\x00"; @@ -674,7 +674,7 @@ void test_read_create_offscreen_bitmap_order(void) CU_ASSERT(create_offscreen_bitmap.cy == 16); CU_ASSERT(create_offscreen_bitmap.deleteList.cIndices == 1); - CU_ASSERT(stream_get_length(s) == (sizeof(create_offscreen_bitmap_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(create_offscreen_bitmap_order) - 1)); } BYTE switch_surface_order[] = "\xff\xff"; @@ -693,7 +693,7 @@ void test_read_switch_surface_order(void) CU_ASSERT(switch_surface.bitmapId == 0xFFFF); - CU_ASSERT(stream_get_length(s) == (sizeof(switch_surface_order) - 1)); + CU_ASSERT(Stream_GetPosition(s) == (sizeof(switch_surface_order) - 1)); } int opaque_rect_count; diff --git a/cunit/test_rfx.c b/cunit/test_rfx.c index a69f85447..aae5b2472 100644 --- a/cunit/test_rfx.c +++ b/cunit/test_rfx.c @@ -307,10 +307,10 @@ void test_decode(void) wStream* s; s = stream_new(sizeof(y_data) + sizeof(cb_data) + sizeof(cr_data)); - stream_write(s, y_data, sizeof(y_data)); - stream_write(s, cb_data, sizeof(cb_data)); - stream_write(s, cr_data, sizeof(cr_data)); - stream_set_pos(s, 0); + Stream_Write(s, y_data, sizeof(y_data)); + Stream_Write(s, cb_data, sizeof(cb_data)); + Stream_Write(s, cr_data, sizeof(cr_data)); + Stream_SetPosition(s, 0); context = rfx_context_new(); context->mode = RLGR3; @@ -321,7 +321,7 @@ void test_decode(void) sizeof(cr_data), test_quantization_values, decode_buffer); rfx_context_free(context); - stream_free(s); + Stream_Free(s, TRUE); dump_ppm_image(decode_buffer); } @@ -352,13 +352,13 @@ void test_encode(void) //dump_buffer(context->priv->cb_g_buffer, 4096); /*printf("*** Y ***\n"); - winpr_HexDump(stream_get_head(enc_stream), y_size); + winpr_HexDump(Stream_Buffer(enc_stream), y_size); printf("*** Cb ***\n"); - winpr_HexDump(stream_get_head(enc_stream) + y_size, cb_size); + winpr_HexDump(Stream_Buffer(enc_stream) + y_size, cb_size); printf("*** Cr ***\n"); - winpr_HexDump(stream_get_head(enc_stream) + y_size + cb_size, cr_size);*/ + winpr_HexDump(Stream_Buffer(enc_stream) + y_size + cb_size, cr_size);*/ - stream_set_pos(enc_stream, 0); + Stream_SetPosition(enc_stream, 0); rfx_decode_rgb(context, enc_stream, y_size, test_quantization_values, cb_size, test_quantization_values, @@ -398,9 +398,9 @@ void test_message(void) stream_clear(s); rfx_compose_message(context, s, &rect, 1, rgb_data, 100, 80, 100 * 3); - stream_seal(s); + Stream_SealLength(s); /*hexdump(buffer, size);*/ - stream_set_pos(s, 0); + Stream_SetPosition(s, 0); message = rfx_process_message(context, s->pointer, s->capacity); if (i == 0) { @@ -410,7 +410,7 @@ void test_message(void) } } rfx_message_free(context, message); - stream_free(s); + Stream_Free(s, TRUE); } rfx_context_free(context); diff --git a/docs/README.ios b/docs/README.ios index 38f6a24a7..ad7a045be 100644 --- a/docs/README.ios +++ b/docs/README.ios @@ -52,6 +52,14 @@ If you want to specify an output directory add CONFIGURATION_BUILD_DIR=<output-p * If using XCode choose "Open Other" from the welcome screen, browse to the FreeRDP root directory and select FreeRDP.xcodeproj. +* If you switch between platforms (OS and SIMULATOR) please remove CMakeCache.txt and CMakeFiles/ before calling cmake again. + Otherwise build errors might occur (this seems to be a bug with cmake or the cmake scripts). To switch between platforms do: + + rm CMakeCache.txt + rm -rf CMakeFiles/ + + before you run a new cmake command with the desired platform. + cmake variables =============== diff --git a/include/freerdp/channels/channels.h b/include/freerdp/channels/channels.h index 052b90931..ffdeb3612 100644 --- a/include/freerdp/channels/channels.h +++ b/include/freerdp/channels/channels.h @@ -48,6 +48,8 @@ FREERDP_API BOOL freerdp_channels_check_fds(rdpChannels* channels, freerdp* inst FREERDP_API wMessage* freerdp_channels_pop_event(rdpChannels* channels); FREERDP_API void freerdp_channels_close(rdpChannels* channels, freerdp* instance); +FREERDP_API void* freerdp_channels_get_static_channel_interface(rdpChannels* channels, const char* name); + FREERDP_API HANDLE freerdp_channels_get_event_handle(freerdp* instance); FREERDP_API int freerdp_channels_process_pending_messages(freerdp* instance); diff --git a/include/freerdp/client.h b/include/freerdp/client.h index 87d998834..a65a83cf6 100644 --- a/include/freerdp/client.h +++ b/include/freerdp/client.h @@ -29,12 +29,22 @@ typedef struct rdp_client rdpClient; extern "C" { #endif +#define FREERDP_WINDOW_STATE_NORMAL 0 +#define FREERDP_WINDOW_STATE_MINIMIZED 1 +#define FREERDP_WINDOW_STATE_MAXIMIZED 2 +#define FREERDP_WINDOW_STATE_FULLSCREEN 3 +#define FREERDP_WINDOW_STATE_ACTIVE 4 + typedef void (*pOnResizeWindow)(freerdp* instance, int width, int height); +typedef void (*pOnWindowStateChange)(freerdp* instance, int state); +typedef void (*pOnErrorInfo)(freerdp* instance, UINT32 code); typedef void (*pOnParamChange)(freerdp* instance, int id); struct rdp_client { pOnResizeWindow OnResizeWindow; + pOnWindowStateChange OnWindowStateChange; + pOnErrorInfo OnErrorInfo; pOnParamChange OnParamChange; }; diff --git a/include/freerdp/client/drdynvc.h b/include/freerdp/client/drdynvc.h new file mode 100644 index 000000000..bb74ee26e --- /dev/null +++ b/include/freerdp/client/drdynvc.h @@ -0,0 +1,43 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Dynamic Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_CLIENT_DRDYNVC_H +#define FREERDP_CHANNEL_CLIENT_DRDYNVC_H + +/** + * Client Interface + */ + +typedef struct _drdynvc_client_context DrdynvcClientContext; + +typedef int (*pcDrdynvcGetVersion)(DrdynvcClientContext* context); +typedef int (*pcDrdynvcOnChannelConnected)(DrdynvcClientContext* context, const char* name, void* pInterface); +typedef int (*pcDrdynvcOnChannelDisconnected)(DrdynvcClientContext* context, const char* name, void* pInterface); + +struct _drdynvc_client_context +{ + void* handle; + void* custom; + + pcDrdynvcGetVersion GetVersion; + pcDrdynvcOnChannelConnected OnChannelConnected; + pcDrdynvcOnChannelDisconnected OnChannelDisconnected; +}; + +#endif /* FREERDP_CHANNEL_CLIENT_DRDYNVC_H */ diff --git a/include/freerdp/client/rdpei.h b/include/freerdp/client/rdpei.h new file mode 100644 index 000000000..a38c940dc --- /dev/null +++ b/include/freerdp/client/rdpei.h @@ -0,0 +1,86 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Dynamic Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_CLIENT_RDPEI_H +#define FREERDP_CHANNEL_CLIENT_RDPEI_H + +#define CONTACT_DATA_CONTACTRECT_PRESENT 0x0001 +#define CONTACT_DATA_ORIENTATION_PRESENT 0x0002 +#define CONTACT_DATA_PRESSURE_PRESENT 0x0004 + +#define CONTACT_FLAG_DOWN 0x0001 +#define CONTACT_FLAG_UPDATE 0x0002 +#define CONTACT_FLAG_UP 0x0004 +#define CONTACT_FLAG_INRANGE 0x0008 +#define CONTACT_FLAG_INCONTACT 0x0010 +#define CONTACT_FLAG_CANCELED 0x0020 + +struct _RDPINPUT_CONTACT_DATA +{ + UINT32 contactId; + UINT32 fieldsPresent; + INT32 x; + INT32 y; + UINT32 contactFlags; + INT32 contactRectLeft; + INT32 contactRectTop; + INT32 contactRectRight; + INT32 contactRectBottom; + UINT32 orientation; + UINT32 pressure; +}; +typedef struct _RDPINPUT_CONTACT_DATA RDPINPUT_CONTACT_DATA; + +struct _RDPINPUT_TOUCH_FRAME +{ + UINT32 contactCount; + UINT64 frameOffset; + RDPINPUT_CONTACT_DATA* contacts; +}; +typedef struct _RDPINPUT_TOUCH_FRAME RDPINPUT_TOUCH_FRAME; + +/** + * Client Interface + */ + +#define RDPEI_DVC_CHANNEL_NAME "Microsoft::Windows::RDS::Input" + +typedef struct _rdpei_client_context RdpeiClientContext; + +typedef int (*pcRdpeiGetVersion)(RdpeiClientContext* context); +typedef int (*pcRdpeiAddContact)(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact); + +typedef int (*pcRdpeiContactBegin)(RdpeiClientContext* context, int externalId); +typedef int (*pcRdpeiContactUpdate)(RdpeiClientContext* context, int externalId); +typedef int (*pcRdpeiContactEnd)(RdpeiClientContext* context, int externalId); + +struct _rdpei_client_context +{ + void* handle; + void* custom; + + pcRdpeiGetVersion GetVersion; + + pcRdpeiAddContact AddContact; + pcRdpeiContactBegin ContactBegin; + pcRdpeiContactUpdate ContactUpdate; + pcRdpeiContactEnd ContactEnd; +}; + +#endif /* FREERDP_CHANNEL_CLIENT_RDPEI_H */ diff --git a/include/freerdp/dvc.h b/include/freerdp/dvc.h index f2025a448..a2350bfe8 100644 --- a/include/freerdp/dvc.h +++ b/include/freerdp/dvc.h @@ -67,6 +67,8 @@ struct _IWTSListener /* Retrieves the listener-specific configuration. */ int (*GetConfiguration) (IWTSListener* pListener, void** ppPropertyBag); + + void* pInterface; }; struct _IWTSVirtualChannel @@ -115,6 +117,10 @@ struct _IWTSPlugin /* Notifies the plug-in that the Remote Desktop Connection (RDC) client has terminated. */ int (*Terminated) (IWTSPlugin* pPlugin); + + /* Extended */ + + void* pInterface; }; struct _IWTSListenerCallback diff --git a/include/freerdp/error.h b/include/freerdp/error.h index 0bb673956..27d54886a 100644 --- a/include/freerdp/error.h +++ b/include/freerdp/error.h @@ -24,6 +24,110 @@ extern "C" { #endif +/** + * Error Info Codes (Error Info PDU) + */ + +/* Protocol-independent codes */ +#define ERRINFO_RPC_INITIATED_DISCONNECT 0x00000001 +#define ERRINFO_RPC_INITIATED_LOGOFF 0x00000002 +#define ERRINFO_IDLE_TIMEOUT 0x00000003 +#define ERRINFO_LOGON_TIMEOUT 0x00000004 +#define ERRINFO_DISCONNECTED_BY_OTHER_CONNECTION 0x00000005 +#define ERRINFO_OUT_OF_MEMORY 0x00000006 +#define ERRINFO_SERVER_DENIED_CONNECTION 0x00000007 +#define ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES 0x00000009 +#define ERRINFO_SERVER_FRESH_CREDENTIALS_REQUIRED 0x0000000A +#define ERRINFO_RPC_INITIATED_DISCONNECT_BY_USER 0x0000000B +#define ERRINFO_LOGOFF_BY_USER 0x0000000C + +/* Protocol-independent licensing codes */ +#define ERRINFO_LICENSE_INTERNAL 0x00000100 +#define ERRINFO_LICENSE_NO_LICENSE_SERVER 0x00000101 +#define ERRINFO_LICENSE_NO_LICENSE 0x00000102 +#define ERRINFO_LICENSE_BAD_CLIENT_MSG 0x00000103 +#define ERRINFO_LICENSE_HWID_DOESNT_MATCH_LICENSE 0x00000104 +#define ERRINFO_LICENSE_BAD_CLIENT_LICENSE 0x00000105 +#define ERRINFO_LICENSE_CANT_FINISH_PROTOCOL 0x00000106 +#define ERRINFO_LICENSE_CLIENT_ENDED_PROTOCOL 0x00000107 +#define ERRINFO_LICENSE_BAD_CLIENT_ENCRYPTION 0x00000108 +#define ERRINFO_LICENSE_CANT_UPGRADE_LICENSE 0x00000109 +#define ERRINFO_LICENSE_NO_REMOTE_CONNECTIONS 0x0000010A + +/* RDP specific codes */ +#define ERRINFO_UNKNOWN_DATA_PDU_TYPE 0x000010C9 +#define ERRINFO_UNKNOWN_PDU_TYPE 0x000010CA +#define ERRINFO_DATA_PDU_SEQUENCE 0x000010CB +#define ERRINFO_CONTROL_PDU_SEQUENCE 0x000010CD +#define ERRINFO_INVALID_CONTROL_PDU_ACTION 0x000010CE +#define ERRINFO_INVALID_INPUT_PDU_TYPE 0x000010CF +#define ERRINFO_INVALID_INPUT_PDU_MOUSE 0x000010D0 +#define ERRINFO_INVALID_REFRESH_RECT_PDU 0x000010D1 +#define ERRINFO_CREATE_USER_DATA_FAILED 0x000010D2 +#define ERRINFO_CONNECT_FAILED 0x000010D3 +#define ERRINFO_CONFIRM_ACTIVE_HAS_WRONG_SHAREID 0x000010D4 +#define ERRINFO_CONFIRM_ACTIVE_HAS_WRONG_ORIGINATOR 0x000010D5 +#define ERRINFO_PERSISTENT_KEY_PDU_BAD_LENGTH 0x000010DA +#define ERRINFO_PERSISTENT_KEY_PDU_ILLEGAL_FIRST 0x000010DB +#define ERRINFO_PERSISTENT_KEY_PDU_TOO_MANY_TOTAL_KEYS 0x000010DC +#define ERRINFO_PERSISTENT_KEY_PDU_TOO_MANY_CACHE_KEYS 0x000010DD +#define ERRINFO_INPUT_PDU_BAD_LENGTH 0x000010DE +#define ERRINFO_BITMAP_CACHE_ERROR_PDU_BAD_LENGTH 0x000010DF +#define ERRINFO_SECURITY_DATA_TOO_SHORT 0x000010E0 +#define ERRINFO_VCHANNEL_DATA_TOO_SHORT 0x000010E1 +#define ERRINFO_SHARE_DATA_TOO_SHORT 0x000010E2 +#define ERRINFO_BAD_SUPPRESS_OUTPUT_PDU 0x000010E3 +#define ERRINFO_CONFIRM_ACTIVE_PDU_TOO_SHORT 0x000010E5 +#define ERRINFO_CAPABILITY_SET_TOO_SMALL 0x000010E7 +#define ERRINFO_CAPABILITY_SET_TOO_LARGE 0x000010E8 +#define ERRINFO_NO_CURSOR_CACHE 0x000010E9 +#define ERRINFO_BAD_CAPABILITIES 0x000010EA +#define ERRINFO_VIRTUAL_CHANNEL_DECOMPRESSION 0x000010EC +#define ERRINFO_INVALID_VC_COMPRESSION_TYPE 0x000010ED +#define ERRINFO_INVALID_CHANNEL_ID 0x000010EF +#define ERRINFO_VCHANNELS_TOO_MANY 0x000010F0 +#define ERRINFO_REMOTEAPP_NOT_ENABLED 0x000010F3 +#define ERRINFO_CACHE_CAP_NOT_SET 0x000010F4 +#define ERRINFO_BITMAP_CACHE_ERROR_PDU_BAD_LENGTH2 0x000010F5 +#define ERRINFO_OFFSCREEN_CACHE_ERROR_PDU_BAD_LENGTH 0x000010F6 +#define ERRINFO_DRAWNINEGRID_CACHE_ERROR_PDU_BAD_LENGTH 0x000010F7 +#define ERRINFO_GDIPLUS_PDU_BAD_LENGTH 0x000010F8 +#define ERRINFO_SECURITY_DATA_TOO_SHORT2 0x00001111 +#define ERRINFO_SECURITY_DATA_TOO_SHORT3 0x00001112 +#define ERRINFO_SECURITY_DATA_TOO_SHORT4 0x00001113 +#define ERRINFO_SECURITY_DATA_TOO_SHORT5 0x00001114 +#define ERRINFO_SECURITY_DATA_TOO_SHORT6 0x00001115 +#define ERRINFO_SECURITY_DATA_TOO_SHORT7 0x00001116 +#define ERRINFO_SECURITY_DATA_TOO_SHORT8 0x00001117 +#define ERRINFO_SECURITY_DATA_TOO_SHORT9 0x00001118 +#define ERRINFO_SECURITY_DATA_TOO_SHORT10 0x00001119 +#define ERRINFO_SECURITY_DATA_TOO_SHORT11 0x0000111A +#define ERRINFO_SECURITY_DATA_TOO_SHORT12 0x0000111B +#define ERRINFO_SECURITY_DATA_TOO_SHORT13 0x0000111C +#define ERRINFO_SECURITY_DATA_TOO_SHORT14 0x0000111D +#define ERRINFO_SECURITY_DATA_TOO_SHORT15 0x0000111E +#define ERRINFO_SECURITY_DATA_TOO_SHORT16 0x0000111F +#define ERRINFO_SECURITY_DATA_TOO_SHORT17 0x00001120 +#define ERRINFO_SECURITY_DATA_TOO_SHORT18 0x00001121 +#define ERRINFO_SECURITY_DATA_TOO_SHORT19 0x00001122 +#define ERRINFO_SECURITY_DATA_TOO_SHORT20 0x00001123 +#define ERRINFO_SECURITY_DATA_TOO_SHORT21 0x00001124 +#define ERRINFO_SECURITY_DATA_TOO_SHORT22 0x00001125 +#define ERRINFO_SECURITY_DATA_TOO_SHORT23 0x00001126 +#define ERRINFO_BAD_MONITOR_DATA 0x00001129 +#define ERRINFO_VC_DECOMPRESSED_REASSEMBLE_FAILED 0x0000112A +#define ERRINFO_VC_DATA_TOO_LONG 0x0000112B +#define ERRINFO_GRAPHICS_MODE_NOT_SUPPORTED 0x0000112D +#define ERRINFO_GRAPHICS_SUBSYSTEM_RESET_FAILED 0x0000112E +#define ERRINFO_UPDATE_SESSION_KEY_FAILED 0x00001191 +#define ERRINFO_DECRYPT_FAILED 0x00001192 +#define ERRINFO_ENCRYPT_FAILED 0x00001193 +#define ERRINFO_ENCRYPTION_PACKAGE_MISMATCH 0x00001194 +#define ERRINFO_DECRYPT_FAILED2 0x00001195 + +#define ERRINFO_SUCCESS 0x00000000 +#define ERRINFO_NONE 0xFFFFFFFF + /** * This static variable holds an error code if the return value from connect is FALSE. * This variable is always set to 0 in the beginning of the connect sequence. diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index 0a3beb346..1c531d992 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -63,6 +63,9 @@ typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type); typedef int (*pSendChannelData)(freerdp* instance, int channelId, BYTE* data, int size); typedef int (*pReceiveChannelData)(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size); +typedef int (*pOnChannelConnected)(freerdp* instance, const char* name, void* pInterface); +typedef int (*pOnChannelDisconnected)(freerdp* instance, const char* name, void* pInterface); + /** * Defines the context for a given instance of RDP connection. * It is embedded in the rdp_freerdp structure, and allocated by a call to freerdp_context_new(). @@ -193,6 +196,10 @@ struct rdp_freerdp Callback for receiving data from a channel. This is called by freerdp_channel_process() (if not NULL). Clients will typically use a function that calls freerdp_channels_data() to perform the needed tasks. */ + + pOnChannelConnected OnChannelConnected; + pOnChannelDisconnected OnChannelDisconnected; + UINT32 paddingE[80 - 66]; /* 66 */ }; @@ -218,6 +225,7 @@ FREERDP_API void freerdp_get_version(int* major, int* minor, int* revision); FREERDP_API freerdp* freerdp_new(void); FREERDP_API void freerdp_free(freerdp* instance); +FREERDP_API BOOL freerdp_focus_required(freerdp* instance); #ifdef __cplusplus } #endif diff --git a/include/freerdp/gdi/gdi.h b/include/freerdp/gdi/gdi.h index 4403c3424..a4172521e 100644 --- a/include/freerdp/gdi/gdi.h +++ b/include/freerdp/gdi/gdi.h @@ -288,6 +288,10 @@ struct rdp_gdi gdiBitmap* image; }; +#ifdef __cplusplus +extern "C" { +#endif + FREERDP_API UINT32 gdi_rop3_code(BYTE code); FREERDP_API BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y); FREERDP_API BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y); @@ -297,6 +301,10 @@ FREERDP_API void gdi_resize(rdpGdi* gdi, int width, int height); FREERDP_API int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer); FREERDP_API void gdi_free(freerdp* instance); +#ifdef __cplusplus +} +#endif + #ifdef WITH_DEBUG_GDI #define DEBUG_GDI(fmt, ...) DEBUG_CLASS(GDI, fmt, ## __VA_ARGS__) #else diff --git a/include/freerdp/input.h b/include/freerdp/input.h index a08637e1d..87324f0ab 100644 --- a/include/freerdp/input.h +++ b/include/freerdp/input.h @@ -67,6 +67,7 @@ typedef void (*pKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code); typedef void (*pUnicodeKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code); typedef void (*pMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); typedef void (*pExtendedMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); +typedef void (*pFocusInEvent)(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y); struct rdp_input { @@ -79,7 +80,9 @@ struct rdp_input pUnicodeKeyboardEvent UnicodeKeyboardEvent; /* 18 */ pMouseEvent MouseEvent; /* 19 */ pExtendedMouseEvent ExtendedMouseEvent; /* 20 */ - UINT32 paddingB[32 - 21]; /* 21 */ + pFocusInEvent FocusInEvent; /*21 */ + + UINT32 paddingB[32 - 22]; /* 22 */ /* Internal */ @@ -98,6 +101,7 @@ FREERDP_API void freerdp_input_send_keyboard_event_ex(rdpInput* input, BOOL down FREERDP_API void freerdp_input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code); FREERDP_API void freerdp_input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); FREERDP_API void freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); +FREERDP_API void freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y); #ifdef __cplusplus } diff --git a/include/freerdp/locale/keyboard.h b/include/freerdp/locale/keyboard.h index 3e57e0b32..32a7ed5fe 100644 --- a/include/freerdp/locale/keyboard.h +++ b/include/freerdp/locale/keyboard.h @@ -199,10 +199,19 @@ typedef struct _RDP_KEYBOARD_LAYOUT RDP_KEYBOARD_LAYOUT; #define KBD_TYPE_NOKIA_9140 0x00000006 /* Nokia 9140 and similar keyboards */ #define KBD_TYPE_JAPANESE 0x00000007 /* Japanese keyboard */ +#ifdef __cplusplus +extern "C" { +#endif + FREERDP_API DWORD freerdp_keyboard_init(DWORD keyboardLayoutId); FREERDP_API RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(DWORD types); FREERDP_API const char* freerdp_keyboard_get_layout_name_from_id(DWORD keyboardLayoutId); +FREERDP_API DWORD freerdp_keyboard_get_layout_id_from_name(const char* name); FREERDP_API DWORD freerdp_keyboard_get_rdp_scancode_from_x11_keycode(DWORD keycode); FREERDP_API DWORD freerdp_keyboard_get_x11_keycode_from_rdp_scancode(DWORD scancode, BOOL extended); +#ifdef __cplusplus +} +#endif + #endif /* FREERDP_LOCALE_KEYBOARD_H */ diff --git a/include/freerdp/message.h b/include/freerdp/message.h index 754802ba2..e275849b4 100644 --- a/include/freerdp/message.h +++ b/include/freerdp/message.h @@ -324,5 +324,25 @@ #define FREERDP_RAIL_CHANNEL_CLIENT_GET_APP_ID_REQUEST MakeMessageId(RailChannel, ClientGetAppIdRequest) #define FREERDP_RAIL_CHANNEL_SERVER_GET_APP_ID_RESPONSE MakeMessageId(RailChannel, ServerGetAppIdResponse) +/** + * MultiTouch Input Channel Extension (MS-RDPEDI) + */ + +#define RdpeiChannel_Class (Channel_Base + 5) + +#define RdpeiChannel_ServerReady 1 +#define RdpeiChannel_ClientReady 2 +#define RdpeiChannel_TouchEvent 3 +#define RdpeiChannel_SuspendTouch 4 +#define RdpeiChannel_ResumeTouch 5 +#define RdpeiChannel_DismissHoveringContact 6 + +#define FREERDP_RDPEI_CHANNEL_SERVER_READY MakeMessageId(RdpeiChannel, ServerReady) +#define FREERDP_RDPEI_CHANNEL_CLIENT_READY MakeMessageId(RdpeiChannel, ClientReady) +#define FREERDP_RDPEI_CHANNEL_TOUCH_EVENT MakeMessageId(RdpeiChannel, TouchEvent) +#define FREERDP_RDPEI_CHANNEL_SUSPEND_TOUCH MakeMessageId(RdpeiChannel, SuspendTouch) +#define FREERDP_RDPEI_CHANNEL_RESUME_TOUCH MakeMessageId(RdpeiChannel, ResumeTouch) +#define FREERDP_RDPEI_CHANNEL_DISMISS_HOVERING_CONTACT MakeMessageId(RdpeiChannel, DismissHoveringContact) + #endif /* FREERDP_CORE_MESSAGE_H */ diff --git a/include/freerdp/primary.h b/include/freerdp/primary.h index add5a4b64..8cb1d716a 100644 --- a/include/freerdp/primary.h +++ b/include/freerdp/primary.h @@ -73,13 +73,11 @@ typedef struct rdp_brush rdpBrush; struct _ORDER_INFO { + UINT32 controlFlags; UINT32 orderType; UINT32 fieldFlags; + UINT32 boundsFlags; rdpBounds bounds; - INT32 deltaBoundLeft; - INT32 deltaBoundTop; - INT32 deltaBoundRight; - INT32 deltaBoundBottom; BOOL deltaCoordinates; }; typedef struct _ORDER_INFO ORDER_INFO; diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 6597e6e30..8bdf4ef9f 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -511,6 +511,8 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_SpanMonitors 387 #define FreeRDP_UseMultimon 388 #define FreeRDP_ForceMultimon 389 +#define FreeRDP_DesktopPosX 390 +#define FreeRDP_DesktopPosY 391 #define FreeRDP_MultitransportFlags 512 #define FreeRDP_AlternateShell 640 #define FreeRDP_ShellWorkingDirectory 641 @@ -673,6 +675,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_ImeFileName 2628 #define FreeRDP_UnicodeInput 2629 #define FreeRDP_FastPathInput 2630 +#define FreeRDP_MultiTouchInput 2631 #define FreeRDP_BrushSupportLevel 2688 #define FreeRDP_GlyphSupportLevel 2752 #define FreeRDP_GlyphCache 2753 @@ -807,7 +810,12 @@ struct rdp_settings ALIGN64 BOOL SpanMonitors; /* 387 */ ALIGN64 BOOL UseMultimon; /* 388 */ ALIGN64 BOOL ForceMultimon; /* 389 */ - UINT64 padding0448[448 - 390]; /* 390 */ + ALIGN64 UINT32 DesktopPosX; /* 390 */ + ALIGN64 UINT32 DesktopPosY; /* 391 */ + ALIGN64 BOOL ListMonitors; /* 392 */ + ALIGN64 UINT32* MonitorIds; /* 393 */ + ALIGN64 UINT32 NumMonitorIds; /* 394 */ + UINT64 padding0448[448 - 395]; /* 395 */ /* Client Message Channel Data */ UINT64 padding0512[512 - 448]; /* 448 */ @@ -1090,7 +1098,8 @@ struct rdp_settings ALIGN64 char* ImeFileName; /* 2628 */ ALIGN64 BOOL UnicodeInput; /* 2629 */ ALIGN64 BOOL FastPathInput; /* 2630 */ - UINT64 padding2688[2688 - 2631]; /* 2631 */ + ALIGN64 BOOL MultiTouchInput; /* 2631 */ + UINT64 padding2688[2688 - 2632]; /* 2632 */ /* Brush Capabilities */ ALIGN64 UINT32 BrushSupportLevel; /* 2688 */ diff --git a/include/freerdp/svc.h b/include/freerdp/svc.h index c09307fd9..519bd9e40 100644 --- a/include/freerdp/svc.h +++ b/include/freerdp/svc.h @@ -35,9 +35,10 @@ struct _CHANNEL_DEF { - char name[CHANNEL_NAME_LEN + 1]; + char name[8]; UINT32 options; }; + typedef struct _CHANNEL_DEF CHANNEL_DEF; typedef CHANNEL_DEF* PCHANNEL_DEF; typedef CHANNEL_DEF** PPCHANNEL_DEF; @@ -94,6 +95,8 @@ typedef CHANNEL_ENTRY_POINTS* PCHANNEL_ENTRY_POINTS; typedef int (FREERDP_CC * PVIRTUALCHANNELENTRY)(PCHANNEL_ENTRY_POINTS pEntryPoints); +#define FREERDP_CHANNEL_MAGIC_NUMBER 0x46524450 + struct _CHANNEL_ENTRY_POINTS_EX { UINT32 cbSize; @@ -104,9 +107,9 @@ struct _CHANNEL_ENTRY_POINTS_EX PVIRTUALCHANNELWRITE pVirtualChannelWrite; /* Extended Fields */ - + UINT32 MagicNumber; /* identifies FreeRDP */ void* pExtendedData; /* extended initial data */ - void* pInterface; /* channel callback interface */ + void** ppInterface; /* channel callback interface */ PVIRTUALCHANNELEVENTPUSH pVirtualChannelEventPush; }; typedef struct _CHANNEL_ENTRY_POINTS_EX CHANNEL_ENTRY_POINTS_EX; diff --git a/include/freerdp/update.h b/include/freerdp/update.h index 047a4ec17..db6f36bb9 100644 --- a/include/freerdp/update.h +++ b/include/freerdp/update.h @@ -206,6 +206,12 @@ struct rdp_update BOOL asynchronous; rdpUpdateProxy* proxy; wMessageQueue* queue; + + wStream* us; + UINT16 numberOrders; + BOOL combineUpdates; + rdpBounds currentBounds; + rdpBounds previousBounds; }; #endif /* FREERDP_UPDATE_H */ diff --git a/libfreerdp/CMakeLists.txt b/libfreerdp/CMakeLists.txt index b8b6adb28..6dccb0771 100644 --- a/libfreerdp/CMakeLists.txt +++ b/libfreerdp/CMakeLists.txt @@ -22,6 +22,15 @@ if(MONOLITHIC_BUILD) set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() +# Create imported targets for Intel IPP libraries + +if(IPP_FOUND) + foreach(ipp_lib ${IPP_LIBRARIES}) + add_library("${ipp_lib}_imported" STATIC IMPORTED) + set_property(TARGET "${ipp_lib}_imported" PROPERTY IMPORTED_LOCATION "${IPP_LIBRARY_DIRS}/${ipp_lib}") + endforeach() +endif() + set(${MODULE_PREFIX}_SUBMODULES utils common @@ -43,7 +52,7 @@ if(MONOLITHIC_BUILD) set(${MODULE_PREFIX}_OBJECTS ${${MODULE_PREFIX}_OBJECTS} "$<TARGET_OBJECTS:${MODULE_NAME}-${${MODULE_PREFIX}_SUBMODULE}>") endforeach() - add_library(${MODULE_NAME} ${${MODULE_PREFIX}_OBJECTS}) + add_library(${MODULE_NAME} dummy.c ${${MODULE_PREFIX}_OBJECTS}) set_target_properties(${MODULE_NAME} PROPERTIES LINKER_LANGUAGE C) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION} PREFIX "lib") diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index e7b9790b1..69a237511 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -614,22 +614,61 @@ BYTE* freerdp_image_convert_16bpp(BYTE* srcData, BYTE* dstData, int width, int h src16 = (UINT16*) srcData; dst32 = (UINT32*) dstData; - for (i = width * height; i > 0; i--) + if (clrconv->alpha) { - pixel = *src16; - src16++; - GetBGR16(red, green, blue, pixel); - if (clrconv->alpha) + if (clrconv->invert) { - pixel = (clrconv->invert) ? ARGB32(0xFF, red, green, blue) : ABGR32(0xFF, red, green, blue); + for (i = width * height; i > 0; i--) + { + pixel = *src16; + src16++; + GetBGR16(red, green, blue, pixel); + pixel = ARGB32(0xFF, red, green, blue); + *dst32 = pixel; + dst32++; + } } else { - pixel = (clrconv->invert) ? RGB32(red, green, blue) : BGR32(red, green, blue); + for (i = width * height; i > 0; i--) + { + pixel = *src16; + src16++; + GetBGR16(red, green, blue, pixel); + pixel = ABGR32(0xFF, red, green, blue); + *dst32 = pixel; + dst32++; + } } - *dst32 = pixel; - dst32++; } + else + { + if (clrconv->invert) + { + for (i = width * height; i > 0; i--) + { + pixel = *src16; + src16++; + GetBGR16(red, green, blue, pixel); + pixel = RGB32(red, green, blue); + *dst32 = pixel; + dst32++; + } + } + else + { + for (i = width * height; i > 0; i--) + { + pixel = *src16; + src16++; + GetBGR16(red, green, blue, pixel); + pixel = BGR32(red, green, blue); + *dst32 = pixel; + dst32++; + } + } + } + return dstData; } diff --git a/libfreerdp/codec/nsc.c b/libfreerdp/codec/nsc.c index 9e9db09e1..ba435a0c8 100644 --- a/libfreerdp/codec/nsc.c +++ b/libfreerdp/codec/nsc.c @@ -174,13 +174,13 @@ static void nsc_stream_initialize(NSC_CONTEXT* context, wStream* s) int i; for (i = 0; i < 4; i++) - stream_read_UINT32(s, context->nsc_stream.PlaneByteCount[i]); + Stream_Read_UINT32(s, context->nsc_stream.PlaneByteCount[i]); - stream_read_BYTE(s, context->nsc_stream.ColorLossLevel); - stream_read_BYTE(s, context->nsc_stream.ChromaSubSamplingLevel); - stream_seek(s, 2); + Stream_Read_UINT8(s, context->nsc_stream.ColorLossLevel); + Stream_Read_UINT8(s, context->nsc_stream.ChromaSubSamplingLevel); + Stream_Seek(s, 2); - context->nsc_stream.Planes = stream_get_tail(s); + context->nsc_stream.Planes = Stream_Pointer(s); } static void nsc_context_initialize(NSC_CONTEXT* context, wStream* s) @@ -329,14 +329,12 @@ void nsc_process_message(NSC_CONTEXT* context, UINT16 bpp, { wStream* s; - s = stream_new(0); - stream_attach(s, data, length); + s = Stream_New(data, length); context->bpp = bpp; context->width = width; context->height = height; nsc_context_initialize(context, s); - stream_detach(s); - stream_free(s); + Stream_Free(s, FALSE); /* RLE decode */ PROFILER_ENTER(context->priv->prof_nsc_rle_decompress_data); diff --git a/libfreerdp/codec/nsc_encode.c b/libfreerdp/codec/nsc_encode.c index 36c1988e9..143e44dc5 100644 --- a/libfreerdp/codec/nsc_encode.c +++ b/libfreerdp/codec/nsc_encode.c @@ -349,21 +349,21 @@ void nsc_compose_message(NSC_CONTEXT* context, wStream* s, PROFILER_EXIT(context->priv->prof_nsc_rle_compress_data); /* Assemble the NSCodec message into stream */ - stream_check_size(s, 20); - stream_write_UINT32(s, context->nsc_stream.PlaneByteCount[0]); /* LumaPlaneByteCount (4 bytes) */ - stream_write_UINT32(s, context->nsc_stream.PlaneByteCount[1]); /* OrangeChromaPlaneByteCount (4 bytes) */ - stream_write_UINT32(s, context->nsc_stream.PlaneByteCount[2]); /* GreenChromaPlaneByteCount (4 bytes) */ - stream_write_UINT32(s, context->nsc_stream.PlaneByteCount[3]); /* AlphaPlaneByteCount (4 bytes) */ - stream_write_BYTE(s, context->nsc_stream.ColorLossLevel); /* ColorLossLevel (1 byte) */ - stream_write_BYTE(s, context->nsc_stream.ChromaSubSamplingLevel); /* ChromaSubsamplingLevel (1 byte) */ - stream_write_UINT16(s, 0); /* Reserved (2 bytes) */ + Stream_EnsureRemainingCapacity(s, 20); + Stream_Write_UINT32(s, context->nsc_stream.PlaneByteCount[0]); /* LumaPlaneByteCount (4 bytes) */ + Stream_Write_UINT32(s, context->nsc_stream.PlaneByteCount[1]); /* OrangeChromaPlaneByteCount (4 bytes) */ + Stream_Write_UINT32(s, context->nsc_stream.PlaneByteCount[2]); /* GreenChromaPlaneByteCount (4 bytes) */ + Stream_Write_UINT32(s, context->nsc_stream.PlaneByteCount[3]); /* AlphaPlaneByteCount (4 bytes) */ + Stream_Write_UINT8(s, context->nsc_stream.ColorLossLevel); /* ColorLossLevel (1 byte) */ + Stream_Write_UINT8(s, context->nsc_stream.ChromaSubSamplingLevel); /* ChromaSubsamplingLevel (1 byte) */ + Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */ for (i = 0; i < 4; i++) { if (context->nsc_stream.PlaneByteCount[i] > 0) { - stream_check_size(s, (int) context->nsc_stream.PlaneByteCount[i]); - stream_write(s, context->priv->plane_buf[i], context->nsc_stream.PlaneByteCount[i]); + Stream_EnsureRemainingCapacity(s, (int) context->nsc_stream.PlaneByteCount[i]); + Stream_Write(s, context->priv->plane_buf[i], context->nsc_stream.PlaneByteCount[i]); } } } diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 05c5735a3..afd9e5ecc 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -330,12 +330,12 @@ static BOOL rfx_process_message_sync(RFX_CONTEXT* context, wStream* s) UINT32 magic; /* RFX_SYNC */ - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) { DEBUG_WARN("RfxSync packet too small"); return FALSE; } - stream_read_UINT32(s, magic); /* magic (4 bytes), 0xCACCACCA */ + Stream_Read_UINT32(s, magic); /* magic (4 bytes), 0xCACCACCA */ if (magic != WF_MAGIC) { @@ -343,7 +343,7 @@ static BOOL rfx_process_message_sync(RFX_CONTEXT* context, wStream* s) return FALSE; } - stream_read_UINT16(s, context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */ + Stream_Read_UINT16(s, context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */ if (context->version != WF_VERSION_1_0) { @@ -359,12 +359,12 @@ static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, wStream* s) { BYTE numCodecs; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) { DEBUG_WARN("RfxCodecVersion packet too small"); return FALSE; } - stream_read_BYTE(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */ + Stream_Read_UINT8(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */ if (numCodecs != 1) { @@ -372,15 +372,15 @@ static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, wStream* s) return FALSE; } - if (stream_get_left(s) < 2 * numCodecs) + if (Stream_GetRemainingLength(s) < 2 * numCodecs) { DEBUG_WARN("RfxCodecVersion packet too small for numCodecs=%d", numCodecs); return FALSE; } /* RFX_CODEC_VERSIONT */ - stream_read_BYTE(s, context->codec_id); /* codecId (1 byte) */ - stream_read_BYTE(s, context->codec_version); /* version (2 bytes) */ + Stream_Read_UINT8(s, context->codec_id); /* codecId (1 byte) */ + Stream_Read_UINT8(s, context->codec_version); /* version (2 bytes) */ DEBUG_RFX("id %d version 0x%X.", context->codec_id, context->codec_version); return TRUE; @@ -391,13 +391,13 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s) BYTE channelId; BYTE numChannels; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) { DEBUG_WARN("RfxMessageChannels packet too small"); return FALSE; } - stream_read_BYTE(s, numChannels); /* numChannels (1 byte), must bet set to 0x01 */ + Stream_Read_UINT8(s, numChannels); /* numChannels (1 byte), must bet set to 0x01 */ /* In RDVH sessions, numChannels will represent the number of virtual monitors * configured and does not always be set to 0x01 as [MS-RDPRFX] said. @@ -408,19 +408,19 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s) return TRUE; } - if (stream_get_left(s) < numChannels * 5) + if (Stream_GetRemainingLength(s) < numChannels * 5) { DEBUG_WARN("RfxMessageChannels packet too small for numChannels=%d", numChannels); return FALSE; } /* RFX_CHANNELT */ - stream_read_BYTE(s, channelId); /* channelId (1 byte) */ - stream_read_UINT16(s, context->width); /* width (2 bytes) */ - stream_read_UINT16(s, context->height); /* height (2 bytes) */ + Stream_Read_UINT8(s, channelId); /* channelId (1 byte) */ + Stream_Read_UINT16(s, context->width); /* width (2 bytes) */ + Stream_Read_UINT16(s, context->height); /* height (2 bytes) */ /* Now, only the first monitor can be used, therefore the other channels will be ignored. */ - stream_seek(s, 5 * (numChannels - 1)); + Stream_Seek(s, 5 * (numChannels - 1)); DEBUG_RFX("numChannels %d id %d, %dx%d.", numChannels, channelId, context->width, context->height); @@ -433,15 +433,15 @@ static BOOL rfx_process_message_context(RFX_CONTEXT* context, wStream* s) UINT16 tileSize; UINT16 properties; - if (stream_get_left(s) < 5) + if (Stream_GetRemainingLength(s) < 5) { DEBUG_WARN("RfxMessageContext packet too small"); return FALSE; } - stream_read_BYTE(s, ctxId); /* ctxId (1 byte), must be set to 0x00 */ - stream_read_UINT16(s, tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */ - stream_read_UINT16(s, properties); /* properties (2 bytes) */ + Stream_Read_UINT8(s, ctxId); /* ctxId (1 byte), must be set to 0x00 */ + Stream_Read_UINT16(s, tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */ + Stream_Read_UINT16(s, properties); /* properties (2 bytes) */ DEBUG_RFX("ctxId %d tileSize %d properties 0x%X.", ctxId, tileSize, properties); @@ -477,13 +477,13 @@ static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context, RFX_MESSAGE* m UINT32 frameIdx; UINT16 numRegions; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) { DEBUG_WARN("RfxMessageFrameBegin packet too small"); return FALSE; } - stream_read_UINT32(s, frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */ - stream_read_UINT16(s, numRegions); /* numRegions (2 bytes) */ + Stream_Read_UINT32(s, frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */ + Stream_Read_UINT16(s, numRegions); /* numRegions (2 bytes) */ DEBUG_RFX("RFX_FRAME_BEGIN: frameIdx:%d numRegions:%d", frameIdx, numRegions); return TRUE; @@ -498,14 +498,14 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag { int i; - if (stream_get_left(s) < 3) + if (Stream_GetRemainingLength(s) < 3) { DEBUG_WARN("RfxMessageRegion packet too small"); return FALSE; } - stream_seek_BYTE(s); /* regionFlags (1 byte) */ - stream_read_UINT16(s, message->num_rects); /* numRects (2 bytes) */ + Stream_Seek_UINT8(s); /* regionFlags (1 byte) */ + Stream_Read_UINT16(s, message->num_rects); /* numRects (2 bytes) */ if (message->num_rects < 1) { @@ -513,7 +513,7 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag return TRUE; } - if (stream_get_left(s) < 8 * message->num_rects) + if (Stream_GetRemainingLength(s) < 8 * message->num_rects) { DEBUG_WARN("RfxMessageRegion packet too small for num_rects=%d", message->num_rects); return FALSE; @@ -528,10 +528,10 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag for (i = 0; i < message->num_rects; i++) { /* RFX_RECT */ - stream_read_UINT16(s, message->rects[i].x); /* x (2 bytes) */ - stream_read_UINT16(s, message->rects[i].y); /* y (2 bytes) */ - stream_read_UINT16(s, message->rects[i].width); /* width (2 bytes) */ - stream_read_UINT16(s, message->rects[i].height); /* height (2 bytes) */ + Stream_Read_UINT16(s, message->rects[i].x); /* x (2 bytes) */ + Stream_Read_UINT16(s, message->rects[i].y); /* y (2 bytes) */ + Stream_Read_UINT16(s, message->rects[i].width); /* width (2 bytes) */ + Stream_Read_UINT16(s, message->rects[i].height); /* height (2 bytes) */ DEBUG_RFX("rect %d (%d %d %d %d).", i, message->rects[i].x, message->rects[i].y, message->rects[i].width, message->rects[i].height); @@ -547,21 +547,21 @@ static BOOL rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, wStre UINT16 xIdx, yIdx; UINT16 YLen, CbLen, CrLen; - if (stream_get_left(s) < 13) + if (Stream_GetRemainingLength(s) < 13) { DEBUG_WARN("RfxMessageTile packet too small"); return FALSE; } /* RFX_TILE */ - stream_read_BYTE(s, quantIdxY); /* quantIdxY (1 byte) */ - stream_read_BYTE(s, quantIdxCb); /* quantIdxCb (1 byte) */ - stream_read_BYTE(s, quantIdxCr); /* quantIdxCr (1 byte) */ - stream_read_UINT16(s, xIdx); /* xIdx (2 bytes) */ - stream_read_UINT16(s, yIdx); /* yIdx (2 bytes) */ - stream_read_UINT16(s, YLen); /* YLen (2 bytes) */ - stream_read_UINT16(s, CbLen); /* CbLen (2 bytes) */ - stream_read_UINT16(s, CrLen); /* CrLen (2 bytes) */ + Stream_Read_UINT8(s, quantIdxY); /* quantIdxY (1 byte) */ + Stream_Read_UINT8(s, quantIdxCb); /* quantIdxCb (1 byte) */ + Stream_Read_UINT8(s, quantIdxCr); /* quantIdxCr (1 byte) */ + Stream_Read_UINT16(s, xIdx); /* xIdx (2 bytes) */ + Stream_Read_UINT16(s, yIdx); /* yIdx (2 bytes) */ + Stream_Read_UINT16(s, YLen); /* YLen (2 bytes) */ + Stream_Read_UINT16(s, CbLen); /* CbLen (2 bytes) */ + Stream_Read_UINT16(s, CrLen); /* CrLen (2 bytes) */ DEBUG_RFX("quantIdxY:%d quantIdxCb:%d quantIdxCr:%d xIdx:%d yIdx:%d YLen:%d CbLen:%d CrLen:%d", quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx, YLen, CbLen, CrLen); @@ -603,13 +603,13 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa PTP_WORK* work_objects = NULL; RFX_TILE_WORK_PARAM* params = NULL; - if (stream_get_left(s) < 14) + if (Stream_GetRemainingLength(s) < 14) { DEBUG_WARN("RfxMessageTileSet packet too small"); return FALSE; } - stream_read_UINT16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */ + Stream_Read_UINT16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */ if (subtype != CBT_TILESET) { @@ -617,11 +617,11 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa return FALSE; } - stream_seek_UINT16(s); /* idx (2 bytes), must be set to 0x0000 */ - stream_seek_UINT16(s); /* properties (2 bytes) */ + Stream_Seek_UINT16(s); /* idx (2 bytes), must be set to 0x0000 */ + Stream_Seek_UINT16(s); /* properties (2 bytes) */ - stream_read_BYTE(s, context->num_quants); /* numQuant (1 byte) */ - stream_seek_BYTE(s); /* tileSize (1 byte), must be set to 0x40 */ + Stream_Read_UINT8(s, context->num_quants); /* numQuant (1 byte) */ + Stream_Seek_UINT8(s); /* tileSize (1 byte), must be set to 0x40 */ if (context->num_quants < 1) { @@ -629,7 +629,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa return TRUE; } - stream_read_UINT16(s, message->num_tiles); /* numTiles (2 bytes) */ + Stream_Read_UINT16(s, message->num_tiles); /* numTiles (2 bytes) */ if (message->num_tiles < 1) { @@ -637,7 +637,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa return TRUE; } - stream_read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */ + Stream_Read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */ if (context->quants != NULL) context->quants = (UINT32*) realloc((void*) context->quants, context->num_quants * 10 * sizeof(UINT32)); @@ -646,7 +646,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa quants = context->quants; /* quantVals */ - if (stream_get_left(s) < context->num_quants * 5) + if (Stream_GetRemainingLength(s) < context->num_quants * 5) { DEBUG_WARN("RfxMessageTileSet packet too small for num_quants=%d", context->num_quants); return FALSE; @@ -655,19 +655,19 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa for (i = 0; i < context->num_quants; i++) { /* RFX_CODEC_QUANT */ - stream_read_BYTE(s, quant); + Stream_Read_UINT8(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); - stream_read_BYTE(s, quant); + Stream_Read_UINT8(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); - stream_read_BYTE(s, quant); + Stream_Read_UINT8(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); - stream_read_BYTE(s, quant); + Stream_Read_UINT8(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); - stream_read_BYTE(s, quant); + Stream_Read_UINT8(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); @@ -692,22 +692,22 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa for (i = 0; i < message->num_tiles; i++) { /* RFX_TILE */ - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) { DEBUG_WARN("RfxMessageTileSet packet too small to read tile %d/%d", i, message->num_tiles); return FALSE; } - stream_read_UINT16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */ - stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */ + Stream_Read_UINT16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */ + Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */ - if (stream_get_left(s) < blockLen - 6) + if (Stream_GetRemainingLength(s) < blockLen - 6) { DEBUG_WARN("RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", i, message->num_tiles, blockLen); return FALSE; } - pos = stream_get_pos(s) - 6 + blockLen; + pos = Stream_GetPosition(s) - 6 + blockLen; if (blockType != CBT_TILE) { @@ -733,7 +733,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa rfx_process_message_tile(context, message->tiles[i], s); } - stream_set_pos(s, pos); + Stream_SetPosition(s, pos); } if (context->priv->UseThreads) @@ -758,14 +758,13 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE)); ZeroMemory(message, sizeof(RFX_MESSAGE)); - s = stream_new(0); - stream_attach(s, data, length); + s = Stream_New(data, length); - while (stream_get_left(s) > 6) + while (Stream_GetRemainingLength(s) > 6) { /* RFX_BLOCKT */ - stream_read_UINT16(s, blockType); /* blockType (2 bytes) */ - stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */ + Stream_Read_UINT16(s, blockType); /* blockType (2 bytes) */ + Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */ DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen); @@ -775,21 +774,21 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length break; } - if (stream_get_left(s) < blockLen - 6) + if (Stream_GetRemainingLength(s) < blockLen - 6) { DEBUG_WARN("rfx_process_message: packet too small for blocklen=%d", blockLen); break; } - pos = stream_get_pos(s) - 6 + blockLen; + pos = Stream_GetPosition(s) - 6 + blockLen; if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) { /* RFX_CODEC_CHANNELT */ /* codecId (1 byte) must be set to 0x01 */ /* channelId (1 byte) must be set to 0x00 */ - if (!stream_skip(s, 2)) + if (!Stream_SafeSeek(s, 2)) { DEBUG_WARN("rfx_process_message: unable to skip RFX_CODEC_CHANNELT"); break; @@ -835,11 +834,10 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length break; } - stream_set_pos(s, pos); + Stream_SetPosition(s, pos); } - stream_detach(s); - stream_free(s); + Stream_Free(s, FALSE); return message; } @@ -886,41 +884,41 @@ void rfx_message_free(RFX_CONTEXT* context, RFX_MESSAGE* message) static void rfx_compose_message_sync(RFX_CONTEXT* context, wStream* s) { - stream_write_UINT16(s, WBT_SYNC); /* BlockT.blockType */ - stream_write_UINT32(s, 12); /* BlockT.blockLen */ - stream_write_UINT32(s, WF_MAGIC); /* magic */ - stream_write_UINT16(s, WF_VERSION_1_0); /* version */ + Stream_Write_UINT16(s, WBT_SYNC); /* BlockT.blockType */ + Stream_Write_UINT32(s, 12); /* BlockT.blockLen */ + Stream_Write_UINT32(s, WF_MAGIC); /* magic */ + Stream_Write_UINT16(s, WF_VERSION_1_0); /* version */ } static void rfx_compose_message_codec_versions(RFX_CONTEXT* context, wStream* s) { - stream_write_UINT16(s, WBT_CODEC_VERSIONS); /* BlockT.blockType */ - stream_write_UINT32(s, 10); /* BlockT.blockLen */ - stream_write_BYTE(s, 1); /* numCodecs */ - stream_write_BYTE(s, 1); /* codecs.codecId */ - stream_write_UINT16(s, WF_VERSION_1_0); /* codecs.version */ + Stream_Write_UINT16(s, WBT_CODEC_VERSIONS); /* BlockT.blockType */ + Stream_Write_UINT32(s, 10); /* BlockT.blockLen */ + Stream_Write_UINT8(s, 1); /* numCodecs */ + Stream_Write_UINT8(s, 1); /* codecs.codecId */ + Stream_Write_UINT16(s, WF_VERSION_1_0); /* codecs.version */ } static void rfx_compose_message_channels(RFX_CONTEXT* context, wStream* s) { - stream_write_UINT16(s, WBT_CHANNELS); /* BlockT.blockType */ - stream_write_UINT32(s, 12); /* BlockT.blockLen */ - stream_write_BYTE(s, 1); /* numChannels */ - stream_write_BYTE(s, 0); /* Channel.channelId */ - stream_write_UINT16(s, context->width); /* Channel.width */ - stream_write_UINT16(s, context->height); /* Channel.height */ + Stream_Write_UINT16(s, WBT_CHANNELS); /* BlockT.blockType */ + Stream_Write_UINT32(s, 12); /* BlockT.blockLen */ + Stream_Write_UINT8(s, 1); /* numChannels */ + Stream_Write_UINT8(s, 0); /* Channel.channelId */ + Stream_Write_UINT16(s, context->width); /* Channel.width */ + Stream_Write_UINT16(s, context->height); /* Channel.height */ } static void rfx_compose_message_context(RFX_CONTEXT* context, wStream* s) { UINT16 properties; - stream_write_UINT16(s, WBT_CONTEXT); /* CodecChannelT.blockType */ - stream_write_UINT32(s, 13); /* CodecChannelT.blockLen */ - stream_write_BYTE(s, 1); /* CodecChannelT.codecId */ - stream_write_BYTE(s, 0); /* CodecChannelT.channelId */ - stream_write_BYTE(s, 0); /* ctxId */ - stream_write_UINT16(s, CT_TILE_64x64); /* tileSize */ + Stream_Write_UINT16(s, WBT_CONTEXT); /* CodecChannelT.blockType */ + Stream_Write_UINT32(s, 13); /* CodecChannelT.blockLen */ + Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId */ + Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */ + Stream_Write_UINT8(s, 0); /* ctxId */ + Stream_Write_UINT16(s, CT_TILE_64x64); /* tileSize */ /* properties */ properties = context->flags; /* flags */ @@ -928,7 +926,7 @@ static void rfx_compose_message_context(RFX_CONTEXT* context, wStream* s) properties |= (CLW_XFORM_DWT_53_A << 5); /* xft */ properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) << 9); /* et */ properties |= (SCALAR_QUANTIZATION << 13); /* qt */ - stream_write_UINT16(s, properties); + Stream_Write_UINT16(s, properties); /* properties in tilesets: note that this has different format from the one in TS_RFX_CONTEXT */ properties = 1; /* lt */ @@ -942,7 +940,7 @@ static void rfx_compose_message_context(RFX_CONTEXT* context, wStream* s) void rfx_compose_message_header(RFX_CONTEXT* context, wStream* s) { - stream_check_size(s, 12 + 10 + 12 + 13); + Stream_EnsureRemainingCapacity(s, 12 + 10 + 12 + 13); rfx_compose_message_sync(context, s); rfx_compose_message_context(context, s); @@ -954,14 +952,14 @@ void rfx_compose_message_header(RFX_CONTEXT* context, wStream* s) static void rfx_compose_message_frame_begin(RFX_CONTEXT* context, wStream* s) { - stream_check_size(s, 14); + Stream_EnsureRemainingCapacity(s, 14); - stream_write_UINT16(s, WBT_FRAME_BEGIN); /* CodecChannelT.blockType */ - stream_write_UINT32(s, 14); /* CodecChannelT.blockLen */ - stream_write_BYTE(s, 1); /* CodecChannelT.codecId */ - stream_write_BYTE(s, 0); /* CodecChannelT.channelId */ - stream_write_UINT32(s, context->frame_idx); /* frameIdx */ - stream_write_UINT16(s, 1); /* numRegions */ + Stream_Write_UINT16(s, WBT_FRAME_BEGIN); /* CodecChannelT.blockType */ + Stream_Write_UINT32(s, 14); /* CodecChannelT.blockLen */ + Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId */ + Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */ + Stream_Write_UINT32(s, context->frame_idx); /* frameIdx */ + Stream_Write_UINT16(s, 1); /* numRegions */ context->frame_idx++; } @@ -973,25 +971,25 @@ static void rfx_compose_message_region(RFX_CONTEXT* context, wStream* s, int i; size = 15 + num_rects * 8; - stream_check_size(s, size); + Stream_EnsureRemainingCapacity(s, size); - stream_write_UINT16(s, WBT_REGION); /* CodecChannelT.blockType */ - stream_write_UINT32(s, size); /* set CodecChannelT.blockLen later */ - stream_write_BYTE(s, 1); /* CodecChannelT.codecId */ - stream_write_BYTE(s, 0); /* CodecChannelT.channelId */ - stream_write_BYTE(s, 1); /* regionFlags */ - stream_write_UINT16(s, num_rects); /* numRects */ + Stream_Write_UINT16(s, WBT_REGION); /* CodecChannelT.blockType */ + Stream_Write_UINT32(s, size); /* set CodecChannelT.blockLen later */ + Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId */ + Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */ + Stream_Write_UINT8(s, 1); /* regionFlags */ + Stream_Write_UINT16(s, num_rects); /* numRects */ for (i = 0; i < num_rects; i++) { - stream_write_UINT16(s, rects[i].x); - stream_write_UINT16(s, rects[i].y); - stream_write_UINT16(s, rects[i].width); - stream_write_UINT16(s, rects[i].height); + Stream_Write_UINT16(s, rects[i].x); + Stream_Write_UINT16(s, rects[i].y); + Stream_Write_UINT16(s, rects[i].width); + Stream_Write_UINT16(s, rects[i].height); } - stream_write_UINT16(s, CBT_REGION); /* regionType */ - stream_write_UINT16(s, 1); /* numTilesets */ + Stream_Write_UINT16(s, CBT_REGION); /* regionType */ + Stream_Write_UINT16(s, 1); /* numTilesets */ } static void rfx_compose_message_tile(RFX_CONTEXT* context, wStream* s, @@ -1004,18 +1002,18 @@ static void rfx_compose_message_tile(RFX_CONTEXT* context, wStream* s, int CrLen = 0; int start_pos, end_pos; - stream_check_size(s, 19); - start_pos = stream_get_pos(s); + Stream_EnsureRemainingCapacity(s, 19); + start_pos = Stream_GetPosition(s); - stream_write_UINT16(s, CBT_TILE); /* BlockT.blockType */ - stream_seek_UINT32(s); /* set BlockT.blockLen later */ - stream_write_BYTE(s, quantIdxY); - stream_write_BYTE(s, quantIdxCb); - stream_write_BYTE(s, quantIdxCr); - stream_write_UINT16(s, xIdx); - stream_write_UINT16(s, yIdx); + Stream_Write_UINT16(s, CBT_TILE); /* BlockT.blockType */ + Stream_Seek_UINT32(s); /* set BlockT.blockLen later */ + Stream_Write_UINT8(s, quantIdxY); + Stream_Write_UINT8(s, quantIdxCb); + Stream_Write_UINT8(s, quantIdxCr); + Stream_Write_UINT16(s, xIdx); + Stream_Write_UINT16(s, yIdx); - stream_seek(s, 6); /* YLen, CbLen, CrLen */ + Stream_Seek(s, 6); /* YLen, CbLen, CrLen */ rfx_encode_rgb(context, tile_data, tile_width, tile_height, rowstride, quantVals + quantIdxY * 10, quantVals + quantIdxCb * 10, quantVals + quantIdxCr * 10, @@ -1024,16 +1022,16 @@ static void rfx_compose_message_tile(RFX_CONTEXT* context, wStream* s, DEBUG_RFX("xIdx=%d yIdx=%d width=%d height=%d YLen=%d CbLen=%d CrLen=%d", xIdx, yIdx, tile_width, tile_height, YLen, CbLen, CrLen); - end_pos = stream_get_pos(s); + end_pos = Stream_GetPosition(s); - stream_set_pos(s, start_pos + 2); - stream_write_UINT32(s, 19 + YLen + CbLen + CrLen); /* BlockT.blockLen */ - stream_set_pos(s, start_pos + 13); - stream_write_UINT16(s, YLen); - stream_write_UINT16(s, CbLen); - stream_write_UINT16(s, CrLen); + Stream_SetPosition(s, start_pos + 2); + Stream_Write_UINT32(s, 19 + YLen + CbLen + CrLen); /* BlockT.blockLen */ + Stream_SetPosition(s, start_pos + 13); + Stream_Write_UINT16(s, YLen); + Stream_Write_UINT16(s, CbLen); + Stream_Write_UINT16(s, CrLen); - stream_set_pos(s, end_pos); + Stream_SetPosition(s, end_pos); } static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, @@ -1077,31 +1075,31 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, numTiles = numTilesX * numTilesY; size = 22 + numQuants * 5; - stream_check_size(s, size); - start_pos = stream_get_pos(s); + Stream_EnsureRemainingCapacity(s, size); + start_pos = Stream_GetPosition(s); - stream_write_UINT16(s, WBT_EXTENSION); /* CodecChannelT.blockType */ - stream_seek_UINT32(s); /* set CodecChannelT.blockLen later */ - stream_write_BYTE(s, 1); /* CodecChannelT.codecId */ - stream_write_BYTE(s, 0); /* CodecChannelT.channelId */ - stream_write_UINT16(s, CBT_TILESET); /* subtype */ - stream_write_UINT16(s, 0); /* idx */ - stream_write_UINT16(s, context->properties); /* properties */ - stream_write_BYTE(s, numQuants); /* numQuants */ - stream_write_BYTE(s, 0x40); /* tileSize */ - stream_write_UINT16(s, numTiles); /* numTiles */ - stream_seek_UINT32(s); /* set tilesDataSize later */ + Stream_Write_UINT16(s, WBT_EXTENSION); /* CodecChannelT.blockType */ + Stream_Seek_UINT32(s); /* set CodecChannelT.blockLen later */ + Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId */ + Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */ + Stream_Write_UINT16(s, CBT_TILESET); /* subtype */ + Stream_Write_UINT16(s, 0); /* idx */ + Stream_Write_UINT16(s, context->properties); /* properties */ + Stream_Write_UINT8(s, numQuants); /* numQuants */ + Stream_Write_UINT8(s, 0x40); /* tileSize */ + Stream_Write_UINT16(s, numTiles); /* numTiles */ + Stream_Seek_UINT32(s); /* set tilesDataSize later */ quantValsPtr = quantVals; for (i = 0; i < numQuants * 5; i++) { - stream_write_BYTE(s, quantValsPtr[0] + (quantValsPtr[1] << 4)); + Stream_Write_UINT8(s, quantValsPtr[0] + (quantValsPtr[1] << 4)); quantValsPtr += 2; } DEBUG_RFX("width:%d height:%d rowstride:%d", width, height, rowstride); - end_pos = stream_get_pos(s); + end_pos = Stream_GetPosition(s); for (yIdx = 0; yIdx < numTilesY; yIdx++) { for (xIdx = 0; xIdx < numTilesX; xIdx++) @@ -1113,26 +1111,26 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx); } } - tilesDataSize = stream_get_pos(s) - end_pos; + tilesDataSize = Stream_GetPosition(s) - end_pos; size += tilesDataSize; - end_pos = stream_get_pos(s); + end_pos = Stream_GetPosition(s); - stream_set_pos(s, start_pos + 2); - stream_write_UINT32(s, size); /* CodecChannelT.blockLen */ - stream_set_pos(s, start_pos + 18); - stream_write_UINT32(s, tilesDataSize); + Stream_SetPosition(s, start_pos + 2); + Stream_Write_UINT32(s, size); /* CodecChannelT.blockLen */ + Stream_SetPosition(s, start_pos + 18); + Stream_Write_UINT32(s, tilesDataSize); - stream_set_pos(s, end_pos); + Stream_SetPosition(s, end_pos); } static void rfx_compose_message_frame_end(RFX_CONTEXT* context, wStream* s) { - stream_check_size(s, 8); + Stream_EnsureRemainingCapacity(s, 8); - stream_write_UINT16(s, WBT_FRAME_END); /* CodecChannelT.blockType */ - stream_write_UINT32(s, 8); /* CodecChannelT.blockLen */ - stream_write_BYTE(s, 1); /* CodecChannelT.codecId */ - stream_write_BYTE(s, 0); /* CodecChannelT.channelId */ + Stream_Write_UINT16(s, WBT_FRAME_END); /* CodecChannelT.blockType */ + Stream_Write_UINT32(s, 8); /* CodecChannelT.blockLen */ + Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId */ + Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */ } static void rfx_compose_message_data(RFX_CONTEXT* context, wStream* s, diff --git a/libfreerdp/codec/rfx_decode.c b/libfreerdp/codec/rfx_decode.c index 15aa4cf00..960096f1d 100644 --- a/libfreerdp/codec/rfx_decode.c +++ b/libfreerdp/codec/rfx_decode.c @@ -165,24 +165,24 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in, params[0].context = context; params[0].quantization_values = y_quants; - params[0].buffer = stream_get_tail(data_in); + params[0].buffer = Stream_Pointer(data_in); params[0].capacity = y_size; params[0].buffer = pSrcDst[0]; - stream_seek(data_in, y_size); + Stream_Seek(data_in, y_size); params[1].context = context; params[1].quantization_values = cb_quants; - params[1].buffer = stream_get_tail(data_in); + params[1].buffer = Stream_Pointer(data_in); params[1].capacity = cb_size; params[1].buffer = pSrcDst[1]; - stream_seek(data_in, cb_size); + Stream_Seek(data_in, cb_size); params[2].context = context; params[2].quantization_values = cr_quants; - params[2].buffer = stream_get_tail(data_in); + params[2].buffer = Stream_Pointer(data_in); params[2].capacity = cr_size; params[2].buffer = pSrcDst[2]; - stream_seek(data_in, cr_size); + Stream_Seek(data_in, cr_size); work_objects[0] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_decode_component_work_callback, (void*) ¶ms[0], &context->priv->ThreadPoolEnv); @@ -202,19 +202,20 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in, else #endif { - if (stream_get_left(data_in) < y_size+cb_size+cr_size) + if (Stream_GetRemainingLength(data_in) < y_size + cb_size + cr_size) { DEBUG_WARN("rfx_decode_rgb: packet too small for y_size+cb_size+cr_size"); return FALSE; } - rfx_decode_component(context, y_quants, stream_get_tail(data_in), y_size, pSrcDst[0]); /* YData */ - stream_seek(data_in, y_size); - rfx_decode_component(context, cb_quants, stream_get_tail(data_in), cb_size, pSrcDst[1]); /* CbData */ - stream_seek(data_in, cb_size); + rfx_decode_component(context, y_quants, Stream_Pointer(data_in), y_size, pSrcDst[0]); /* YData */ + Stream_Seek(data_in, y_size); - rfx_decode_component(context, cr_quants, stream_get_tail(data_in), cr_size, pSrcDst[2]); /* CrData */ - stream_seek(data_in, cr_size); + rfx_decode_component(context, cb_quants, Stream_Pointer(data_in), cb_size, pSrcDst[1]); /* CbData */ + Stream_Seek(data_in, cb_size); + + rfx_decode_component(context, cr_quants, Stream_Pointer(data_in), cr_size, pSrcDst[2]); /* CrData */ + Stream_Seek(data_in, cr_size); } prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * sizeof(INT16), @@ -230,5 +231,6 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in, BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[0] - 16); BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[1] - 16); BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[2] - 16); + return TRUE; } diff --git a/libfreerdp/codec/rfx_encode.c b/libfreerdp/codec/rfx_encode.c index af54d8997..b59570bec 100644 --- a/libfreerdp/codec/rfx_encode.c +++ b/libfreerdp/codec/rfx_encode.c @@ -242,21 +242,21 @@ void rfx_encode_rgb(RFX_CONTEXT* context, const BYTE* rgb_data, int width, int h PROFILER_EXIT(context->priv->prof_rfx_rgb_to_ycbcr); /* Ensure the buffer is reasonably large enough */ - stream_check_size(data_out, 4096); + Stream_EnsureRemainingCapacity(data_out, 4096); rfx_encode_component(context, y_quants, pSrcDst[0], - stream_get_tail(data_out), stream_get_left(data_out), y_size); - stream_seek(data_out, *y_size); + Stream_Pointer(data_out), Stream_GetRemainingLength(data_out), y_size); + Stream_Seek(data_out, *y_size); - stream_check_size(data_out, 4096); + Stream_EnsureRemainingCapacity(data_out, 4096); rfx_encode_component(context, cb_quants, pSrcDst[1], - stream_get_tail(data_out), stream_get_left(data_out), cb_size); - stream_seek(data_out, *cb_size); + Stream_Pointer(data_out), Stream_GetRemainingLength(data_out), cb_size); + Stream_Seek(data_out, *cb_size); - stream_check_size(data_out, 4096); + Stream_EnsureRemainingCapacity(data_out, 4096); rfx_encode_component(context, cr_quants, pSrcDst[2], - stream_get_tail(data_out), stream_get_left(data_out), cr_size); - stream_seek(data_out, *cr_size); + Stream_Pointer(data_out), Stream_GetRemainingLength(data_out), cr_size); + Stream_Seek(data_out, *cr_size); PROFILER_EXIT(context->priv->prof_rfx_encode_rgb); diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 5c3ad49ab..6bda2092e 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -650,6 +650,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) return settings->FastPathInput; break; + case FreeRDP_MultiTouchInput: + return settings->MultiTouchInput; + break; + case FreeRDP_SoundBeepsEnabled: return settings->SoundBeepsEnabled; break; @@ -1090,6 +1094,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) settings->FastPathInput = param; break; + case FreeRDP_MultiTouchInput: + settings->MultiTouchInput = param; + break; + case FreeRDP_SoundBeepsEnabled: settings->SoundBeepsEnabled = param; break; @@ -1258,6 +1266,14 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id) return settings->MonitorDefArraySize; break; + case FreeRDP_DesktopPosX: + return settings->DesktopPosX; + break; + + case FreeRDP_DesktopPosY: + return settings->DesktopPosY; + break; + case FreeRDP_MultitransportFlags: return settings->MultitransportFlags; break; @@ -1566,6 +1582,14 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) settings->MonitorDefArraySize = param; break; + case FreeRDP_DesktopPosX: + settings->DesktopPosX = param; + break; + + case FreeRDP_DesktopPosY: + settings->DesktopPosY = param; + break; + case FreeRDP_MultitransportFlags: settings->MultitransportFlags = param; break; diff --git a/libfreerdp/core/activation.c b/libfreerdp/core/activation.c index 61c7007dd..58d80ed82 100644 --- a/libfreerdp/core/activation.c +++ b/libfreerdp/core/activation.c @@ -36,8 +36,8 @@ static const char* const CTRLACTION_STRINGS[] = void rdp_write_synchronize_pdu(wStream* s, rdpSettings* settings) { - stream_write_UINT16(s, SYNCMSGTYPE_SYNC); /* messageType (2 bytes) */ - stream_write_UINT16(s, settings->PduSource); /* targetUser (2 bytes) */ + Stream_Write_UINT16(s, SYNCMSGTYPE_SYNC); /* messageType (2 bytes) */ + Stream_Write_UINT16(s, settings->PduSource); /* targetUser (2 bytes) */ } BOOL rdp_recv_synchronize_pdu(rdpRdp* rdp, wStream* s) @@ -70,16 +70,16 @@ BOOL rdp_recv_client_synchronize_pdu(rdpRdp* rdp, wStream* s) rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU; - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT16(s, messageType); /* messageType (2 bytes) */ + Stream_Read_UINT16(s, messageType); /* messageType (2 bytes) */ if (messageType != SYNCMSGTYPE_SYNC) return FALSE; /* targetUser (2 bytes) */ - stream_seek_UINT16(s); + Stream_Seek_UINT16(s); return TRUE; } @@ -97,21 +97,21 @@ BOOL rdp_send_client_synchronize_pdu(rdpRdp* rdp) BOOL rdp_recv_control_pdu(wStream* s, UINT16* action) { - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT16(s, *action); /* action (2 bytes) */ - stream_seek_UINT16(s); /* grantId (2 bytes) */ - stream_seek_UINT32(s); /* controlId (4 bytes) */ + Stream_Read_UINT16(s, *action); /* action (2 bytes) */ + Stream_Seek_UINT16(s); /* grantId (2 bytes) */ + Stream_Seek_UINT32(s); /* controlId (4 bytes) */ return TRUE; } void rdp_write_client_control_pdu(wStream* s, UINT16 action) { - stream_write_UINT16(s, action); /* action (2 bytes) */ - stream_write_UINT16(s, 0); /* grantId (2 bytes) */ - stream_write_UINT32(s, 0); /* controlId (4 bytes) */ + Stream_Write_UINT16(s, action); /* action (2 bytes) */ + Stream_Write_UINT16(s, 0); /* grantId (2 bytes) */ + Stream_Write_UINT32(s, 0); /* controlId (4 bytes) */ } BOOL rdp_recv_server_control_pdu(rdpRdp* rdp, wStream* s) @@ -129,6 +129,7 @@ BOOL rdp_recv_server_control_pdu(rdpRdp* rdp, wStream* s) case CTRLACTION_GRANTED_CONTROL: rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU; + rdp->resendFocus = TRUE; break; } @@ -141,9 +142,9 @@ BOOL rdp_send_server_control_cooperate_pdu(rdpRdp* rdp) s = rdp_data_pdu_init(rdp); - stream_write_UINT16(s, CTRLACTION_COOPERATE); /* action (2 bytes) */ - stream_write_UINT16(s, 0); /* grantId (2 bytes) */ - stream_write_UINT32(s, 0); /* controlId (4 bytes) */ + Stream_Write_UINT16(s, CTRLACTION_COOPERATE); /* action (2 bytes) */ + Stream_Write_UINT16(s, 0); /* grantId (2 bytes) */ + Stream_Write_UINT32(s, 0); /* controlId (4 bytes) */ return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id); } @@ -154,9 +155,9 @@ BOOL rdp_send_server_control_granted_pdu(rdpRdp* rdp) s = rdp_data_pdu_init(rdp); - stream_write_UINT16(s, CTRLACTION_GRANTED_CONTROL); /* action (2 bytes) */ - stream_write_UINT16(s, rdp->mcs->user_id); /* grantId (2 bytes) */ - stream_write_UINT32(s, 0x03EA); /* controlId (4 bytes) */ + Stream_Write_UINT16(s, CTRLACTION_GRANTED_CONTROL); /* action (2 bytes) */ + Stream_Write_UINT16(s, rdp->mcs->user_id); /* grantId (2 bytes) */ + Stream_Write_UINT32(s, 0x03EA); /* controlId (4 bytes) */ return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id); } @@ -173,25 +174,25 @@ BOOL rdp_send_client_control_pdu(rdpRdp* rdp, UINT16 action) void rdp_write_persistent_list_entry(wStream* s, UINT32 key1, UINT32 key2) { - stream_write_UINT32(s, key1); /* key1 (4 bytes) */ - stream_write_UINT32(s, key2); /* key2 (4 bytes) */ + Stream_Write_UINT32(s, key1); /* key1 (4 bytes) */ + Stream_Write_UINT32(s, key2); /* key2 (4 bytes) */ } void rdp_write_client_persistent_key_list_pdu(wStream* s, rdpSettings* settings) { - stream_write_UINT16(s, 0); /* numEntriesCache0 (2 bytes) */ - stream_write_UINT16(s, 0); /* numEntriesCache1 (2 bytes) */ - stream_write_UINT16(s, 0); /* numEntriesCache2 (2 bytes) */ - stream_write_UINT16(s, 0); /* numEntriesCache3 (2 bytes) */ - stream_write_UINT16(s, 0); /* numEntriesCache4 (2 bytes) */ - stream_write_UINT16(s, 0); /* totalEntriesCache0 (2 bytes) */ - stream_write_UINT16(s, 0); /* totalEntriesCache1 (2 bytes) */ - stream_write_UINT16(s, 0); /* totalEntriesCache2 (2 bytes) */ - stream_write_UINT16(s, 0); /* totalEntriesCache3 (2 bytes) */ - stream_write_UINT16(s, 0); /* totalEntriesCache4 (2 bytes) */ - stream_write_BYTE(s, PERSIST_FIRST_PDU | PERSIST_LAST_PDU); /* bBitMask (1 byte) */ - stream_write_BYTE(s, 0); /* pad1 (1 byte) */ - stream_write_UINT16(s, 0); /* pad3 (2 bytes) */ + Stream_Write_UINT16(s, 0); /* numEntriesCache0 (2 bytes) */ + Stream_Write_UINT16(s, 0); /* numEntriesCache1 (2 bytes) */ + Stream_Write_UINT16(s, 0); /* numEntriesCache2 (2 bytes) */ + Stream_Write_UINT16(s, 0); /* numEntriesCache3 (2 bytes) */ + Stream_Write_UINT16(s, 0); /* numEntriesCache4 (2 bytes) */ + Stream_Write_UINT16(s, 0); /* totalEntriesCache0 (2 bytes) */ + Stream_Write_UINT16(s, 0); /* totalEntriesCache1 (2 bytes) */ + Stream_Write_UINT16(s, 0); /* totalEntriesCache2 (2 bytes) */ + Stream_Write_UINT16(s, 0); /* totalEntriesCache3 (2 bytes) */ + Stream_Write_UINT16(s, 0); /* totalEntriesCache4 (2 bytes) */ + Stream_Write_UINT8(s, PERSIST_FIRST_PDU | PERSIST_LAST_PDU); /* bBitMask (1 byte) */ + Stream_Write_UINT8(s, 0); /* pad1 (1 byte) */ + Stream_Write_UINT16(s, 0); /* pad3 (2 bytes) */ /* entries */ } @@ -208,7 +209,7 @@ BOOL rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp) BOOL rdp_recv_client_font_list_pdu(wStream* s) { - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; return TRUE; @@ -216,10 +217,10 @@ BOOL rdp_recv_client_font_list_pdu(wStream* s) void rdp_write_client_font_list_pdu(wStream* s, UINT16 flags) { - stream_write_UINT16(s, 0); /* numberFonts (2 bytes) */ - stream_write_UINT16(s, 0); /* totalNumFonts (2 bytes) */ - stream_write_UINT16(s, flags); /* listFlags (2 bytes) */ - stream_write_UINT16(s, 50); /* entrySize (2 bytes) */ + Stream_Write_UINT16(s, 0); /* numberFonts (2 bytes) */ + Stream_Write_UINT16(s, 0); /* totalNumFonts (2 bytes) */ + Stream_Write_UINT16(s, flags); /* listFlags (2 bytes) */ + Stream_Write_UINT16(s, 50); /* entrySize (2 bytes) */ } BOOL rdp_send_client_font_list_pdu(rdpRdp* rdp, UINT16 flags) @@ -249,12 +250,12 @@ BOOL rdp_recv_server_font_map_pdu(rdpRdp* rdp, wStream* s) BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s) { rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU; - if(stream_get_left(s) >= 8) + if(Stream_GetRemainingLength(s) >= 8) { - stream_seek_UINT16(s); /* numberEntries (2 bytes) */ - stream_seek_UINT16(s); /* totalNumEntries (2 bytes) */ - stream_seek_UINT16(s); /* mapFlags (2 bytes) */ - stream_seek_UINT16(s); /* entrySize (2 bytes) */ + Stream_Seek_UINT16(s); /* numberEntries (2 bytes) */ + Stream_Seek_UINT16(s); /* totalNumEntries (2 bytes) */ + Stream_Seek_UINT16(s); /* mapFlags (2 bytes) */ + Stream_Seek_UINT16(s); /* entrySize (2 bytes) */ } return TRUE; @@ -266,10 +267,10 @@ BOOL rdp_send_server_font_map_pdu(rdpRdp* rdp) s = rdp_data_pdu_init(rdp); - stream_write_UINT16(s, 0); /* numberEntries (2 bytes) */ - stream_write_UINT16(s, 0); /* totalNumEntries (2 bytes) */ - stream_write_UINT16(s, FONTLIST_FIRST | FONTLIST_LAST); /* mapFlags (2 bytes) */ - stream_write_UINT16(s, 4); /* entrySize (2 bytes) */ + Stream_Write_UINT16(s, 0); /* numberEntries (2 bytes) */ + Stream_Write_UINT16(s, 0); /* totalNumEntries (2 bytes) */ + Stream_Write_UINT16(s, FONTLIST_FIRST | FONTLIST_LAST); /* mapFlags (2 bytes) */ + Stream_Write_UINT16(s, 4); /* entrySize (2 bytes) */ return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_MAP, rdp->mcs->user_id); } @@ -282,19 +283,26 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s) * Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain * the following fields. */ - if (stream_get_left(s) > 0) + if (Stream_GetRemainingLength(s) > 0) { - do { - if(stream_get_left(s) < 4) + do + { + if (Stream_GetRemainingLength(s) < 4) break; - stream_read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ - if(stream_get_left(s) < 2) + + Stream_Read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ + + if (Stream_GetRemainingLength(s) < 2) break; - stream_read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ - if(stream_get_left(s) < lengthSourceDescriptor) + + Stream_Read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ + + if (Stream_GetRemainingLength(s) < lengthSourceDescriptor) break; - stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */ - } while(0); + + Stream_Seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */ + } + while(0); } rdp->state = CONNECTION_STATE_CAPABILITY; @@ -303,6 +311,7 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s) { if (rdp_check_fds(rdp) < 0) return FALSE; + if (rdp->disconnect) break; } @@ -313,14 +322,20 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s) BOOL rdp_send_deactivate_all(rdpRdp* rdp) { wStream* s; + BOOL status; - s = rdp_pdu_init(rdp); + s = Stream_New(NULL, 1024); + rdp_init_stream_pdu(rdp, s); - stream_write_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ - stream_write_UINT16(s, 1); /* lengthSourceDescriptor (2 bytes) */ - stream_write_BYTE(s, 0); /* sourceDescriptor (should be 0x00) */ + Stream_Write_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ + Stream_Write_UINT16(s, 1); /* lengthSourceDescriptor (2 bytes) */ + Stream_Write_UINT8(s, 0); /* sourceDescriptor (should be 0x00) */ - return rdp_send_pdu(rdp, s, PDU_TYPE_DEACTIVATE_ALL, rdp->mcs->user_id); + status = rdp_send_pdu(rdp, s, PDU_TYPE_DEACTIVATE_ALL, rdp->mcs->user_id); + + Stream_Free(s, TRUE); + + return status; } BOOL rdp_server_accept_client_control_pdu(rdpRdp* rdp, wStream* s) @@ -329,11 +344,13 @@ BOOL rdp_server_accept_client_control_pdu(rdpRdp* rdp, wStream* s) if (!rdp_recv_control_pdu(s, &action)) return FALSE; + if (action == CTRLACTION_REQUEST_CONTROL) { if (!rdp_send_server_control_granted_pdu(rdp)) return FALSE; } + return TRUE; } @@ -341,6 +358,7 @@ BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s) { if (!rdp_recv_client_font_list_pdu(s)) return FALSE; + if (!rdp_send_server_font_map_pdu(rdp)) return FALSE; diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index a927b3cc2..a5f3f7ee7 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -114,37 +114,37 @@ GUID CODEC_GUID_JPEG = void rdp_read_capability_set_header(wStream* s, UINT16* length, UINT16* type) { - stream_read_UINT16(s, *type); /* capabilitySetType */ - stream_read_UINT16(s, *length); /* lengthCapability */ + Stream_Read_UINT16(s, *type); /* capabilitySetType */ + Stream_Read_UINT16(s, *length); /* lengthCapability */ } void rdp_write_capability_set_header(wStream* s, UINT16 length, UINT16 type) { - stream_write_UINT16(s, type); /* capabilitySetType */ - stream_write_UINT16(s, length); /* lengthCapability */ + Stream_Write_UINT16(s, type); /* capabilitySetType */ + Stream_Write_UINT16(s, length); /* lengthCapability */ } -BYTE* rdp_capability_set_start(wStream* s) +int rdp_capability_set_start(wStream* s) { - BYTE* header; + int header; - stream_get_mark(s, header); - stream_write_zero(s, CAPSET_HEADER_LENGTH); + header = Stream_GetPosition(s); + Stream_Zero(s, CAPSET_HEADER_LENGTH); return header; } -void rdp_capability_set_finish(wStream* s, BYTE* header, UINT16 type) +void rdp_capability_set_finish(wStream* s, int header, UINT16 type) { + int footer; UINT16 length; - BYTE* footer; - footer = s->pointer; + footer = Stream_GetPosition(s); length = footer - header; - stream_set_mark(s, header); + Stream_SetPosition(s, header); rdp_write_capability_set_header(s, length, type); - stream_set_mark(s, footer); + Stream_SetPosition(s, footer); } /** @@ -166,24 +166,24 @@ BOOL rdp_read_general_capability_set(wStream* s, UINT16 length, rdpSettings* set if (settings->ServerMode) { - stream_read_UINT16(s, settings->OsMajorType); /* osMajorType (2 bytes) */ - stream_read_UINT16(s, settings->OsMinorType); /* osMinorType (2 bytes) */ + Stream_Read_UINT16(s, settings->OsMajorType); /* osMajorType (2 bytes) */ + Stream_Read_UINT16(s, settings->OsMinorType); /* osMinorType (2 bytes) */ } else { - stream_seek_UINT16(s); /* osMajorType (2 bytes) */ - stream_seek_UINT16(s); /* osMinorType (2 bytes) */ + Stream_Seek_UINT16(s); /* osMajorType (2 bytes) */ + Stream_Seek_UINT16(s); /* osMinorType (2 bytes) */ } - stream_seek_UINT16(s); /* protocolVersion (2 bytes) */ - stream_seek_UINT16(s); /* pad2OctetsA (2 bytes) */ - stream_seek_UINT16(s); /* generalCompressionTypes (2 bytes) */ - stream_read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ - stream_seek_UINT16(s); /* updateCapabilityFlag (2 bytes) */ - stream_seek_UINT16(s); /* remoteUnshareFlag (2 bytes) */ - stream_seek_UINT16(s); /* generalCompressionLevel (2 bytes) */ - stream_read_BYTE(s, refreshRectSupport); /* refreshRectSupport (1 byte) */ - stream_read_BYTE(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */ + Stream_Seek_UINT16(s); /* protocolVersion (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2OctetsA (2 bytes) */ + Stream_Seek_UINT16(s); /* generalCompressionTypes (2 bytes) */ + Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ + Stream_Seek_UINT16(s); /* updateCapabilityFlag (2 bytes) */ + Stream_Seek_UINT16(s); /* remoteUnshareFlag (2 bytes) */ + Stream_Seek_UINT16(s); /* generalCompressionLevel (2 bytes) */ + Stream_Read_UINT8(s, refreshRectSupport); /* refreshRectSupport (1 byte) */ + Stream_Read_UINT8(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */ if (!(extraFlags & FASTPATH_OUTPUT_SUPPORTED)) settings->FastPathOutput = FALSE; @@ -206,9 +206,11 @@ BOOL rdp_read_general_capability_set(wStream* s, UINT16 length, rdpSettings* set void rdp_write_general_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT16 extraFlags; + Stream_EnsureRemainingCapacity(s, 64); + header = rdp_capability_set_start(s); extraFlags = LONG_CREDENTIALS_SUPPORTED | NO_BITMAP_COMPRESSION_HDR; @@ -222,17 +224,17 @@ void rdp_write_general_capability_set(wStream* s, rdpSettings* settings) if (settings->SaltedChecksum) extraFlags |= ENC_SALTED_CHECKSUM; - stream_write_UINT16(s, settings->OsMajorType); /* osMajorType (2 bytes) */ - stream_write_UINT16(s, settings->OsMinorType); /* osMinorType (2 bytes) */ - stream_write_UINT16(s, CAPS_PROTOCOL_VERSION); /* protocolVersion (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2OctetsA (2 bytes) */ - stream_write_UINT16(s, 0); /* generalCompressionTypes (2 bytes) */ - stream_write_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ - stream_write_UINT16(s, 0); /* updateCapabilityFlag (2 bytes) */ - stream_write_UINT16(s, 0); /* remoteUnshareFlag (2 bytes) */ - stream_write_UINT16(s, 0); /* generalCompressionLevel (2 bytes) */ - stream_write_BYTE(s, settings->RefreshRect); /* refreshRectSupport (1 byte) */ - stream_write_BYTE(s, settings->SuppressOutput); /* suppressOutputSupport (1 byte) */ + Stream_Write_UINT16(s, settings->OsMajorType); /* osMajorType (2 bytes) */ + Stream_Write_UINT16(s, settings->OsMinorType); /* osMinorType (2 bytes) */ + Stream_Write_UINT16(s, CAPS_PROTOCOL_VERSION); /* protocolVersion (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2OctetsA (2 bytes) */ + Stream_Write_UINT16(s, 0); /* generalCompressionTypes (2 bytes) */ + Stream_Write_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ + Stream_Write_UINT16(s, 0); /* updateCapabilityFlag (2 bytes) */ + Stream_Write_UINT16(s, 0); /* remoteUnshareFlag (2 bytes) */ + Stream_Write_UINT16(s, 0); /* generalCompressionLevel (2 bytes) */ + Stream_Write_UINT8(s, settings->RefreshRect); /* refreshRectSupport (1 byte) */ + Stream_Write_UINT8(s, settings->SuppressOutput); /* suppressOutputSupport (1 byte) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL); } @@ -256,17 +258,17 @@ BOOL rdp_print_general_capability_set(wStream* s, UINT16 length) fprintf(stderr, "GeneralCapabilitySet (length %d):\n", length); - stream_read_UINT16(s, osMajorType); /* osMajorType (2 bytes) */ - stream_read_UINT16(s, osMinorType); /* osMinorType (2 bytes) */ - stream_read_UINT16(s, protocolVersion); /* protocolVersion (2 bytes) */ - stream_read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ - stream_read_UINT16(s, generalCompressionTypes); /* generalCompressionTypes (2 bytes) */ - stream_read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ - stream_read_UINT16(s, updateCapabilityFlag); /* updateCapabilityFlag (2 bytes) */ - stream_read_UINT16(s, remoteUnshareFlag); /* remoteUnshareFlag (2 bytes) */ - stream_read_UINT16(s, generalCompressionLevel); /* generalCompressionLevel (2 bytes) */ - stream_read_BYTE(s, refreshRectSupport); /* refreshRectSupport (1 byte) */ - stream_read_BYTE(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */ + Stream_Read_UINT16(s, osMajorType); /* osMajorType (2 bytes) */ + Stream_Read_UINT16(s, osMinorType); /* osMinorType (2 bytes) */ + Stream_Read_UINT16(s, protocolVersion); /* protocolVersion (2 bytes) */ + Stream_Read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ + Stream_Read_UINT16(s, generalCompressionTypes); /* generalCompressionTypes (2 bytes) */ + Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ + Stream_Read_UINT16(s, updateCapabilityFlag); /* updateCapabilityFlag (2 bytes) */ + Stream_Read_UINT16(s, remoteUnshareFlag); /* remoteUnshareFlag (2 bytes) */ + Stream_Read_UINT16(s, generalCompressionLevel); /* generalCompressionLevel (2 bytes) */ + Stream_Read_UINT8(s, refreshRectSupport); /* refreshRectSupport (1 byte) */ + Stream_Read_UINT8(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */ fprintf(stderr, "\tosMajorType: 0x%04X\n", osMajorType); fprintf(stderr, "\tosMinorType: 0x%04X\n", osMinorType); @@ -302,19 +304,19 @@ BOOL rdp_read_bitmap_capability_set(wStream* s, UINT16 length, rdpSettings* sett if (length < 28) return FALSE; - stream_read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ - stream_seek_UINT16(s); /* receive1BitPerPixel (2 bytes) */ - stream_seek_UINT16(s); /* receive4BitsPerPixel (2 bytes) */ - stream_seek_UINT16(s); /* receive8BitsPerPixel (2 bytes) */ - stream_read_UINT16(s, desktopWidth); /* desktopWidth (2 bytes) */ - stream_read_UINT16(s, desktopHeight); /* desktopHeight (2 bytes) */ - stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ - stream_read_UINT16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */ - stream_seek_UINT16(s); /* bitmapCompressionFlag (2 bytes) */ - stream_seek_BYTE(s); /* highColorFlags (1 byte) */ - stream_read_BYTE(s, drawingFlags); /* drawingFlags (1 byte) */ - stream_seek_UINT16(s); /* multipleRectangleSupport (2 bytes) */ - stream_seek_UINT16(s); /* pad2OctetsB (2 bytes) */ + Stream_Read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ + Stream_Seek_UINT16(s); /* receive1BitPerPixel (2 bytes) */ + Stream_Seek_UINT16(s); /* receive4BitsPerPixel (2 bytes) */ + Stream_Seek_UINT16(s); /* receive8BitsPerPixel (2 bytes) */ + Stream_Read_UINT16(s, desktopWidth); /* desktopWidth (2 bytes) */ + Stream_Read_UINT16(s, desktopHeight); /* desktopHeight (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */ + Stream_Seek_UINT16(s); /* bitmapCompressionFlag (2 bytes) */ + Stream_Seek_UINT8(s); /* highColorFlags (1 byte) */ + Stream_Read_UINT8(s, drawingFlags); /* drawingFlags (1 byte) */ + Stream_Seek_UINT16(s); /* multipleRectangleSupport (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2OctetsB (2 bytes) */ if (!settings->ServerMode && (preferredBitsPerPixel != settings->ColorDepth)) { @@ -344,11 +346,13 @@ BOOL rdp_read_bitmap_capability_set(wStream* s, UINT16 length, rdpSettings* sett void rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; BYTE drawingFlags = 0; UINT16 desktopResizeFlag; UINT16 preferredBitsPerPixel; + Stream_EnsureRemainingCapacity(s, 64); + header = rdp_capability_set_start(s); drawingFlags |= DRAW_ALLOW_SKIP_ALPHA; @@ -361,19 +365,19 @@ void rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) desktopResizeFlag = settings->DesktopResize; - stream_write_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ - stream_write_UINT16(s, 1); /* receive1BitPerPixel (2 bytes) */ - stream_write_UINT16(s, 1); /* receive4BitsPerPixel (2 bytes) */ - stream_write_UINT16(s, 1); /* receive8BitsPerPixel (2 bytes) */ - stream_write_UINT16(s, settings->DesktopWidth); /* desktopWidth (2 bytes) */ - stream_write_UINT16(s, settings->DesktopHeight); /* desktopHeight (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ - stream_write_UINT16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */ - stream_write_UINT16(s, 1); /* bitmapCompressionFlag (2 bytes) */ - stream_write_BYTE(s, 0); /* highColorFlags (1 byte) */ - stream_write_BYTE(s, drawingFlags); /* drawingFlags (1 byte) */ - stream_write_UINT16(s, 1); /* multipleRectangleSupport (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2OctetsB (2 bytes) */ + Stream_Write_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ + Stream_Write_UINT16(s, 1); /* receive1BitPerPixel (2 bytes) */ + Stream_Write_UINT16(s, 1); /* receive4BitsPerPixel (2 bytes) */ + Stream_Write_UINT16(s, 1); /* receive8BitsPerPixel (2 bytes) */ + Stream_Write_UINT16(s, settings->DesktopWidth); /* desktopWidth (2 bytes) */ + Stream_Write_UINT16(s, settings->DesktopHeight); /* desktopHeight (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + Stream_Write_UINT16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */ + Stream_Write_UINT16(s, 1); /* bitmapCompressionFlag (2 bytes) */ + Stream_Write_UINT8(s, 0); /* highColorFlags (1 byte) */ + Stream_Write_UINT8(s, drawingFlags); /* drawingFlags (1 byte) */ + Stream_Write_UINT16(s, 1); /* multipleRectangleSupport (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2OctetsB (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP); } @@ -399,19 +403,19 @@ BOOL rdp_print_bitmap_capability_set(wStream* s, UINT16 length) if (length < 28) return FALSE; - stream_read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ - stream_read_UINT16(s, receive1BitPerPixel); /* receive1BitPerPixel (2 bytes) */ - stream_read_UINT16(s, receive4BitsPerPixel); /* receive4BitsPerPixel (2 bytes) */ - stream_read_UINT16(s, receive8BitsPerPixel); /* receive8BitsPerPixel (2 bytes) */ - stream_read_UINT16(s, desktopWidth); /* desktopWidth (2 bytes) */ - stream_read_UINT16(s, desktopHeight); /* desktopHeight (2 bytes) */ - stream_read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ - stream_read_UINT16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */ - stream_read_UINT16(s, bitmapCompressionFlag); /* bitmapCompressionFlag (2 bytes) */ - stream_read_BYTE(s, highColorFlags); /* highColorFlags (1 byte) */ - stream_read_BYTE(s, drawingFlags); /* drawingFlags (1 byte) */ - stream_read_UINT16(s, multipleRectangleSupport); /* multipleRectangleSupport (2 bytes) */ - stream_read_UINT16(s, pad2OctetsB); /* pad2OctetsB (2 bytes) */ + Stream_Read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ + Stream_Read_UINT16(s, receive1BitPerPixel); /* receive1BitPerPixel (2 bytes) */ + Stream_Read_UINT16(s, receive4BitsPerPixel); /* receive4BitsPerPixel (2 bytes) */ + Stream_Read_UINT16(s, receive8BitsPerPixel); /* receive8BitsPerPixel (2 bytes) */ + Stream_Read_UINT16(s, desktopWidth); /* desktopWidth (2 bytes) */ + Stream_Read_UINT16(s, desktopHeight); /* desktopHeight (2 bytes) */ + Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */ + Stream_Read_UINT16(s, bitmapCompressionFlag); /* bitmapCompressionFlag (2 bytes) */ + Stream_Read_UINT8(s, highColorFlags); /* highColorFlags (1 byte) */ + Stream_Read_UINT8(s, drawingFlags); /* drawingFlags (1 byte) */ + Stream_Read_UINT16(s, multipleRectangleSupport); /* multipleRectangleSupport (2 bytes) */ + Stream_Read_UINT16(s, pad2OctetsB); /* pad2OctetsB (2 bytes) */ fprintf(stderr, "\tpreferredBitsPerPixel: 0x%04X\n", preferredBitsPerPixel); fprintf(stderr, "\treceive1BitPerPixel: 0x%04X\n", receive1BitPerPixel); @@ -448,23 +452,23 @@ BOOL rdp_read_order_capability_set(wStream* s, UINT16 length, rdpSettings* setti if (length < 88) return FALSE; - stream_seek(s, 16); /* terminalDescriptor (16 bytes) */ - stream_seek_UINT32(s); /* pad4OctetsA (4 bytes) */ - stream_seek_UINT16(s); /* desktopSaveXGranularity (2 bytes) */ - stream_seek_UINT16(s); /* desktopSaveYGranularity (2 bytes) */ - stream_seek_UINT16(s); /* pad2OctetsA (2 bytes) */ - stream_seek_UINT16(s); /* maximumOrderLevel (2 bytes) */ - stream_seek_UINT16(s); /* numberFonts (2 bytes) */ - stream_read_UINT16(s, orderFlags); /* orderFlags (2 bytes) */ - stream_read(s, orderSupport, 32); /* orderSupport (32 bytes) */ - stream_seek_UINT16(s); /* textFlags (2 bytes) */ - stream_read_UINT16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */ - stream_seek_UINT32(s); /* pad4OctetsB (4 bytes) */ - stream_seek_UINT32(s); /* desktopSaveSize (4 bytes) */ - stream_seek_UINT16(s); /* pad2OctetsC (2 bytes) */ - stream_seek_UINT16(s); /* pad2OctetsD (2 bytes) */ - stream_seek_UINT16(s); /* textANSICodePage (2 bytes) */ - stream_seek_UINT16(s); /* pad2OctetsE (2 bytes) */ + Stream_Seek(s, 16); /* terminalDescriptor (16 bytes) */ + Stream_Seek_UINT32(s); /* pad4OctetsA (4 bytes) */ + Stream_Seek_UINT16(s); /* desktopSaveXGranularity (2 bytes) */ + Stream_Seek_UINT16(s); /* desktopSaveYGranularity (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2OctetsA (2 bytes) */ + Stream_Seek_UINT16(s); /* maximumOrderLevel (2 bytes) */ + Stream_Seek_UINT16(s); /* numberFonts (2 bytes) */ + Stream_Read_UINT16(s, orderFlags); /* orderFlags (2 bytes) */ + Stream_Read(s, orderSupport, 32); /* orderSupport (32 bytes) */ + Stream_Seek_UINT16(s); /* textFlags (2 bytes) */ + Stream_Read_UINT16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */ + Stream_Seek_UINT32(s); /* pad4OctetsB (4 bytes) */ + Stream_Seek_UINT32(s); /* desktopSaveSize (4 bytes) */ + Stream_Seek_UINT16(s); /* pad2OctetsC (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2OctetsD (2 bytes) */ + Stream_Seek_UINT16(s); /* textANSICodePage (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2OctetsE (2 bytes) */ for (i = 0; i < 32; i++) { @@ -484,11 +488,13 @@ BOOL rdp_read_order_capability_set(wStream* s, UINT16 length, rdpSettings* setti void rdp_write_order_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT16 orderFlags; UINT16 orderSupportExFlags; UINT16 textANSICodePage; + Stream_EnsureRemainingCapacity(s, 64); + header = rdp_capability_set_start(s); /* see [MSDN-CP]: http://msdn.microsoft.com/en-us/library/dd317756 */ @@ -509,23 +515,23 @@ void rdp_write_order_capability_set(wStream* s, rdpSettings* settings) orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT; } - stream_write_zero(s, 16); /* terminalDescriptor (16 bytes) */ - stream_write_UINT32(s, 0); /* pad4OctetsA (4 bytes) */ - stream_write_UINT16(s, 1); /* desktopSaveXGranularity (2 bytes) */ - stream_write_UINT16(s, 20); /* desktopSaveYGranularity (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2OctetsA (2 bytes) */ - stream_write_UINT16(s, 1); /* maximumOrderLevel (2 bytes) */ - stream_write_UINT16(s, 0); /* numberFonts (2 bytes) */ - stream_write_UINT16(s, orderFlags); /* orderFlags (2 bytes) */ - stream_write(s, settings->OrderSupport, 32); /* orderSupport (32 bytes) */ - stream_write_UINT16(s, 0); /* textFlags (2 bytes) */ - stream_write_UINT16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */ - stream_write_UINT32(s, 0); /* pad4OctetsB (4 bytes) */ - stream_write_UINT32(s, 230400); /* desktopSaveSize (4 bytes) */ - stream_write_UINT16(s, 0); /* pad2OctetsC (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2OctetsD (2 bytes) */ - stream_write_UINT16(s, 0); /* textANSICodePage (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2OctetsE (2 bytes) */ + Stream_Zero(s, 16); /* terminalDescriptor (16 bytes) */ + Stream_Write_UINT32(s, 0); /* pad4OctetsA (4 bytes) */ + Stream_Write_UINT16(s, 1); /* desktopSaveXGranularity (2 bytes) */ + Stream_Write_UINT16(s, 20); /* desktopSaveYGranularity (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2OctetsA (2 bytes) */ + Stream_Write_UINT16(s, 1); /* maximumOrderLevel (2 bytes) */ + Stream_Write_UINT16(s, 0); /* numberFonts (2 bytes) */ + Stream_Write_UINT16(s, orderFlags); /* orderFlags (2 bytes) */ + Stream_Write(s, settings->OrderSupport, 32); /* orderSupport (32 bytes) */ + Stream_Write_UINT16(s, 0); /* textFlags (2 bytes) */ + Stream_Write_UINT16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */ + Stream_Write_UINT32(s, 0); /* pad4OctetsB (4 bytes) */ + Stream_Write_UINT32(s, 230400); /* desktopSaveSize (4 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2OctetsC (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2OctetsD (2 bytes) */ + Stream_Write_UINT16(s, 0); /* textANSICodePage (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2OctetsE (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER); } @@ -555,23 +561,23 @@ BOOL rdp_print_order_capability_set(wStream* s, UINT16 length) if (length < 88) return FALSE; - stream_read(s, terminalDescriptor, 16); /* terminalDescriptor (16 bytes) */ - stream_read_UINT32(s, pad4OctetsA); /* pad4OctetsA (4 bytes) */ - stream_read_UINT16(s, desktopSaveXGranularity); /* desktopSaveXGranularity (2 bytes) */ - stream_read_UINT16(s, desktopSaveYGranularity); /* desktopSaveYGranularity (2 bytes) */ - stream_read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ - stream_read_UINT16(s, maximumOrderLevel); /* maximumOrderLevel (2 bytes) */ - stream_read_UINT16(s, numberFonts); /* numberFonts (2 bytes) */ - stream_read_UINT16(s, orderFlags); /* orderFlags (2 bytes) */ - stream_read(s, orderSupport, 32); /* orderSupport (32 bytes) */ - stream_read_UINT16(s, textFlags); /* textFlags (2 bytes) */ - stream_read_UINT16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */ - stream_read_UINT32(s, pad4OctetsB); /* pad4OctetsB (4 bytes) */ - stream_read_UINT32(s, desktopSaveSize); /* desktopSaveSize (4 bytes) */ - stream_read_UINT16(s, pad2OctetsC); /* pad2OctetsC (2 bytes) */ - stream_read_UINT16(s, pad2OctetsD); /* pad2OctetsD (2 bytes) */ - stream_read_UINT16(s, textANSICodePage); /* textANSICodePage (2 bytes) */ - stream_read_UINT16(s, pad2OctetsE); /* pad2OctetsE (2 bytes) */ + Stream_Read(s, terminalDescriptor, 16); /* terminalDescriptor (16 bytes) */ + Stream_Read_UINT32(s, pad4OctetsA); /* pad4OctetsA (4 bytes) */ + Stream_Read_UINT16(s, desktopSaveXGranularity); /* desktopSaveXGranularity (2 bytes) */ + Stream_Read_UINT16(s, desktopSaveYGranularity); /* desktopSaveYGranularity (2 bytes) */ + Stream_Read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ + Stream_Read_UINT16(s, maximumOrderLevel); /* maximumOrderLevel (2 bytes) */ + Stream_Read_UINT16(s, numberFonts); /* numberFonts (2 bytes) */ + Stream_Read_UINT16(s, orderFlags); /* orderFlags (2 bytes) */ + Stream_Read(s, orderSupport, 32); /* orderSupport (32 bytes) */ + Stream_Read_UINT16(s, textFlags); /* textFlags (2 bytes) */ + Stream_Read_UINT16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */ + Stream_Read_UINT32(s, pad4OctetsB); /* pad4OctetsB (4 bytes) */ + Stream_Read_UINT32(s, desktopSaveSize); /* desktopSaveSize (4 bytes) */ + Stream_Read_UINT16(s, pad2OctetsC); /* pad2OctetsC (2 bytes) */ + Stream_Read_UINT16(s, pad2OctetsD); /* pad2OctetsD (2 bytes) */ + Stream_Read_UINT16(s, textANSICodePage); /* textANSICodePage (2 bytes) */ + Stream_Read_UINT16(s, pad2OctetsE); /* pad2OctetsE (2 bytes) */ fprintf(stderr, "\tpad4OctetsA: 0x%08X\n", pad4OctetsA); fprintf(stderr, "\tdesktopSaveXGranularity: 0x%04X\n", desktopSaveXGranularity); @@ -640,18 +646,18 @@ BOOL rdp_read_bitmap_cache_capability_set(wStream* s, UINT16 length, rdpSettings if (length < 40) return FALSE; - stream_seek_UINT32(s); /* pad1 (4 bytes) */ - stream_seek_UINT32(s); /* pad2 (4 bytes) */ - stream_seek_UINT32(s); /* pad3 (4 bytes) */ - stream_seek_UINT32(s); /* pad4 (4 bytes) */ - stream_seek_UINT32(s); /* pad5 (4 bytes) */ - stream_seek_UINT32(s); /* pad6 (4 bytes) */ - stream_seek_UINT16(s); /* Cache0Entries (2 bytes) */ - stream_seek_UINT16(s); /* Cache0MaximumCellSize (2 bytes) */ - stream_seek_UINT16(s); /* Cache1Entries (2 bytes) */ - stream_seek_UINT16(s); /* Cache1MaximumCellSize (2 bytes) */ - stream_seek_UINT16(s); /* Cache2Entries (2 bytes) */ - stream_seek_UINT16(s); /* Cache2MaximumCellSize (2 bytes) */ + Stream_Seek_UINT32(s); /* pad1 (4 bytes) */ + Stream_Seek_UINT32(s); /* pad2 (4 bytes) */ + Stream_Seek_UINT32(s); /* pad3 (4 bytes) */ + Stream_Seek_UINT32(s); /* pad4 (4 bytes) */ + Stream_Seek_UINT32(s); /* pad5 (4 bytes) */ + Stream_Seek_UINT32(s); /* pad6 (4 bytes) */ + Stream_Seek_UINT16(s); /* Cache0Entries (2 bytes) */ + Stream_Seek_UINT16(s); /* Cache0MaximumCellSize (2 bytes) */ + Stream_Seek_UINT16(s); /* Cache1Entries (2 bytes) */ + Stream_Seek_UINT16(s); /* Cache1MaximumCellSize (2 bytes) */ + Stream_Seek_UINT16(s); /* Cache2Entries (2 bytes) */ + Stream_Seek_UINT16(s); /* Cache2MaximumCellSize (2 bytes) */ return TRUE; } @@ -666,31 +672,33 @@ BOOL rdp_read_bitmap_cache_capability_set(wStream* s, UINT16 length, rdpSettings void rdp_write_bitmap_cache_capability_set(wStream* s, rdpSettings* settings) { int bpp; + int header; UINT16 size; - BYTE* header; + + Stream_EnsureRemainingCapacity(s, 64); header = rdp_capability_set_start(s); bpp = (settings->ColorDepth + 7) / 8; - stream_write_UINT32(s, 0); /* pad1 (4 bytes) */ - stream_write_UINT32(s, 0); /* pad2 (4 bytes) */ - stream_write_UINT32(s, 0); /* pad3 (4 bytes) */ - stream_write_UINT32(s, 0); /* pad4 (4 bytes) */ - stream_write_UINT32(s, 0); /* pad5 (4 bytes) */ - stream_write_UINT32(s, 0); /* pad6 (4 bytes) */ + Stream_Write_UINT32(s, 0); /* pad1 (4 bytes) */ + Stream_Write_UINT32(s, 0); /* pad2 (4 bytes) */ + Stream_Write_UINT32(s, 0); /* pad3 (4 bytes) */ + Stream_Write_UINT32(s, 0); /* pad4 (4 bytes) */ + Stream_Write_UINT32(s, 0); /* pad5 (4 bytes) */ + Stream_Write_UINT32(s, 0); /* pad6 (4 bytes) */ size = bpp * 256; - stream_write_UINT16(s, 200); /* Cache0Entries (2 bytes) */ - stream_write_UINT16(s, size); /* Cache0MaximumCellSize (2 bytes) */ + Stream_Write_UINT16(s, 200); /* Cache0Entries (2 bytes) */ + Stream_Write_UINT16(s, size); /* Cache0MaximumCellSize (2 bytes) */ size = bpp * 1024; - stream_write_UINT16(s, 600); /* Cache1Entries (2 bytes) */ - stream_write_UINT16(s, size); /* Cache1MaximumCellSize (2 bytes) */ + Stream_Write_UINT16(s, 600); /* Cache1Entries (2 bytes) */ + Stream_Write_UINT16(s, size); /* Cache1MaximumCellSize (2 bytes) */ size = bpp * 4096; - stream_write_UINT16(s, 1000); /* Cache2Entries (2 bytes) */ - stream_write_UINT16(s, size); /* Cache2MaximumCellSize (2 bytes) */ + Stream_Write_UINT16(s, 1000); /* Cache2Entries (2 bytes) */ + Stream_Write_UINT16(s, size); /* Cache2MaximumCellSize (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE); } @@ -711,18 +719,18 @@ BOOL rdp_print_bitmap_cache_capability_set(wStream* s, UINT16 length) if (length < 40) return FALSE; - stream_read_UINT32(s, pad1); /* pad1 (4 bytes) */ - stream_read_UINT32(s, pad2); /* pad2 (4 bytes) */ - stream_read_UINT32(s, pad3); /* pad3 (4 bytes) */ - stream_read_UINT32(s, pad4); /* pad4 (4 bytes) */ - stream_read_UINT32(s, pad5); /* pad5 (4 bytes) */ - stream_read_UINT32(s, pad6); /* pad6 (4 bytes) */ - stream_read_UINT16(s, Cache0Entries); /* Cache0Entries (2 bytes) */ - stream_read_UINT16(s, Cache0MaximumCellSize); /* Cache0MaximumCellSize (2 bytes) */ - stream_read_UINT16(s, Cache1Entries); /* Cache1Entries (2 bytes) */ - stream_read_UINT16(s, Cache1MaximumCellSize); /* Cache1MaximumCellSize (2 bytes) */ - stream_read_UINT16(s, Cache2Entries); /* Cache2Entries (2 bytes) */ - stream_read_UINT16(s, Cache2MaximumCellSize); /* Cache2MaximumCellSize (2 bytes) */ + Stream_Read_UINT32(s, pad1); /* pad1 (4 bytes) */ + Stream_Read_UINT32(s, pad2); /* pad2 (4 bytes) */ + Stream_Read_UINT32(s, pad3); /* pad3 (4 bytes) */ + Stream_Read_UINT32(s, pad4); /* pad4 (4 bytes) */ + Stream_Read_UINT32(s, pad5); /* pad5 (4 bytes) */ + Stream_Read_UINT32(s, pad6); /* pad6 (4 bytes) */ + Stream_Read_UINT16(s, Cache0Entries); /* Cache0Entries (2 bytes) */ + Stream_Read_UINT16(s, Cache0MaximumCellSize); /* Cache0MaximumCellSize (2 bytes) */ + Stream_Read_UINT16(s, Cache1Entries); /* Cache1Entries (2 bytes) */ + Stream_Read_UINT16(s, Cache1MaximumCellSize); /* Cache1MaximumCellSize (2 bytes) */ + Stream_Read_UINT16(s, Cache2Entries); /* Cache2Entries (2 bytes) */ + Stream_Read_UINT16(s, Cache2MaximumCellSize); /* Cache2MaximumCellSize (2 bytes) */ fprintf(stderr, "\tpad1: 0x%08X\n", pad1); fprintf(stderr, "\tpad2: 0x%08X\n", pad2); @@ -753,10 +761,10 @@ BOOL rdp_read_control_capability_set(wStream* s, UINT16 length, rdpSettings* set if (length < 12) return FALSE; - stream_seek_UINT16(s); /* controlFlags (2 bytes) */ - stream_seek_UINT16(s); /* remoteDetachFlag (2 bytes) */ - stream_seek_UINT16(s); /* controlInterest (2 bytes) */ - stream_seek_UINT16(s); /* detachInterest (2 bytes) */ + Stream_Seek_UINT16(s); /* controlFlags (2 bytes) */ + Stream_Seek_UINT16(s); /* remoteDetachFlag (2 bytes) */ + Stream_Seek_UINT16(s); /* controlInterest (2 bytes) */ + Stream_Seek_UINT16(s); /* detachInterest (2 bytes) */ return TRUE; } @@ -770,14 +778,16 @@ BOOL rdp_read_control_capability_set(wStream* s, UINT16 length, rdpSettings* set void rdp_write_control_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; + + Stream_EnsureRemainingCapacity(s, 32); header = rdp_capability_set_start(s); - stream_write_UINT16(s, 0); /* controlFlags (2 bytes) */ - stream_write_UINT16(s, 0); /* remoteDetachFlag (2 bytes) */ - stream_write_UINT16(s, 2); /* controlInterest (2 bytes) */ - stream_write_UINT16(s, 2); /* detachInterest (2 bytes) */ + Stream_Write_UINT16(s, 0); /* controlFlags (2 bytes) */ + Stream_Write_UINT16(s, 0); /* remoteDetachFlag (2 bytes) */ + Stream_Write_UINT16(s, 2); /* controlInterest (2 bytes) */ + Stream_Write_UINT16(s, 2); /* detachInterest (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL); } @@ -794,10 +804,10 @@ BOOL rdp_print_control_capability_set(wStream* s, UINT16 length) if (length < 12) return FALSE; - stream_read_UINT16(s, controlFlags); /* controlFlags (2 bytes) */ - stream_read_UINT16(s, remoteDetachFlag); /* remoteDetachFlag (2 bytes) */ - stream_read_UINT16(s, controlInterest); /* controlInterest (2 bytes) */ - stream_read_UINT16(s, detachInterest); /* detachInterest (2 bytes) */ + Stream_Read_UINT16(s, controlFlags); /* controlFlags (2 bytes) */ + Stream_Read_UINT16(s, remoteDetachFlag); /* remoteDetachFlag (2 bytes) */ + Stream_Read_UINT16(s, controlInterest); /* controlInterest (2 bytes) */ + Stream_Read_UINT16(s, detachInterest); /* detachInterest (2 bytes) */ fprintf(stderr, "\tcontrolFlags: 0x%04X\n", controlFlags); fprintf(stderr, "\tremoteDetachFlag: 0x%04X\n", remoteDetachFlag); @@ -820,10 +830,10 @@ BOOL rdp_read_window_activation_capability_set(wStream* s, UINT16 length, rdpSet if (length < 12) return FALSE; - stream_seek_UINT16(s); /* helpKeyFlag (2 bytes) */ - stream_seek_UINT16(s); /* helpKeyIndexFlag (2 bytes) */ - stream_seek_UINT16(s); /* helpExtendedKeyFlag (2 bytes) */ - stream_seek_UINT16(s); /* windowManagerKeyFlag (2 bytes) */ + Stream_Seek_UINT16(s); /* helpKeyFlag (2 bytes) */ + Stream_Seek_UINT16(s); /* helpKeyIndexFlag (2 bytes) */ + Stream_Seek_UINT16(s); /* helpExtendedKeyFlag (2 bytes) */ + Stream_Seek_UINT16(s); /* windowManagerKeyFlag (2 bytes) */ return TRUE; } @@ -837,14 +847,16 @@ BOOL rdp_read_window_activation_capability_set(wStream* s, UINT16 length, rdpSet void rdp_write_window_activation_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; + + Stream_EnsureRemainingCapacity(s, 32); header = rdp_capability_set_start(s); - stream_write_UINT16(s, 0); /* helpKeyFlag (2 bytes) */ - stream_write_UINT16(s, 0); /* helpKeyIndexFlag (2 bytes) */ - stream_write_UINT16(s, 0); /* helpExtendedKeyFlag (2 bytes) */ - stream_write_UINT16(s, 0); /* windowManagerKeyFlag (2 bytes) */ + Stream_Write_UINT16(s, 0); /* helpKeyFlag (2 bytes) */ + Stream_Write_UINT16(s, 0); /* helpKeyIndexFlag (2 bytes) */ + Stream_Write_UINT16(s, 0); /* helpExtendedKeyFlag (2 bytes) */ + Stream_Write_UINT16(s, 0); /* windowManagerKeyFlag (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION); } @@ -861,10 +873,10 @@ BOOL rdp_print_window_activation_capability_set(wStream* s, UINT16 length) if (length < 12) return FALSE; - stream_read_UINT16(s, helpKeyFlag); /* helpKeyFlag (2 bytes) */ - stream_read_UINT16(s, helpKeyIndexFlag); /* helpKeyIndexFlag (2 bytes) */ - stream_read_UINT16(s, helpExtendedKeyFlag); /* helpExtendedKeyFlag (2 bytes) */ - stream_read_UINT16(s, windowManagerKeyFlag); /* windowManagerKeyFlag (2 bytes) */ + Stream_Read_UINT16(s, helpKeyFlag); /* helpKeyFlag (2 bytes) */ + Stream_Read_UINT16(s, helpKeyIndexFlag); /* helpKeyIndexFlag (2 bytes) */ + Stream_Read_UINT16(s, helpExtendedKeyFlag); /* helpExtendedKeyFlag (2 bytes) */ + Stream_Read_UINT16(s, windowManagerKeyFlag); /* windowManagerKeyFlag (2 bytes) */ fprintf(stderr, "\thelpKeyFlag: 0x%04X\n", helpKeyFlag); fprintf(stderr, "\thelpKeyIndexFlag: 0x%04X\n", helpKeyIndexFlag); @@ -891,9 +903,9 @@ BOOL rdp_read_pointer_capability_set(wStream* s, UINT16 length, rdpSettings* set if (length < 10) return FALSE; - stream_read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ - stream_read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ - stream_read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */ + Stream_Read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ + Stream_Read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ + Stream_Read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */ if (colorPointerFlag == FALSE) settings->ColorPointerFlag = FALSE; @@ -914,19 +926,21 @@ BOOL rdp_read_pointer_capability_set(wStream* s, UINT16 length, rdpSettings* set void rdp_write_pointer_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT16 colorPointerFlag; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); colorPointerFlag = (settings->ColorPointerFlag) ? 1 : 0; - stream_write_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ - stream_write_UINT16(s, settings->PointerCacheSize); /* colorPointerCacheSize (2 bytes) */ + Stream_Write_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ + Stream_Write_UINT16(s, settings->PointerCacheSize); /* colorPointerCacheSize (2 bytes) */ if (settings->LargePointerFlag) { - stream_write_UINT16(s, settings->PointerCacheSize); /* pointerCacheSize (2 bytes) */ + Stream_Write_UINT16(s, settings->PointerCacheSize); /* pointerCacheSize (2 bytes) */ } rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER); @@ -943,9 +957,9 @@ BOOL rdp_print_pointer_capability_set(wStream* s, UINT16 length) fprintf(stderr, "PointerCapabilitySet (length %d):\n", length); - stream_read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ - stream_read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ - stream_read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */ + Stream_Read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ + Stream_Read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ + Stream_Read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */ fprintf(stderr, "\tcolorPointerFlag: 0x%04X\n", colorPointerFlag); fprintf(stderr, "\tcolorPointerCacheSize: 0x%04X\n", colorPointerCacheSize); @@ -967,8 +981,8 @@ BOOL rdp_read_share_capability_set(wStream* s, UINT16 length, rdpSettings* setti if (length < 8) return FALSE; - stream_seek_UINT16(s); /* nodeId (2 bytes) */ - stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ + Stream_Seek_UINT16(s); /* nodeId (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ return TRUE; } @@ -982,15 +996,17 @@ BOOL rdp_read_share_capability_set(wStream* s, UINT16 length, rdpSettings* setti void rdp_write_share_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT16 nodeId; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); nodeId = (settings->ServerMode) ? 0x03EA : 0; - stream_write_UINT16(s, nodeId); /* nodeId (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + Stream_Write_UINT16(s, nodeId); /* nodeId (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE); } @@ -1005,8 +1021,8 @@ BOOL rdp_print_share_capability_set(wStream* s, UINT16 length) if (length < 8) return FALSE; - stream_read_UINT16(s, nodeId); /* nodeId (2 bytes) */ - stream_read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, nodeId); /* nodeId (2 bytes) */ + Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ fprintf(stderr, "\tnodeId: 0x%04X\n", nodeId); fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets); @@ -1027,8 +1043,8 @@ BOOL rdp_read_color_cache_capability_set(wStream* s, UINT16 length, rdpSettings* if (length < 8) return FALSE; - stream_seek_UINT16(s); /* colorTableCacheSize (2 bytes) */ - stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ + Stream_Seek_UINT16(s); /* colorTableCacheSize (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ return TRUE; } @@ -1042,12 +1058,14 @@ BOOL rdp_read_color_cache_capability_set(wStream* s, UINT16 length, rdpSettings* void rdp_write_color_cache_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; + + Stream_EnsureRemainingCapacity(s, 32); header = rdp_capability_set_start(s); - stream_write_UINT16(s, 6); /* colorTableCacheSize (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + Stream_Write_UINT16(s, 6); /* colorTableCacheSize (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE); } @@ -1062,8 +1080,8 @@ BOOL rdp_print_color_cache_capability_set(wStream* s, UINT16 length) if (length < 8) return FALSE; - stream_read_UINT16(s, colorTableCacheSize); /* colorTableCacheSize (2 bytes) */ - stream_read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, colorTableCacheSize); /* colorTableCacheSize (2 bytes) */ + Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ fprintf(stderr, "\tcolorTableCacheSize: 0x%04X\n", colorTableCacheSize); fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets); @@ -1086,8 +1104,8 @@ BOOL rdp_read_sound_capability_set(wStream* s, UINT16 length, rdpSettings* setti if (length < 8) return FALSE; - stream_read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ - stream_seek_UINT16(s); /* pad2OctetsA (2 bytes) */ + Stream_Read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2OctetsA (2 bytes) */ settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) ? TRUE : FALSE; @@ -1103,15 +1121,17 @@ BOOL rdp_read_sound_capability_set(wStream* s, UINT16 length, rdpSettings* setti void rdp_write_sound_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT16 soundFlags; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); soundFlags = (settings->SoundBeepsEnabled) ? SOUND_BEEPS_FLAG : 0; - stream_write_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2OctetsA (2 bytes) */ + Stream_Write_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2OctetsA (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND); } @@ -1126,8 +1146,8 @@ BOOL rdp_print_sound_capability_set(wStream* s, UINT16 length) if (length < 8) return FALSE; - stream_read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ - stream_read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ + Stream_Read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ + Stream_Read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ fprintf(stderr, "\tsoundFlags: 0x%04X\n", soundFlags); fprintf(stderr, "\tpad2OctetsA: 0x%04X\n", pad2OctetsA); @@ -1150,25 +1170,25 @@ BOOL rdp_read_input_capability_set(wStream* s, UINT16 length, rdpSettings* setti if (length < 88) return FALSE; - stream_read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ - stream_seek_UINT16(s); /* pad2OctetsA (2 bytes) */ + Stream_Read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2OctetsA (2 bytes) */ if (settings->ServerMode) { - stream_read_UINT32(s, settings->KeyboardLayout); /* keyboardLayout (4 bytes) */ - stream_read_UINT32(s, settings->KeyboardType); /* keyboardType (4 bytes) */ - stream_read_UINT32(s, settings->KeyboardSubType); /* keyboardSubType (4 bytes) */ - stream_read_UINT32(s, settings->KeyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ + Stream_Read_UINT32(s, settings->KeyboardLayout); /* keyboardLayout (4 bytes) */ + Stream_Read_UINT32(s, settings->KeyboardType); /* keyboardType (4 bytes) */ + Stream_Read_UINT32(s, settings->KeyboardSubType); /* keyboardSubType (4 bytes) */ + Stream_Read_UINT32(s, settings->KeyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ } else { - stream_seek_UINT32(s); /* keyboardLayout (4 bytes) */ - stream_seek_UINT32(s); /* keyboardType (4 bytes) */ - stream_seek_UINT32(s); /* keyboardSubType (4 bytes) */ - stream_seek_UINT32(s); /* keyboardFunctionKeys (4 bytes) */ + Stream_Seek_UINT32(s); /* keyboardLayout (4 bytes) */ + Stream_Seek_UINT32(s); /* keyboardType (4 bytes) */ + Stream_Seek_UINT32(s); /* keyboardSubType (4 bytes) */ + Stream_Seek_UINT32(s); /* keyboardFunctionKeys (4 bytes) */ } - stream_seek(s, 64); /* imeFileName (64 bytes) */ + Stream_Seek(s, 64); /* imeFileName (64 bytes) */ if (settings->ServerMode != TRUE) { @@ -1198,9 +1218,11 @@ BOOL rdp_read_input_capability_set(wStream* s, UINT16 length, rdpSettings* setti void rdp_write_input_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT16 inputFlags; + Stream_EnsureRemainingCapacity(s, 128); + header = rdp_capability_set_start(s); inputFlags = INPUT_FLAG_SCANCODES | INPUT_FLAG_MOUSEX | INPUT_FLAG_UNICODE; @@ -1211,13 +1233,13 @@ void rdp_write_input_capability_set(wStream* s, rdpSettings* settings) inputFlags |= INPUT_FLAG_FASTPATH_INPUT2; } - stream_write_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2OctetsA (2 bytes) */ - stream_write_UINT32(s, settings->KeyboardLayout); /* keyboardLayout (4 bytes) */ - stream_write_UINT32(s, settings->KeyboardType); /* keyboardType (4 bytes) */ - stream_write_UINT32(s, settings->KeyboardSubType); /* keyboardSubType (4 bytes) */ - stream_write_UINT32(s, settings->KeyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ - stream_write_zero(s, 64); /* imeFileName (64 bytes) */ + Stream_Write_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2OctetsA (2 bytes) */ + Stream_Write_UINT32(s, settings->KeyboardLayout); /* keyboardLayout (4 bytes) */ + Stream_Write_UINT32(s, settings->KeyboardType); /* keyboardType (4 bytes) */ + Stream_Write_UINT32(s, settings->KeyboardSubType); /* keyboardSubType (4 bytes) */ + Stream_Write_UINT32(s, settings->KeyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ + Stream_Zero(s, 64); /* imeFileName (64 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT); } @@ -1236,13 +1258,13 @@ BOOL rdp_print_input_capability_set(wStream* s, UINT16 length) if (length < 88) return FALSE; - stream_read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ - stream_read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ - stream_read_UINT32(s, keyboardLayout); /* keyboardLayout (4 bytes) */ - stream_read_UINT32(s, keyboardType); /* keyboardType (4 bytes) */ - stream_read_UINT32(s, keyboardSubType); /* keyboardSubType (4 bytes) */ - stream_read_UINT32(s, keyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ - stream_seek(s, 64); /* imeFileName (64 bytes) */ + Stream_Read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ + Stream_Read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ + Stream_Read_UINT32(s, keyboardLayout); /* keyboardLayout (4 bytes) */ + Stream_Read_UINT32(s, keyboardType); /* keyboardType (4 bytes) */ + Stream_Read_UINT32(s, keyboardSubType); /* keyboardSubType (4 bytes) */ + Stream_Read_UINT32(s, keyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ + Stream_Seek(s, 64); /* imeFileName (64 bytes) */ fprintf(stderr, "\tinputFlags: 0x%04X\n", inputFlags); fprintf(stderr, "\tpad2OctetsA: 0x%04X\n", pad2OctetsA); @@ -1265,10 +1287,10 @@ BOOL rdp_print_input_capability_set(wStream* s, UINT16 length) BOOL rdp_read_font_capability_set(wStream* s, UINT16 length, rdpSettings* settings) { if (length > 4) - stream_seek_UINT16(s); /* fontSupportFlags (2 bytes) */ + Stream_Seek_UINT16(s); /* fontSupportFlags (2 bytes) */ if (length > 6) - stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ return TRUE; } @@ -1282,12 +1304,14 @@ BOOL rdp_read_font_capability_set(wStream* s, UINT16 length, rdpSettings* settin void rdp_write_font_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; + + Stream_EnsureRemainingCapacity(s, 32); header = rdp_capability_set_start(s); - stream_write_UINT16(s, FONTSUPPORT_FONTLIST); /* fontSupportFlags (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + Stream_Write_UINT16(s, FONTSUPPORT_FONTLIST); /* fontSupportFlags (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT); } @@ -1300,10 +1324,10 @@ BOOL rdp_print_font_capability_set(wStream* s, UINT16 length) fprintf(stderr, "FontCapabilitySet (length %d):\n", length); if (length > 4) - stream_read_UINT16(s, fontSupportFlags); /* fontSupportFlags (2 bytes) */ + Stream_Read_UINT16(s, fontSupportFlags); /* fontSupportFlags (2 bytes) */ if (length > 6) - stream_read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ fprintf(stderr, "\tfontSupportFlags: 0x%04X\n", fontSupportFlags); fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets); @@ -1324,7 +1348,7 @@ BOOL rdp_read_brush_capability_set(wStream* s, UINT16 length, rdpSettings* setti if (length < 8) return FALSE; - stream_seek_UINT32(s); /* brushSupportLevel (4 bytes) */ + Stream_Seek_UINT32(s); /* brushSupportLevel (4 bytes) */ return TRUE; } @@ -1338,11 +1362,13 @@ BOOL rdp_read_brush_capability_set(wStream* s, UINT16 length, rdpSettings* setti void rdp_write_brush_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; + + Stream_EnsureRemainingCapacity(s, 32); header = rdp_capability_set_start(s); - stream_write_UINT32(s, BRUSH_COLOR_FULL); /* brushSupportLevel (4 bytes) */ + Stream_Write_UINT32(s, BRUSH_COLOR_FULL); /* brushSupportLevel (4 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH); } @@ -1356,7 +1382,7 @@ BOOL rdp_print_brush_capability_set(wStream* s, UINT16 length) if (length < 8) return FALSE; - stream_read_UINT32(s, brushSupportLevel); /* brushSupportLevel (4 bytes) */ + Stream_Read_UINT32(s, brushSupportLevel); /* brushSupportLevel (4 bytes) */ fprintf(stderr, "\tbrushSupportLevel: 0x%08X\n", brushSupportLevel); @@ -1370,8 +1396,8 @@ BOOL rdp_print_brush_capability_set(wStream* s, UINT16 length) */ void rdp_read_cache_definition(wStream* s, GLYPH_CACHE_DEFINITION* cache_definition) { - stream_read_UINT16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */ - stream_read_UINT16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */ + Stream_Read_UINT16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */ + Stream_Read_UINT16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */ } /** @@ -1381,8 +1407,8 @@ void rdp_read_cache_definition(wStream* s, GLYPH_CACHE_DEFINITION* cache_definit */ void rdp_write_cache_definition(wStream* s, GLYPH_CACHE_DEFINITION* cache_definition) { - stream_write_UINT16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */ - stream_write_UINT16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */ + Stream_Write_UINT16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */ + Stream_Write_UINT16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */ } /** @@ -1400,10 +1426,10 @@ BOOL rdp_read_glyph_cache_capability_set(wStream* s, UINT16 length, rdpSettings* if (length < 52) return FALSE; - stream_seek(s, 40); /* glyphCache (40 bytes) */ - stream_seek_UINT32(s); /* fragCache (4 bytes) */ - stream_read_UINT16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */ - stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ + Stream_Seek(s, 40); /* glyphCache (40 bytes) */ + Stream_Seek_UINT32(s); /* fragCache (4 bytes) */ + Stream_Read_UINT16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ settings->GlyphSupportLevel = glyphSupportLevel; @@ -1419,7 +1445,9 @@ BOOL rdp_read_glyph_cache_capability_set(wStream* s, UINT16 length, rdpSettings* void rdp_write_glyph_cache_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; + + Stream_EnsureRemainingCapacity(s, 64); header = rdp_capability_set_start(s); @@ -1436,9 +1464,9 @@ void rdp_write_glyph_cache_capability_set(wStream* s, rdpSettings* settings) rdp_write_cache_definition(s, &(settings->GlyphCache[9])); /* glyphCache9 (4 bytes) */ rdp_write_cache_definition(s, settings->FragCache); /* fragCache (4 bytes) */ - stream_write_UINT16(s, settings->GlyphSupportLevel); /* glyphSupportLevel (2 bytes) */ + Stream_Write_UINT16(s, settings->GlyphSupportLevel); /* glyphSupportLevel (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE); } @@ -1468,8 +1496,8 @@ BOOL rdp_print_glyph_cache_capability_set(wStream* s, UINT16 length) rdp_read_cache_definition(s, &glyphCache[9]); /* glyphCache9 (4 bytes) */ rdp_read_cache_definition(s, &fragCache); /* fragCache (4 bytes) */ - stream_read_UINT16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */ - stream_read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */ + Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ fprintf(stderr, "\tglyphCache0: Entries: %d MaximumCellSize: %d\n", glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize); fprintf(stderr, "\tglyphCache1: Entries: %d MaximumCellSize: %d\n", glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize); @@ -1503,9 +1531,9 @@ BOOL rdp_read_offscreen_bitmap_cache_capability_set(wStream* s, UINT16 length, r if (length < 12) return FALSE; - stream_read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ - stream_read_UINT16(s, settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ - stream_read_UINT16(s, settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ + Stream_Read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ + Stream_Read_UINT16(s, settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ + Stream_Read_UINT16(s, settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ if (offscreenSupportLevel & TRUE) settings->OffscreenSupportLevel = TRUE; @@ -1522,17 +1550,19 @@ BOOL rdp_read_offscreen_bitmap_cache_capability_set(wStream* s, UINT16 length, r void rdp_write_offscreen_bitmap_cache_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT32 offscreenSupportLevel = FALSE; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); if (settings->OffscreenSupportLevel) offscreenSupportLevel = TRUE; - stream_write_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ - stream_write_UINT16(s, settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ - stream_write_UINT16(s, settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ + Stream_Write_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ + Stream_Write_UINT16(s, settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ + Stream_Write_UINT16(s, settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE); } @@ -1548,9 +1578,9 @@ BOOL rdp_print_offscreen_bitmap_cache_capability_set(wStream* s, UINT16 length) if (length < 12) return FALSE; - stream_read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ - stream_read_UINT16(s, offscreenCacheSize); /* offscreenCacheSize (2 bytes) */ - stream_read_UINT16(s, offscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ + Stream_Read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ + Stream_Read_UINT16(s, offscreenCacheSize); /* offscreenCacheSize (2 bytes) */ + Stream_Read_UINT16(s, offscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ fprintf(stderr, "\toffscreenSupportLevel: 0x%08X\n", offscreenSupportLevel); fprintf(stderr, "\toffscreenCacheSize: 0x%04X\n", offscreenCacheSize); @@ -1574,9 +1604,9 @@ BOOL rdp_read_bitmap_cache_host_support_capability_set(wStream* s, UINT16 length if (length < 8) return FALSE; - stream_read_BYTE(s, cacheVersion); /* cacheVersion (1 byte) */ - stream_seek_BYTE(s); /* pad1 (1 byte) */ - stream_seek_UINT16(s); /* pad2 (2 bytes) */ + Stream_Read_UINT8(s, cacheVersion); /* cacheVersion (1 byte) */ + Stream_Seek_UINT8(s); /* pad1 (1 byte) */ + Stream_Seek_UINT16(s); /* pad2 (2 bytes) */ if (cacheVersion & BITMAP_CACHE_V2) settings->BitmapCachePersistEnabled = TRUE; @@ -1593,13 +1623,15 @@ BOOL rdp_read_bitmap_cache_host_support_capability_set(wStream* s, UINT16 length void rdp_write_bitmap_cache_host_support_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; + + Stream_EnsureRemainingCapacity(s, 32); header = rdp_capability_set_start(s); - stream_write_BYTE(s, BITMAP_CACHE_V2); /* cacheVersion (1 byte) */ - stream_write_BYTE(s, 0); /* pad1 (1 byte) */ - stream_write_UINT16(s, 0); /* pad2 (2 bytes) */ + Stream_Write_UINT8(s, BITMAP_CACHE_V2); /* cacheVersion (1 byte) */ + Stream_Write_UINT8(s, 0); /* pad1 (1 byte) */ + Stream_Write_UINT16(s, 0); /* pad2 (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT); } @@ -1615,9 +1647,9 @@ BOOL rdp_print_bitmap_cache_host_support_capability_set(wStream* s, UINT16 lengt if (length < 8) return FALSE; - stream_read_BYTE(s, cacheVersion); /* cacheVersion (1 byte) */ - stream_read_BYTE(s, pad1); /* pad1 (1 byte) */ - stream_read_UINT16(s, pad2); /* pad2 (2 bytes) */ + Stream_Read_UINT8(s, cacheVersion); /* cacheVersion (1 byte) */ + Stream_Read_UINT8(s, pad1); /* pad1 (1 byte) */ + Stream_Read_UINT16(s, pad2); /* pad2 (2 bytes) */ fprintf(stderr, "\tcacheVersion: 0x%02X\n", cacheVersion); fprintf(stderr, "\tpad1: 0x%02X\n", pad1); @@ -1635,7 +1667,7 @@ void rdp_read_bitmap_cache_cell_info(wStream* s, BITMAP_CACHE_V2_CELL_INFO* cell * is used to indicate a persistent bitmap cache. */ - stream_read_UINT32(s, info); + Stream_Read_UINT32(s, info); cellInfo->numEntries = (info & 0x7FFFFFFF); cellInfo->persistent = (info & 0x80000000) ? 1 : 0; @@ -1651,7 +1683,7 @@ void rdp_write_bitmap_cache_cell_info(wStream* s, BITMAP_CACHE_V2_CELL_INFO* cel */ info = (cellInfo->numEntries | (cellInfo->persistent << 31)); - stream_write_UINT32(s, info); + Stream_Write_UINT32(s, info); } /** @@ -1667,15 +1699,15 @@ BOOL rdp_read_bitmap_cache_v2_capability_set(wStream* s, UINT16 length, rdpSetti if (length < 40) return FALSE; - stream_seek_UINT16(s); /* cacheFlags (2 bytes) */ - stream_seek_BYTE(s); /* pad2 (1 byte) */ - stream_seek_BYTE(s); /* numCellCaches (1 byte) */ - stream_seek(s, 4); /* bitmapCache0CellInfo (4 bytes) */ - stream_seek(s, 4); /* bitmapCache1CellInfo (4 bytes) */ - stream_seek(s, 4); /* bitmapCache2CellInfo (4 bytes) */ - stream_seek(s, 4); /* bitmapCache3CellInfo (4 bytes) */ - stream_seek(s, 4); /* bitmapCache4CellInfo (4 bytes) */ - stream_seek(s, 12); /* pad3 (12 bytes) */ + Stream_Seek_UINT16(s); /* cacheFlags (2 bytes) */ + Stream_Seek_UINT8(s); /* pad2 (1 byte) */ + Stream_Seek_UINT8(s); /* numCellCaches (1 byte) */ + Stream_Seek(s, 4); /* bitmapCache0CellInfo (4 bytes) */ + Stream_Seek(s, 4); /* bitmapCache1CellInfo (4 bytes) */ + Stream_Seek(s, 4); /* bitmapCache2CellInfo (4 bytes) */ + Stream_Seek(s, 4); /* bitmapCache3CellInfo (4 bytes) */ + Stream_Seek(s, 4); /* bitmapCache4CellInfo (4 bytes) */ + Stream_Seek(s, 12); /* pad3 (12 bytes) */ return TRUE; } @@ -1689,9 +1721,11 @@ BOOL rdp_read_bitmap_cache_v2_capability_set(wStream* s, UINT16 length, rdpSetti void rdp_write_bitmap_cache_v2_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT16 cacheFlags; + Stream_EnsureRemainingCapacity(s, 64); + header = rdp_capability_set_start(s); cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG; @@ -1699,15 +1733,15 @@ void rdp_write_bitmap_cache_v2_capability_set(wStream* s, rdpSettings* settings) if (settings->BitmapCachePersistEnabled) cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG; - stream_write_UINT16(s, cacheFlags); /* cacheFlags (2 bytes) */ - stream_write_BYTE(s, 0); /* pad2 (1 byte) */ - stream_write_BYTE(s, settings->BitmapCacheV2NumCells); /* numCellCaches (1 byte) */ + Stream_Write_UINT16(s, cacheFlags); /* cacheFlags (2 bytes) */ + Stream_Write_UINT8(s, 0); /* pad2 (1 byte) */ + Stream_Write_UINT8(s, settings->BitmapCacheV2NumCells); /* numCellCaches (1 byte) */ rdp_write_bitmap_cache_cell_info(s, &settings->BitmapCacheV2CellInfo[0]); /* bitmapCache0CellInfo (4 bytes) */ rdp_write_bitmap_cache_cell_info(s, &settings->BitmapCacheV2CellInfo[1]); /* bitmapCache1CellInfo (4 bytes) */ rdp_write_bitmap_cache_cell_info(s, &settings->BitmapCacheV2CellInfo[2]); /* bitmapCache2CellInfo (4 bytes) */ rdp_write_bitmap_cache_cell_info(s, &settings->BitmapCacheV2CellInfo[3]); /* bitmapCache3CellInfo (4 bytes) */ rdp_write_bitmap_cache_cell_info(s, &settings->BitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */ - stream_write_zero(s, 12); /* pad3 (12 bytes) */ + Stream_Zero(s, 12); /* pad3 (12 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2); } @@ -1724,15 +1758,15 @@ BOOL rdp_print_bitmap_cache_v2_capability_set(wStream* s, UINT16 length) if (length < 40) return FALSE; - stream_read_UINT16(s, cacheFlags); /* cacheFlags (2 bytes) */ - stream_read_BYTE(s, pad2); /* pad2 (1 byte) */ - stream_read_BYTE(s, numCellCaches); /* numCellCaches (1 byte) */ + Stream_Read_UINT16(s, cacheFlags); /* cacheFlags (2 bytes) */ + Stream_Read_UINT8(s, pad2); /* pad2 (1 byte) */ + Stream_Read_UINT8(s, numCellCaches); /* numCellCaches (1 byte) */ rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[0]); /* bitmapCache0CellInfo (4 bytes) */ rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[1]); /* bitmapCache1CellInfo (4 bytes) */ rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[2]); /* bitmapCache2CellInfo (4 bytes) */ rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[3]); /* bitmapCache3CellInfo (4 bytes) */ rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */ - stream_seek(s, 12); /* pad3 (12 bytes) */ + Stream_Seek(s, 12); /* pad3 (12 bytes) */ fprintf(stderr, "\tcacheFlags: 0x%04X\n", cacheFlags); fprintf(stderr, "\tpad2: 0x%02X\n", pad2); @@ -1762,10 +1796,10 @@ BOOL rdp_read_virtual_channel_capability_set(wStream* s, UINT16 length, rdpSetti if (length < 8) return FALSE; - stream_read_UINT32(s, flags); /* flags (4 bytes) */ + Stream_Read_UINT32(s, flags); /* flags (4 bytes) */ if (length > 8) - stream_read_UINT32(s, VCChunkSize); /* VCChunkSize (4 bytes) */ + Stream_Read_UINT32(s, VCChunkSize); /* VCChunkSize (4 bytes) */ else VCChunkSize = 1600; @@ -1784,15 +1818,17 @@ BOOL rdp_read_virtual_channel_capability_set(wStream* s, UINT16 length, rdpSetti void rdp_write_virtual_channel_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT32 flags; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); flags = VCCAPS_NO_COMPR; - stream_write_UINT32(s, flags); /* flags (4 bytes) */ - stream_write_UINT32(s, settings->VirtualChannelChunkSize); /* VCChunkSize (4 bytes) */ + Stream_Write_UINT32(s, flags); /* flags (4 bytes) */ + Stream_Write_UINT32(s, settings->VirtualChannelChunkSize); /* VCChunkSize (4 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL); } @@ -1807,10 +1843,10 @@ BOOL rdp_print_virtual_channel_capability_set(wStream* s, UINT16 length) if (length < 8) return FALSE; - stream_read_UINT32(s, flags); /* flags (4 bytes) */ + Stream_Read_UINT32(s, flags); /* flags (4 bytes) */ if (length > 8) - stream_read_UINT32(s, VCChunkSize); /* VCChunkSize (4 bytes) */ + Stream_Read_UINT32(s, VCChunkSize); /* VCChunkSize (4 bytes) */ else VCChunkSize = 1600; @@ -1835,9 +1871,9 @@ BOOL rdp_read_draw_nine_grid_cache_capability_set(wStream* s, UINT16 length, rdp if (length < 12) return FALSE; - stream_read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ - stream_read_UINT16(s, settings->DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ - stream_read_UINT16(s, settings->DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ + Stream_Read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ + Stream_Read_UINT16(s, settings->DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ + Stream_Read_UINT16(s, settings->DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ if ((drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED) || (drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED_V2)) @@ -1855,42 +1891,44 @@ BOOL rdp_read_draw_nine_grid_cache_capability_set(wStream* s, UINT16 length, rdp void rdp_write_draw_nine_grid_cache_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT32 drawNineGridSupportLevel; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); drawNineGridSupportLevel = (settings->DrawNineGridEnabled) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT; - stream_write_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ - stream_write_UINT16(s, settings->DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ - stream_write_UINT16(s, settings->DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ + Stream_Write_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ + Stream_Write_UINT16(s, settings->DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ + Stream_Write_UINT16(s, settings->DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE); } void rdp_write_gdiplus_cache_entries(wStream* s, UINT16 gce, UINT16 bce, UINT16 pce, UINT16 ice, UINT16 ace) { - stream_write_UINT16(s, gce); /* gdipGraphicsCacheEntries (2 bytes) */ - stream_write_UINT16(s, bce); /* gdipBrushCacheEntries (2 bytes) */ - stream_write_UINT16(s, pce); /* gdipPenCacheEntries (2 bytes) */ - stream_write_UINT16(s, ice); /* gdipImageCacheEntries (2 bytes) */ - stream_write_UINT16(s, ace); /* gdipImageAttributesCacheEntries (2 bytes) */ + Stream_Write_UINT16(s, gce); /* gdipGraphicsCacheEntries (2 bytes) */ + Stream_Write_UINT16(s, bce); /* gdipBrushCacheEntries (2 bytes) */ + Stream_Write_UINT16(s, pce); /* gdipPenCacheEntries (2 bytes) */ + Stream_Write_UINT16(s, ice); /* gdipImageCacheEntries (2 bytes) */ + Stream_Write_UINT16(s, ace); /* gdipImageAttributesCacheEntries (2 bytes) */ } void rdp_write_gdiplus_cache_chunk_size(wStream* s, UINT16 gccs, UINT16 obccs, UINT16 opccs, UINT16 oiaccs) { - stream_write_UINT16(s, gccs); /* gdipGraphicsCacheChunkSize (2 bytes) */ - stream_write_UINT16(s, obccs); /* gdipObjectBrushCacheChunkSize (2 bytes) */ - stream_write_UINT16(s, opccs); /* gdipObjectPenCacheChunkSize (2 bytes) */ - stream_write_UINT16(s, oiaccs); /* gdipObjectImageAttributesCacheChunkSize (2 bytes) */ + Stream_Write_UINT16(s, gccs); /* gdipGraphicsCacheChunkSize (2 bytes) */ + Stream_Write_UINT16(s, obccs); /* gdipObjectBrushCacheChunkSize (2 bytes) */ + Stream_Write_UINT16(s, opccs); /* gdipObjectPenCacheChunkSize (2 bytes) */ + Stream_Write_UINT16(s, oiaccs); /* gdipObjectImageAttributesCacheChunkSize (2 bytes) */ } void rdp_write_gdiplus_image_cache_properties(wStream* s, UINT16 oiccs, UINT16 oicts, UINT16 oicms) { - stream_write_UINT16(s, oiccs); /* gdipObjectImageCacheChunkSize (2 bytes) */ - stream_write_UINT16(s, oicts); /* gdipObjectImageCacheTotalSize (2 bytes) */ - stream_write_UINT16(s, oicms); /* gdipObjectImageCacheMaxSize (2 bytes) */ + Stream_Write_UINT16(s, oiccs); /* gdipObjectImageCacheChunkSize (2 bytes) */ + Stream_Write_UINT16(s, oicts); /* gdipObjectImageCacheTotalSize (2 bytes) */ + Stream_Write_UINT16(s, oicms); /* gdipObjectImageCacheMaxSize (2 bytes) */ } BOOL rdp_print_draw_nine_grid_cache_capability_set(wStream* s, UINT16 length) @@ -1904,9 +1942,9 @@ BOOL rdp_print_draw_nine_grid_cache_capability_set(wStream* s, UINT16 length) if (length < 12) return FALSE; - stream_read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ - stream_read_UINT16(s, DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ - stream_read_UINT16(s, DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ + Stream_Read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ + Stream_Read_UINT16(s, DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ + Stream_Read_UINT16(s, DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ return TRUE; } @@ -1927,12 +1965,12 @@ BOOL rdp_read_draw_gdiplus_cache_capability_set(wStream* s, UINT16 length, rdpSe if (length < 40) return FALSE; - stream_read_UINT32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ - stream_seek_UINT32(s); /* GdipVersion (4 bytes) */ - stream_read_UINT32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ - stream_seek(s, 10); /* GdipCacheEntries (10 bytes) */ - stream_seek(s, 8); /* GdipCacheChunkSize (8 bytes) */ - stream_seek(s, 6); /* GdipImageCacheProperties (6 bytes) */ + Stream_Read_UINT32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ + Stream_Seek_UINT32(s); /* GdipVersion (4 bytes) */ + Stream_Read_UINT32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ + Stream_Seek(s, 10); /* GdipCacheEntries (10 bytes) */ + Stream_Seek(s, 8); /* GdipCacheChunkSize (8 bytes) */ + Stream_Seek(s, 6); /* GdipImageCacheProperties (6 bytes) */ if (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED) settings->DrawGdiPlusEnabled = TRUE; @@ -1952,18 +1990,20 @@ BOOL rdp_read_draw_gdiplus_cache_capability_set(wStream* s, UINT16 length, rdpSe void rdp_write_draw_gdiplus_cache_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT32 drawGDIPlusSupportLevel; UINT32 drawGdiplusCacheLevel; + Stream_EnsureRemainingCapacity(s, 64); + header = rdp_capability_set_start(s); drawGDIPlusSupportLevel = (settings->DrawGdiPlusEnabled) ? DRAW_GDIPLUS_SUPPORTED : DRAW_GDIPLUS_DEFAULT; drawGdiplusCacheLevel = (settings->DrawGdiPlusEnabled) ? DRAW_GDIPLUS_CACHE_LEVEL_ONE : DRAW_GDIPLUS_CACHE_LEVEL_DEFAULT; - stream_write_UINT32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ - stream_write_UINT32(s, 0); /* GdipVersion (4 bytes) */ - stream_write_UINT32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ + Stream_Write_UINT32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ + Stream_Write_UINT32(s, 0); /* GdipVersion (4 bytes) */ + Stream_Write_UINT32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ rdp_write_gdiplus_cache_entries(s, 10, 5, 5, 10, 2); /* GdipCacheEntries (10 bytes) */ rdp_write_gdiplus_cache_chunk_size(s, 512, 2048, 1024, 64); /* GdipCacheChunkSize (8 bytes) */ rdp_write_gdiplus_image_cache_properties(s, 4096, 256, 128); /* GdipImageCacheProperties (6 bytes) */ @@ -1982,12 +2022,12 @@ BOOL rdp_print_draw_gdiplus_cache_capability_set(wStream* s, UINT16 length) if (length < 40) return FALSE; - stream_read_UINT32(s, drawGdiPlusSupportLevel); /* drawGdiPlusSupportLevel (4 bytes) */ - stream_read_UINT32(s, GdipVersion); /* GdipVersion (4 bytes) */ - stream_read_UINT32(s, drawGdiplusCacheLevel); /* drawGdiPlusCacheLevel (4 bytes) */ - stream_seek(s, 10); /* GdipCacheEntries (10 bytes) */ - stream_seek(s, 8); /* GdipCacheChunkSize (8 bytes) */ - stream_seek(s, 6); /* GdipImageCacheProperties (6 bytes) */ + Stream_Read_UINT32(s, drawGdiPlusSupportLevel); /* drawGdiPlusSupportLevel (4 bytes) */ + Stream_Read_UINT32(s, GdipVersion); /* GdipVersion (4 bytes) */ + Stream_Read_UINT32(s, drawGdiplusCacheLevel); /* drawGdiPlusCacheLevel (4 bytes) */ + Stream_Seek(s, 10); /* GdipCacheEntries (10 bytes) */ + Stream_Seek(s, 8); /* GdipCacheChunkSize (8 bytes) */ + Stream_Seek(s, 6); /* GdipImageCacheProperties (6 bytes) */ return TRUE; } @@ -2007,7 +2047,7 @@ BOOL rdp_read_remote_programs_capability_set(wStream* s, UINT16 length, rdpSetti if (length < 8) return FALSE; - stream_read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ + Stream_Read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ if ((railSupportLevel & RAIL_LEVEL_SUPPORTED) == 0) { @@ -2029,9 +2069,11 @@ BOOL rdp_read_remote_programs_capability_set(wStream* s, UINT16 length, rdpSetti void rdp_write_remote_programs_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT32 railSupportLevel; + Stream_EnsureRemainingCapacity(s, 64); + header = rdp_capability_set_start(s); railSupportLevel = RAIL_LEVEL_SUPPORTED; @@ -2039,7 +2081,7 @@ void rdp_write_remote_programs_capability_set(wStream* s, rdpSettings* settings) if (settings->RemoteAppLanguageBarSupported) railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED; - stream_write_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ + Stream_Write_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL); } @@ -2053,7 +2095,7 @@ BOOL rdp_print_remote_programs_capability_set(wStream* s, UINT16 length) if (length < 8) return FALSE; - stream_read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ + Stream_Read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ fprintf(stderr, "\trailSupportLevel: 0x%08X\n", railSupportLevel); @@ -2073,9 +2115,9 @@ BOOL rdp_read_window_list_capability_set(wStream* s, UINT16 length, rdpSettings* if (length < 11) return FALSE; - stream_seek_UINT32(s); /* wndSupportLevel (4 bytes) */ - stream_seek_BYTE(s); /* numIconCaches (1 byte) */ - stream_seek_UINT16(s); /* numIconCacheEntries (2 bytes) */ + Stream_Seek_UINT32(s); /* wndSupportLevel (4 bytes) */ + Stream_Seek_UINT8(s); /* numIconCaches (1 byte) */ + Stream_Seek_UINT16(s); /* numIconCacheEntries (2 bytes) */ return TRUE; } @@ -2089,16 +2131,18 @@ BOOL rdp_read_window_list_capability_set(wStream* s, UINT16 length, rdpSettings* void rdp_write_window_list_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT32 wndSupportLevel; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); wndSupportLevel = WINDOW_LEVEL_SUPPORTED_EX; - stream_write_UINT32(s, wndSupportLevel); /* wndSupportLevel (4 bytes) */ - stream_write_BYTE(s, settings->RemoteAppNumIconCaches); /* numIconCaches (1 byte) */ - stream_write_UINT16(s, settings->RemoteAppNumIconCacheEntries); /* numIconCacheEntries (2 bytes) */ + Stream_Write_UINT32(s, wndSupportLevel); /* wndSupportLevel (4 bytes) */ + Stream_Write_UINT8(s, settings->RemoteAppNumIconCaches); /* numIconCaches (1 byte) */ + Stream_Write_UINT16(s, settings->RemoteAppNumIconCacheEntries); /* numIconCacheEntries (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW); } @@ -2114,9 +2158,9 @@ BOOL rdp_print_window_list_capability_set(wStream* s, UINT16 length) if (length < 11) return FALSE; - stream_read_UINT32(s, wndSupportLevel); /* wndSupportLevel (4 bytes) */ - stream_read_BYTE(s, numIconCaches); /* numIconCaches (1 byte) */ - stream_read_UINT16(s, numIconCacheEntries); /* numIconCacheEntries (2 bytes) */ + Stream_Read_UINT32(s, wndSupportLevel); /* wndSupportLevel (4 bytes) */ + Stream_Read_UINT8(s, numIconCaches); /* numIconCaches (1 byte) */ + Stream_Read_UINT16(s, numIconCacheEntries); /* numIconCacheEntries (2 bytes) */ fprintf(stderr, "\twndSupportLevel: 0x%08X\n", wndSupportLevel); fprintf(stderr, "\tnumIconCaches: 0x%02X\n", numIconCaches); @@ -2138,7 +2182,7 @@ BOOL rdp_read_desktop_composition_capability_set(wStream* s, UINT16 length, rdpS if (length < 6) return FALSE; - stream_seek_UINT16(s); /* compDeskSupportLevel (2 bytes) */ + Stream_Seek_UINT16(s); /* compDeskSupportLevel (2 bytes) */ return TRUE; } @@ -2152,14 +2196,16 @@ BOOL rdp_read_desktop_composition_capability_set(wStream* s, UINT16 length, rdpS void rdp_write_desktop_composition_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT16 compDeskSupportLevel; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); compDeskSupportLevel = (settings->AllowDesktopComposition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED; - stream_write_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ + Stream_Write_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK); } @@ -2173,7 +2219,7 @@ BOOL rdp_print_desktop_composition_capability_set(wStream* s, UINT16 length) if (length < 6) return FALSE; - stream_read_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ + Stream_Read_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ fprintf(stderr, "\tcompDeskSupportLevel: 0x%04X\n", compDeskSupportLevel); @@ -2191,12 +2237,11 @@ BOOL rdp_print_desktop_composition_capability_set(wStream* s, UINT16 length) BOOL rdp_read_multifragment_update_capability_set(wStream* s, UINT16 length, rdpSettings* settings) { UINT32 multifragMaxRequestSize; + if (length < 8) return FALSE; - stream_read_UINT32(s, multifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ - if (settings->MultifragMaxRequestSize < multifragMaxRequestSize) - settings->MultifragMaxRequestSize = multifragMaxRequestSize; + Stream_Read_UINT32(s, multifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ return TRUE; } @@ -2210,11 +2255,13 @@ BOOL rdp_read_multifragment_update_capability_set(wStream* s, UINT16 length, rdp void rdp_write_multifragment_update_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; + + Stream_EnsureRemainingCapacity(s, 32); header = rdp_capability_set_start(s); - stream_write_UINT32(s, settings->MultifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ + Stream_Write_UINT32(s, settings->MultifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE); } @@ -2228,7 +2275,7 @@ BOOL rdp_print_multifragment_update_capability_set(wStream* s, UINT16 length) if (length < 8) return FALSE; - stream_read_UINT32(s, maxRequestSize); /* maxRequestSize (4 bytes) */ + Stream_Read_UINT32(s, maxRequestSize); /* maxRequestSize (4 bytes) */ fprintf(stderr, "\tmaxRequestSize: 0x%04X\n", maxRequestSize); @@ -2248,7 +2295,7 @@ BOOL rdp_read_large_pointer_capability_set(wStream* s, UINT16 length, rdpSetting if (length < 6) return FALSE; - stream_seek_UINT16(s); /* largePointerSupportFlags (2 bytes) */ + Stream_Seek_UINT16(s); /* largePointerSupportFlags (2 bytes) */ return TRUE; } @@ -2262,14 +2309,16 @@ BOOL rdp_read_large_pointer_capability_set(wStream* s, UINT16 length, rdpSetting void rdp_write_large_pointer_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT16 largePointerSupportFlags; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); largePointerSupportFlags = (settings->LargePointerFlag) ? LARGE_POINTER_FLAG_96x96 : 0; - stream_write_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ + Stream_Write_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER); } @@ -2283,7 +2332,7 @@ BOOL rdp_print_large_pointer_capability_set(wStream* s, UINT16 length) if (length < 6) return FALSE; - stream_read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ + Stream_Read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ fprintf(stderr, "\tlargePointerSupportFlags: 0x%04X\n", largePointerSupportFlags); @@ -2303,8 +2352,8 @@ BOOL rdp_read_surface_commands_capability_set(wStream* s, UINT16 length, rdpSett if (length < 12) return FALSE; - stream_seek_UINT32(s); /* cmdFlags (4 bytes) */ - stream_seek_UINT32(s); /* reserved (4 bytes) */ + Stream_Seek_UINT32(s); /* cmdFlags (4 bytes) */ + Stream_Seek_UINT32(s); /* reserved (4 bytes) */ settings->SurfaceCommandsEnabled = TRUE; @@ -2320,17 +2369,19 @@ BOOL rdp_read_surface_commands_capability_set(wStream* s, UINT16 length, rdpSett void rdp_write_surface_commands_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT32 cmdFlags; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); cmdFlags = SURFCMDS_FRAME_MARKER | SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS; - stream_write_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */ - stream_write_UINT32(s, 0); /* reserved (4 bytes) */ + Stream_Write_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */ + Stream_Write_UINT32(s, 0); /* reserved (4 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS); } @@ -2345,8 +2396,8 @@ BOOL rdp_print_surface_commands_capability_set(wStream* s, UINT16 length) if (length < 12) return FALSE; - stream_read_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */ - stream_read_UINT32(s, reserved); /* reserved (4 bytes) */ + Stream_Read_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */ + Stream_Read_UINT32(s, reserved); /* reserved (4 bytes) */ fprintf(stderr, "\tcmdFlags: 0x%08X\n", cmdFlags); fprintf(stderr, "\treserved: 0x%08X\n", reserved); @@ -2358,7 +2409,7 @@ void rdp_read_bitmap_codec_guid(wStream* s, GUID* guid) { BYTE g[16]; - stream_read(s, g, 16); + Stream_Read(s, g, 16); guid->Data1 = (g[3] << 24) | (g[2] << 16) | (g[1] << 8) | g[0]; guid->Data2 = (g[5] << 8) | g[4]; @@ -2394,7 +2445,7 @@ void rdp_write_bitmap_codec_guid(wStream* s, GUID* guid) g[14] = guid->Data4[6]; g[15] = guid->Data4[7]; - stream_write(s, g, 16); + Stream_Write(s, g, 16); } void rdp_print_bitmap_codec_guid(GUID* guid) @@ -2442,7 +2493,7 @@ BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, rdpSetting if (length < 5) return FALSE; - stream_read_BYTE(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ + Stream_Read_UINT8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ remainingLength = length - 5; if (settings->ServerMode) @@ -2463,25 +2514,25 @@ BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, rdpSetting { if (UuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX, &rpc_status)) { - stream_read_BYTE(s, settings->RemoteFxCodecId); + Stream_Read_UINT8(s, settings->RemoteFxCodecId); settings->RemoteFxCodec = TRUE; } else if (UuidEqual(&codecGuid, &CODEC_GUID_NSCODEC, &rpc_status)) { - stream_read_BYTE(s, settings->NSCodecId); + Stream_Read_UINT8(s, settings->NSCodecId); settings->NSCodec = TRUE; } else { - stream_seek_BYTE(s); /* codecID (1 byte) */ + Stream_Seek_UINT8(s); /* codecID (1 byte) */ } } else { - stream_seek_BYTE(s); /* codecID (1 byte) */ + Stream_Seek_UINT8(s); /* codecID (1 byte) */ } - stream_read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ + Stream_Read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ remainingLength -= 19; if (remainingLength < codecPropertiesLength) @@ -2491,9 +2542,9 @@ BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, rdpSetting { if (UuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX, &rpc_status)) { - stream_seek_UINT32(s); /* length */ - stream_read_UINT32(s, settings->RemoteFxCaptureFlags); /* captureFlags */ - stream_rewind(s, 8); + Stream_Seek_UINT32(s); /* length */ + Stream_Read_UINT32(s, settings->RemoteFxCaptureFlags); /* captureFlags */ + Stream_Rewind(s, 8); if (settings->RemoteFxCaptureFlags & CARDP_CAPS_CAPTURE_NON_CAC) { @@ -2502,7 +2553,7 @@ BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, rdpSetting } } - stream_seek(s, codecPropertiesLength); /* codecProperties */ + Stream_Seek(s, codecPropertiesLength); /* codecProperties */ remainingLength -= codecPropertiesLength; bitmapCodecCount--; @@ -2521,44 +2572,46 @@ void rdp_write_rfx_client_capability_container(wStream* s, rdpSettings* settings UINT32 captureFlags; BYTE codecMode; + Stream_EnsureRemainingCapacity(s, 64); + captureFlags = settings->RemoteFxOnly ? 0 : CARDP_CAPS_CAPTURE_NON_CAC; codecMode = settings->RemoteFxCodecMode; - stream_write_UINT16(s, 49); /* codecPropertiesLength */ + Stream_Write_UINT16(s, 49); /* codecPropertiesLength */ /* TS_RFX_CLNT_CAPS_CONTAINER */ - stream_write_UINT32(s, 49); /* length */ - stream_write_UINT32(s, captureFlags); /* captureFlags */ - stream_write_UINT32(s, 37); /* capsLength */ + Stream_Write_UINT32(s, 49); /* length */ + Stream_Write_UINT32(s, captureFlags); /* captureFlags */ + Stream_Write_UINT32(s, 37); /* capsLength */ /* TS_RFX_CAPS */ - stream_write_UINT16(s, CBY_CAPS); /* blockType */ - stream_write_UINT32(s, 8); /* blockLen */ - stream_write_UINT16(s, 1); /* numCapsets */ + Stream_Write_UINT16(s, CBY_CAPS); /* blockType */ + Stream_Write_UINT32(s, 8); /* blockLen */ + Stream_Write_UINT16(s, 1); /* numCapsets */ /* TS_RFX_CAPSET */ - stream_write_UINT16(s, CBY_CAPSET); /* blockType */ - stream_write_UINT32(s, 29); /* blockLen */ - stream_write_BYTE(s, 0x01); /* codecId (MUST be set to 0x01) */ - stream_write_UINT16(s, CLY_CAPSET); /* capsetType */ - stream_write_UINT16(s, 2); /* numIcaps */ - stream_write_UINT16(s, 8); /* icapLen */ + Stream_Write_UINT16(s, CBY_CAPSET); /* blockType */ + Stream_Write_UINT32(s, 29); /* blockLen */ + Stream_Write_UINT8(s, 0x01); /* codecId (MUST be set to 0x01) */ + Stream_Write_UINT16(s, CLY_CAPSET); /* capsetType */ + Stream_Write_UINT16(s, 2); /* numIcaps */ + Stream_Write_UINT16(s, 8); /* icapLen */ /* TS_RFX_ICAP (RLGR1) */ - stream_write_UINT16(s, CLW_VERSION_1_0); /* version */ - stream_write_UINT16(s, CT_TILE_64x64); /* tileSize */ - stream_write_BYTE(s, codecMode); /* flags */ - stream_write_BYTE(s, CLW_COL_CONV_ICT); /* colConvBits */ - stream_write_BYTE(s, CLW_XFORM_DWT_53_A); /* transformBits */ - stream_write_BYTE(s, CLW_ENTROPY_RLGR1); /* entropyBits */ + Stream_Write_UINT16(s, CLW_VERSION_1_0); /* version */ + Stream_Write_UINT16(s, CT_TILE_64x64); /* tileSize */ + Stream_Write_UINT8(s, codecMode); /* flags */ + Stream_Write_UINT8(s, CLW_COL_CONV_ICT); /* colConvBits */ + Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A); /* transformBits */ + Stream_Write_UINT8(s, CLW_ENTROPY_RLGR1); /* entropyBits */ /* TS_RFX_ICAP (RLGR3) */ - stream_write_UINT16(s, CLW_VERSION_1_0); /* version */ - stream_write_UINT16(s, CT_TILE_64x64); /* tileSize */ - stream_write_BYTE(s, codecMode); /* flags */ - stream_write_BYTE(s, CLW_COL_CONV_ICT); /* colConvBits */ - stream_write_BYTE(s, CLW_XFORM_DWT_53_A); /* transformBits */ - stream_write_BYTE(s, CLW_ENTROPY_RLGR3); /* entropyBits */ + Stream_Write_UINT16(s, CLW_VERSION_1_0); /* version */ + Stream_Write_UINT16(s, CT_TILE_64x64); /* tileSize */ + Stream_Write_UINT8(s, codecMode); /* flags */ + Stream_Write_UINT8(s, CLW_COL_CONV_ICT); /* colConvBits */ + Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A); /* transformBits */ + Stream_Write_UINT8(s, CLW_ENTROPY_RLGR3); /* entropyBits */ } /** @@ -2568,18 +2621,22 @@ void rdp_write_rfx_client_capability_container(wStream* s, rdpSettings* settings */ void rdp_write_nsc_client_capability_container(wStream* s, rdpSettings* settings) { - stream_write_UINT16(s, 3); /* codecPropertiesLength */ + Stream_EnsureRemainingCapacity(s, 8); + + Stream_Write_UINT16(s, 3); /* codecPropertiesLength */ /* TS_NSCODEC_CAPABILITYSET */ - stream_write_BYTE(s, 1); /* fAllowDynamicFidelity */ - stream_write_BYTE(s, 1); /* fAllowSubsampling */ - stream_write_BYTE(s, 3); /* colorLossLevel */ + Stream_Write_UINT8(s, 1); /* fAllowDynamicFidelity */ + Stream_Write_UINT8(s, 1); /* fAllowSubsampling */ + Stream_Write_UINT8(s, 3); /* colorLossLevel */ } void rdp_write_jpeg_client_capability_container(wStream* s, rdpSettings* settings) { - stream_write_UINT16(s, 1); /* codecPropertiesLength */ - stream_write_BYTE(s, settings->JpegQuality); + Stream_EnsureRemainingCapacity(s, 8); + + Stream_Write_UINT16(s, 1); /* codecPropertiesLength */ + Stream_Write_UINT8(s, settings->JpegQuality); } /** @@ -2589,14 +2646,18 @@ void rdp_write_jpeg_client_capability_container(wStream* s, rdpSettings* setting */ void rdp_write_rfx_server_capability_container(wStream* s, rdpSettings* settings) { - stream_write_UINT16(s, 4); /* codecPropertiesLength */ - stream_write_UINT32(s, 0); /* reserved */ + Stream_EnsureRemainingCapacity(s, 8); + + Stream_Write_UINT16(s, 4); /* codecPropertiesLength */ + Stream_Write_UINT32(s, 0); /* reserved */ } void rdp_write_jpeg_server_capability_container(wStream* s, rdpSettings* settings) { - stream_write_UINT16(s, 1); /* codecPropertiesLength */ - stream_write_BYTE(s, 75); + Stream_EnsureRemainingCapacity(s, 8); + + Stream_Write_UINT16(s, 1); /* codecPropertiesLength */ + Stream_Write_UINT8(s, 75); } /** @@ -2606,8 +2667,10 @@ void rdp_write_jpeg_server_capability_container(wStream* s, rdpSettings* setting */ void rdp_write_nsc_server_capability_container(wStream* s, rdpSettings* settings) { - stream_write_UINT16(s, 4); /* codecPropertiesLength */ - stream_write_UINT32(s, 0); /* reserved */ + Stream_EnsureRemainingCapacity(s, 8); + + Stream_Write_UINT16(s, 4); /* codecPropertiesLength */ + Stream_Write_UINT32(s, 0); /* reserved */ } /** @@ -2619,9 +2682,11 @@ void rdp_write_nsc_server_capability_container(wStream* s, rdpSettings* settings void rdp_write_bitmap_codecs_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; BYTE bitmapCodecCount; + Stream_EnsureRemainingCapacity(s, 64); + header = rdp_capability_set_start(s); bitmapCodecCount = 0; @@ -2638,7 +2703,7 @@ void rdp_write_bitmap_codecs_capability_set(wStream* s, rdpSettings* settings) if (settings->RemoteFxImageCodec) bitmapCodecCount++; - stream_write_BYTE(s, bitmapCodecCount); + Stream_Write_UINT8(s, bitmapCodecCount); if (settings->RemoteFxCodec) { @@ -2646,12 +2711,12 @@ void rdp_write_bitmap_codecs_capability_set(wStream* s, rdpSettings* settings) if (settings->ServerMode) { - stream_write_BYTE(s, 0); /* codecID is defined by the client */ + Stream_Write_UINT8(s, 0); /* codecID is defined by the client */ rdp_write_rfx_server_capability_container(s, settings); } else { - stream_write_BYTE(s, RDP_CODEC_ID_REMOTEFX); /* codecID */ + Stream_Write_UINT8(s, RDP_CODEC_ID_REMOTEFX); /* codecID */ rdp_write_rfx_client_capability_container(s, settings); } } @@ -2662,12 +2727,12 @@ void rdp_write_bitmap_codecs_capability_set(wStream* s, rdpSettings* settings) if (settings->ServerMode) { - stream_write_BYTE(s, 0); /* codecID is defined by the client */ + Stream_Write_UINT8(s, 0); /* codecID is defined by the client */ rdp_write_nsc_server_capability_container(s, settings); } else { - stream_write_BYTE(s, RDP_CODEC_ID_NSCODEC); /* codecID */ + Stream_Write_UINT8(s, RDP_CODEC_ID_NSCODEC); /* codecID */ rdp_write_nsc_client_capability_container(s, settings); } } @@ -2678,12 +2743,12 @@ void rdp_write_bitmap_codecs_capability_set(wStream* s, rdpSettings* settings) if (settings->ServerMode) { - stream_write_BYTE(s, 0); /* codecID is defined by the client */ + Stream_Write_UINT8(s, 0); /* codecID is defined by the client */ rdp_write_jpeg_server_capability_container(s, settings); } else { - stream_write_BYTE(s, RDP_CODEC_ID_JPEG); /* codecID */ + Stream_Write_UINT8(s, RDP_CODEC_ID_JPEG); /* codecID */ rdp_write_jpeg_client_capability_container(s, settings); } } @@ -2694,12 +2759,12 @@ void rdp_write_bitmap_codecs_capability_set(wStream* s, rdpSettings* settings) if (settings->ServerMode) { - stream_write_BYTE(s, 0); /* codecID is defined by the client */ + Stream_Write_UINT8(s, 0); /* codecID is defined by the client */ rdp_write_rfx_server_capability_container(s, settings); } else { - stream_write_BYTE(s, RDP_CODEC_ID_IMAGE_REMOTEFX); /* codecID */ + Stream_Write_UINT8(s, RDP_CODEC_ID_IMAGE_REMOTEFX); /* codecID */ rdp_write_rfx_client_capability_container(s, settings); } } @@ -2720,7 +2785,7 @@ BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) if (length < 5) return FALSE; - stream_read_BYTE(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ + Stream_Read_UINT8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ remainingLength = length - 5; fprintf(stderr, "\tbitmapCodecCount: %d\n", bitmapCodecCount); @@ -2731,7 +2796,7 @@ BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) return FALSE; rdp_read_bitmap_codec_guid(s, &codecGuid); /* codecGuid (16 bytes) */ - stream_read_BYTE(s, codecId); /* codecId (1 byte) */ + Stream_Read_UINT8(s, codecId); /* codecId (1 byte) */ fprintf(stderr, "\tcodecGuid: 0x"); rdp_print_bitmap_codec_guid(&codecGuid); @@ -2739,7 +2804,7 @@ BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) fprintf(stderr, "\tcodecId: %d\n", codecId); - stream_read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ + Stream_Read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ fprintf(stderr, "\tcodecPropertiesLength: %d\n", codecPropertiesLength); remainingLength -= 19; @@ -2747,7 +2812,7 @@ BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) if (remainingLength < codecPropertiesLength) return FALSE; - stream_seek(s, codecPropertiesLength); /* codecProperties */ + Stream_Seek(s, codecPropertiesLength); /* codecProperties */ remainingLength -= codecPropertiesLength; bitmapCodecCount--; @@ -2770,11 +2835,11 @@ BOOL rdp_read_frame_acknowledge_capability_set(wStream* s, UINT16 length, rdpSet if (settings->ServerMode) { - stream_read_UINT32(s, settings->FrameAcknowledge); /* (4 bytes) */ + Stream_Read_UINT32(s, settings->FrameAcknowledge); /* (4 bytes) */ } else { - stream_seek_UINT32(s); /* (4 bytes) */ + Stream_Seek_UINT32(s); /* (4 bytes) */ } return TRUE; } @@ -2787,13 +2852,15 @@ BOOL rdp_read_frame_acknowledge_capability_set(wStream* s, UINT16 length, rdpSet void rdp_write_frame_acknowledge_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; UINT32 frame_acknowledge; + Stream_EnsureRemainingCapacity(s, 32); + header = rdp_capability_set_start(s); frame_acknowledge = settings->FrameAcknowledge; - stream_write_UINT32(s, frame_acknowledge); /* (4 bytes) */ + Stream_Write_UINT32(s, frame_acknowledge); /* (4 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE); } @@ -2807,7 +2874,7 @@ BOOL rdp_print_frame_acknowledge_capability_set(wStream* s, UINT16 length) if (length < 8) return FALSE; - stream_read_UINT32(s, frameAcknowledge); /* frameAcknowledge (4 bytes) */ + Stream_Read_UINT32(s, frameAcknowledge); /* frameAcknowledge (4 bytes) */ fprintf(stderr, "\tframeAcknowledge: 0x%08X\n", frameAcknowledge); @@ -2821,17 +2888,20 @@ BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wStream* s, UINT16 length, if (length < 5) return FALSE; - stream_read_BYTE(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */ + Stream_Read_UINT8(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */ return TRUE; } void rdp_write_bitmap_cache_v3_codec_id_capability_set(wStream* s, rdpSettings* settings) { - BYTE* header; + int header; + + Stream_EnsureRemainingCapacity(s, 32); header = rdp_capability_set_start(s); - stream_write_BYTE(s, settings->BitmapCacheV3CodecId); + Stream_Write_UINT8(s, settings->BitmapCacheV3CodecId); + rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID); } @@ -2844,7 +2914,7 @@ BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wStream* s, UINT16 length if (length < 5) return FALSE; - stream_read_BYTE(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */ + Stream_Read_UINT8(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */ fprintf(stderr, "\tbitmapCacheV3CodecId: 0x%02X\n", bitmapCacheV3CodecId); @@ -2859,7 +2929,7 @@ BOOL rdp_print_capability_sets(wStream* s, UINT16 numberCapabilities, BOOL recei while (numberCapabilities > 0) { - stream_get_mark(s, bm); + Stream_GetPointer(s, bm); rdp_read_capability_set_header(s, &length, &type); @@ -2867,7 +2937,7 @@ BOOL rdp_print_capability_sets(wStream* s, UINT16 numberCapabilities, BOOL recei em = bm + length; - if (stream_get_left(s) < length - 4) + if (Stream_GetRemainingLength(s) < length - 4) { fprintf(stderr, "error processing stream\n"); return FALSE; @@ -3031,7 +3101,7 @@ BOOL rdp_print_capability_sets(wStream* s, UINT16 numberCapabilities, BOOL recei type, (int) (s->pointer - bm), (int) (em - bm)); } - stream_set_mark(s, em); + Stream_SetPointer(s, em); numberCapabilities--; } @@ -3046,19 +3116,19 @@ BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCa UINT16 length; BYTE *bm, *em; - stream_get_mark(s, mark); + Stream_GetPointer(s, mark); count = numberCapabilities; while (numberCapabilities > 0) { - stream_get_mark(s, bm); + Stream_GetPointer(s, bm); rdp_read_capability_set_header(s, &length, &type); settings->ReceivedCapabilities[type] = TRUE; em = bm + length; - if (stream_get_left(s) < length - 4) + if (Stream_GetRemainingLength(s) < length - 4) { fprintf(stderr, "error processing stream\n"); return FALSE; @@ -3222,16 +3292,16 @@ BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCa type, (int) (s->pointer - bm), (int) (em - bm)); } - stream_set_mark(s, em); + Stream_SetPointer(s, em); numberCapabilities--; } #ifdef WITH_DEBUG_CAPABILITIES - stream_get_mark(s, em); - stream_set_mark(s, mark); + Stream_GetPointer(s, em); + Stream_SetPointer(s, mark); numberCapabilities = count; rdp_print_capability_sets(s, numberCapabilities, TRUE); - stream_set_mark(s, em); + Stream_SetPointer(s, em); #endif return TRUE; @@ -3302,18 +3372,18 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) return FALSE; } - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ - stream_read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ - stream_read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + Stream_Read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ + Stream_Read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ + Stream_Read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ - if (!stream_skip(s, lengthSourceDescriptor) || stream_get_left(s) < 4) /* sourceDescriptor */ + if (!Stream_SafeSeek(s, lengthSourceDescriptor) || Stream_GetRemainingLength(s) < 4) /* sourceDescriptor */ return FALSE; - stream_read_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ - stream_seek(s, 2); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ + Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ /* capabilitySets */ if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities)) @@ -3329,20 +3399,22 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) void rdp_write_demand_active(wStream* s, rdpSettings* settings) { - BYTE *bm, *em, *lm; + int bm, em, lm; UINT16 numberCapabilities; UINT16 lengthCombinedCapabilities; - stream_write_UINT32(s, settings->ShareId); /* shareId (4 bytes) */ - stream_write_UINT16(s, 4); /* lengthSourceDescriptor (2 bytes) */ + Stream_EnsureRemainingCapacity(s, 64); - stream_get_mark(s, lm); - stream_seek_UINT16(s); /* lengthCombinedCapabilities (2 bytes) */ - stream_write(s, "RDP", 4); /* sourceDescriptor */ + Stream_Write_UINT32(s, settings->ShareId); /* shareId (4 bytes) */ + Stream_Write_UINT16(s, 4); /* lengthSourceDescriptor (2 bytes) */ - stream_get_mark(s, bm); - stream_seek_UINT16(s); /* numberCapabilities (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + lm = Stream_GetPosition(s); + Stream_Seek_UINT16(s); /* lengthCombinedCapabilities (2 bytes) */ + Stream_Write(s, "RDP", 4); /* sourceDescriptor */ + + bm = Stream_GetPosition(s); + Stream_Seek_UINT16(s); /* numberCapabilities (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ numberCapabilities = 14; rdp_write_general_capability_set(s, settings); @@ -3366,38 +3438,44 @@ void rdp_write_demand_active(wStream* s, rdpSettings* settings) rdp_write_bitmap_cache_host_support_capability_set(s, settings); } - stream_get_mark(s, em); + em = Stream_GetPosition(s); - stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */ + Stream_SetPosition(s, lm); /* go back to lengthCombinedCapabilities */ lengthCombinedCapabilities = (em - bm); - stream_write_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + Stream_Write_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ - stream_set_mark(s, bm); /* go back to numberCapabilities */ - stream_write_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ + Stream_SetPosition(s, bm); /* go back to numberCapabilities */ + Stream_Write_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ #ifdef WITH_DEBUG_CAPABILITIES - stream_seek_UINT16(s); + Stream_Seek_UINT16(s); rdp_print_capability_sets(s, numberCapabilities, FALSE); - stream_set_mark(s, bm); - stream_seek_UINT16(s); + Stream_SetPosition(s, bm); + Stream_Seek_UINT16(s); #endif - stream_set_mark(s, em); + Stream_SetPosition(s, em); - stream_write_UINT32(s, 0); /* sessionId */ + Stream_Write_UINT32(s, 0); /* sessionId */ } BOOL rdp_send_demand_active(rdpRdp* rdp) { wStream* s; + BOOL status; - s = rdp_pdu_init(rdp); + s = Stream_New(NULL, 4096); + rdp_init_stream_pdu(rdp, s); rdp->settings->ShareId = 0x10000 + rdp->mcs->user_id; rdp_write_demand_active(s, rdp->settings); - return rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->user_id); + status = rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->user_id); + + Stream_Free(s, TRUE); + + return status; } BOOL rdp_recv_confirm_active(rdpRdp* rdp, wStream* s) @@ -3421,44 +3499,44 @@ BOOL rdp_recv_confirm_active(rdpRdp* rdp, wStream* s) if (pduType != PDU_TYPE_CONFIRM_ACTIVE) return FALSE; - if (stream_get_left(s) < 10) + if (Stream_GetRemainingLength(s) < 10) return FALSE; - stream_seek_UINT32(s); /* shareId (4 bytes) */ - stream_seek_UINT16(s); /* originatorId (2 bytes) */ - stream_read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ - stream_read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + Stream_Seek_UINT32(s); /* shareId (4 bytes) */ + Stream_Seek_UINT16(s); /* originatorId (2 bytes) */ + Stream_Read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ + Stream_Read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ - if (stream_get_left(s) < lengthSourceDescriptor + 4) + if (Stream_GetRemainingLength(s) < lengthSourceDescriptor + 4) return FALSE; - stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */ - stream_read_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ - stream_seek(s, 2); /* pad2Octets (2 bytes) */ + Stream_Seek(s, lengthSourceDescriptor); /* sourceDescriptor */ + Stream_Read_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ + Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ return rdp_read_capability_sets(s, rdp->settings, numberCapabilities); } void rdp_write_confirm_active(wStream* s, rdpSettings* settings) { - BYTE *bm, *em, *lm; + int bm, em, lm; UINT16 numberCapabilities; UINT16 lengthSourceDescriptor; UINT16 lengthCombinedCapabilities; lengthSourceDescriptor = sizeof(SOURCE_DESCRIPTOR); - stream_write_UINT32(s, settings->ShareId); /* shareId (4 bytes) */ - stream_write_UINT16(s, 0x03EA); /* originatorId (2 bytes) */ - stream_write_UINT16(s, lengthSourceDescriptor);/* lengthSourceDescriptor (2 bytes) */ + Stream_Write_UINT32(s, settings->ShareId); /* shareId (4 bytes) */ + Stream_Write_UINT16(s, 0x03EA); /* originatorId (2 bytes) */ + Stream_Write_UINT16(s, lengthSourceDescriptor);/* lengthSourceDescriptor (2 bytes) */ - stream_get_mark(s, lm); - stream_seek_UINT16(s); /* lengthCombinedCapabilities (2 bytes) */ - stream_write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor); /* sourceDescriptor */ + lm = Stream_GetPosition(s); + Stream_Seek_UINT16(s); /* lengthCombinedCapabilities (2 bytes) */ + Stream_Write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor); /* sourceDescriptor */ - stream_get_mark(s, bm); - stream_seek_UINT16(s); /* numberCapabilities (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + bm = Stream_GetPosition(s); + Stream_Seek_UINT16(s); /* numberCapabilities (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ /* Capability Sets */ numberCapabilities = 15; @@ -3551,32 +3629,38 @@ void rdp_write_confirm_active(wStream* s, rdpSettings* settings) } } - stream_get_mark(s, em); + em = Stream_GetPosition(s); - stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */ + Stream_SetPosition(s, lm); /* go back to lengthCombinedCapabilities */ lengthCombinedCapabilities = (em - bm); - stream_write_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + Stream_Write_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ - stream_set_mark(s, bm); /* go back to numberCapabilities */ - stream_write_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ + Stream_SetPosition(s, bm); /* go back to numberCapabilities */ + Stream_Write_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ #ifdef WITH_DEBUG_CAPABILITIES - stream_seek_UINT16(s); + Stream_Seek_UINT16(s); rdp_print_capability_sets(s, numberCapabilities, FALSE); - stream_set_mark(s, bm); - stream_seek_UINT16(s); + Stream_SetPosition(s, bm); + Stream_Seek_UINT16(s); #endif - stream_set_mark(s, em); + Stream_SetPosition(s, em); } BOOL rdp_send_confirm_active(rdpRdp* rdp) { wStream* s; + BOOL status; - s = rdp_pdu_init(rdp); + s = Stream_New(NULL, 4096); + rdp_init_stream_pdu(rdp, s); rdp_write_confirm_active(s, rdp->settings); - return rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id); + status = rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id); + + Stream_Free(s, TRUE); + + return status; } diff --git a/libfreerdp/core/certificate.c b/libfreerdp/core/certificate.c index d97ba11a2..6a28ab3b2 100644 --- a/libfreerdp/core/certificate.c +++ b/libfreerdp/core/certificate.c @@ -160,110 +160,115 @@ BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info) int exponent_length; int error = 0; - s = stream_new(0); - stream_attach(s, cert->data, cert->length); + s = Stream_New(cert->data, cert->length); info->Modulus = 0; - if(!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */ + if (!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */ goto error1; error++; - if(!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */ + if (!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */ goto error1; error++; - if(!ber_read_contextual_tag(s, 0, &length, TRUE)) /* Explicit Contextual Tag [0] */ + if (!ber_read_contextual_tag(s, 0, &length, TRUE)) /* Explicit Contextual Tag [0] */ goto error1; error++; - if(!ber_read_integer(s, &version)) /* version (INTEGER) */ + if (!ber_read_integer(s, &version)) /* version (INTEGER) */ goto error1; error++; version++; /* serialNumber */ - if(!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */ + if (!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */ goto error1; error++; /* signature */ - if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* AlgorithmIdentifier (SEQUENCE) */ + if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */ goto error1; error++; /* issuer */ - if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Name (SEQUENCE) */ + if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */ goto error1; error++; /* validity */ - if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Validity (SEQUENCE) */ + if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Validity (SEQUENCE) */ goto error1; error++; /* subject */ - if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Name (SEQUENCE) */ + if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */ goto error1; error++; /* subjectPublicKeyInfo */ - if(!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */ + if (!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */ goto error1; error++; /* subjectPublicKeyInfo::AlgorithmIdentifier */ - if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* AlgorithmIdentifier (SEQUENCE) */ + if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */ goto error1; error++; /* subjectPublicKeyInfo::subjectPublicKey */ - if(!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */ + if (!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */ goto error1; error++; /* RSAPublicKey (SEQUENCE) */ - if(!ber_read_sequence_tag(s, &length)) /* SEQUENCE */ + if (!ber_read_sequence_tag(s, &length)) /* SEQUENCE */ goto error1; error++; - if(!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */ + if (!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */ goto error1; error++; /* skip zero padding, if any */ do { - if(stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) goto error1; - stream_peek_BYTE(s, padding); + + Stream_Peek_UINT8(s, padding); if (padding == 0) { - if(!stream_skip(s, 1)) + if (!Stream_SafeSeek(s, 1)) goto error1; + modulus_length--; } } while (padding == 0); + error++; - if(stream_get_left(s) < modulus_length) + if (Stream_GetRemainingLength(s) < modulus_length) goto error1; + info->ModulusLength = modulus_length; info->Modulus = (BYTE*) malloc(info->ModulusLength); - stream_read(s, info->Modulus, info->ModulusLength); + Stream_Read(s, info->Modulus, info->ModulusLength); error++; - if(!ber_read_integer_length(s, &exponent_length)) /* publicExponent (INTEGER) */ + if (!ber_read_integer_length(s, &exponent_length)) /* publicExponent (INTEGER) */ goto error2; + error++; - if(stream_get_left(s) < exponent_length || exponent_length > 4) + + if (Stream_GetRemainingLength(s) < exponent_length || exponent_length > 4) goto error2; - stream_read(s, &info->exponent[4 - exponent_length], exponent_length); + + Stream_Read(s, &info->exponent[4 - exponent_length], exponent_length); crypto_reverse(info->Modulus, info->ModulusLength); crypto_reverse(info->exponent, 4); - stream_detach(s); - stream_free(s); + Stream_Free(s, FALSE); return TRUE; error2: @@ -271,8 +276,7 @@ error2: info->Modulus = 0; error1: fprintf(stderr, "error reading when reading certificate: part=%s error=%d\n", certificate_read_errors[error], error); - stream_detach(s); - stream_free(s); + Stream_Free(s, FALSE); return FALSE; } @@ -325,9 +329,9 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w UINT32 datalen; UINT32 modlen; - if(stream_get_left(s) < 20) + if (Stream_GetRemainingLength(s) < 20) return FALSE; - stream_read(s, magic, 4); + Stream_Read(s, magic, 4); if (memcmp(magic, "RSA1", 4) != 0) { @@ -335,19 +339,19 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w return FALSE; } - stream_read_UINT32(s, keylen); - stream_read_UINT32(s, bitlen); - stream_read_UINT32(s, datalen); - stream_read(s, certificate->cert_info.exponent, 4); + Stream_Read_UINT32(s, keylen); + Stream_Read_UINT32(s, bitlen); + Stream_Read_UINT32(s, datalen); + Stream_Read(s, certificate->cert_info.exponent, 4); modlen = keylen - 8; - if(stream_get_left(s) < modlen + 8) // count padding + if (Stream_GetRemainingLength(s) < modlen + 8) // count padding return FALSE; certificate->cert_info.ModulusLength = modlen; certificate->cert_info.Modulus = malloc(certificate->cert_info.ModulusLength); - stream_read(s, certificate->cert_info.Modulus, certificate->cert_info.ModulusLength); + Stream_Read(s, certificate->cert_info.Modulus, certificate->cert_info.ModulusLength); /* 8 bytes of zero padding */ - stream_seek(s, 8); + Stream_Seek(s, 8); return TRUE; } @@ -365,7 +369,7 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific crypto_md5_update(md5ctx, sigdata, sigdatalen); crypto_md5_final(md5ctx, md5hash); - stream_read(s, encsig, siglen); + Stream_Read(s, encsig, siglen); /* Last 8 bytes shall be all zero. */ @@ -425,13 +429,13 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate BYTE* sigdata; int sigdatalen; - if(stream_get_left(s) < 12) + if (Stream_GetRemainingLength(s) < 12) return FALSE; /* -4, because we need to include dwVersion */ - sigdata = stream_get_tail(s) - 4; - stream_read_UINT32(s, dwSigAlgId); - stream_read_UINT32(s, dwKeyAlgId); + sigdata = Stream_Pointer(s) - 4; + Stream_Read_UINT32(s, dwSigAlgId); + Stream_Read_UINT32(s, dwKeyAlgId); if (!(dwSigAlgId == SIGNATURE_ALG_RSA && dwKeyAlgId == KEY_EXCHANGE_ALG_RSA)) { @@ -439,7 +443,7 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate return FALSE; } - stream_read_UINT16(s, wPublicKeyBlobType); + Stream_Read_UINT16(s, wPublicKeyBlobType); if (wPublicKeyBlobType != BB_RSA_KEY_BLOB) { @@ -447,8 +451,8 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate return FALSE; } - stream_read_UINT16(s, wPublicKeyBlobLen); - if(stream_get_left(s) < wPublicKeyBlobLen) + Stream_Read_UINT16(s, wPublicKeyBlobLen); + if (Stream_GetRemainingLength(s) < wPublicKeyBlobLen) return FALSE; if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen)) @@ -457,11 +461,11 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate return FALSE; } - if(stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - sigdatalen = stream_get_tail(s) - sigdata; - stream_read_UINT16(s, wSignatureBlobType); + sigdatalen = Stream_Pointer(s) - sigdata; + Stream_Read_UINT16(s, wSignatureBlobType); if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB) { @@ -469,8 +473,8 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate return FALSE; } - stream_read_UINT16(s, wSignatureBlobLen); - if(stream_get_left(s) < wSignatureBlobLen) + Stream_Read_UINT16(s, wSignatureBlobLen); + if (Stream_GetRemainingLength(s) < wSignatureBlobLen) return FALSE; if (wSignatureBlobLen != 72) @@ -503,24 +507,26 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, DEBUG_CERTIFICATE("Server X.509 Certificate Chain"); - if(stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, numCertBlobs); /* numCertBlobs */ + Stream_Read_UINT32(s, numCertBlobs); /* numCertBlobs */ certificate->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs); for (i = 0; i < (int) numCertBlobs; i++) { - if(stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, certLength); - if(stream_get_left(s) < certLength) + + Stream_Read_UINT32(s, certLength); + + if (Stream_GetRemainingLength(s) < certLength) return FALSE; DEBUG_CERTIFICATE("\nX.509 Certificate #%d, length:%d", i + 1, certLength); certificate->x509_cert_chain->array[i].data = (BYTE*) malloc(certLength); - stream_read(s, certificate->x509_cert_chain->array[i].data, certLength); + Stream_Read(s, certificate->x509_cert_chain->array[i].data, certLength); certificate->x509_cert_chain->array[i].length = certLength; if (numCertBlobs - i == 2) @@ -571,10 +577,9 @@ int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serve if (length < 4) return -1; - s = stream_new(0); - stream_attach(s, server_cert, length); + s = Stream_New(server_cert, length); - stream_read_UINT32(s, dwVersion); /* dwVersion (4 bytes) */ + Stream_Read_UINT32(s, dwVersion); /* dwVersion (4 bytes) */ switch (dwVersion & CERT_CHAIN_VERSION_MASK) { @@ -592,7 +597,7 @@ int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serve break; } - free(s); + Stream_Free(s, FALSE); return status; } diff --git a/libfreerdp/core/channel.c b/libfreerdp/core/channel.c index 45d11c8d9..e9b14c27f 100644 --- a/libfreerdp/core/channel.c +++ b/libfreerdp/core/channel.c @@ -78,10 +78,10 @@ BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channel_id, BYTE* data, int size) flags |= CHANNEL_FLAG_SHOW_PROTOCOL; } - stream_write_UINT32(s, size); - stream_write_UINT32(s, flags); - stream_check_size(s, chunk_size); - stream_write(s, data, chunk_size); + Stream_Write_UINT32(s, size); + Stream_Write_UINT32(s, flags); + Stream_EnsureCapacity(s, chunk_size); + Stream_Write(s, data, chunk_size); rdp_send(rdp, s, channel_id); @@ -99,15 +99,15 @@ BOOL freerdp_channel_process(freerdp* instance, wStream* s, UINT16 channel_id) UINT32 flags; int chunk_length; - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, length); - stream_read_UINT32(s, flags); - chunk_length = stream_get_left(s); + Stream_Read_UINT32(s, length); + Stream_Read_UINT32(s, flags); + chunk_length = Stream_GetRemainingLength(s); IFCALL(instance->ReceiveChannelData, instance, - channel_id, stream_get_tail(s), chunk_length, flags, length); + channel_id, Stream_Pointer(s), chunk_length, flags, length); return TRUE; } @@ -118,13 +118,15 @@ BOOL freerdp_channel_peer_process(freerdp_peer* client, wStream* s, UINT16 chann UINT32 flags; int chunk_length; - if(stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, length); - stream_read_UINT32(s, flags); - chunk_length = stream_get_left(s); + + Stream_Read_UINT32(s, length); + Stream_Read_UINT32(s, flags); + chunk_length = Stream_GetRemainingLength(s); IFCALL(client->ReceiveChannelData, client, - channel_id, stream_get_tail(s), chunk_length, flags, length); + channel_id, Stream_Pointer(s), chunk_length, flags, length); + return TRUE; } diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index dabba597f..2ce41eb11 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -135,6 +135,9 @@ BOOL rdp_client_connect(rdpRdp* rdp) nego_set_cookie_max_length(rdp->nego, settings->CookieMaxLength); + if (settings->LoadBalanceInfo) + nego_set_routing_token(rdp->nego, settings->LoadBalanceInfo, settings->LoadBalanceInfoLength); + if (!nego_connect(rdp->nego)) { fprintf(stderr, "Error: protocol security negotiation or connection failure\n"); @@ -267,7 +270,7 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) } /* encrypt client random */ - memset(crypt_client_random, 0, sizeof(crypt_client_random)); + ZeroMemory(crypt_client_random, sizeof(crypt_client_random)); crypto_nonce(client_random, sizeof(client_random)); key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength; mod = rdp->settings->RdpServerCertificate->cert_info.Modulus; @@ -276,20 +279,23 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) /* send crypt client random to server */ length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8; - s = transport_send_stream_init(rdp->mcs->transport, length); + s = Stream_New(NULL, length); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, SEC_EXCHANGE_PKT); length = key_len + 8; - stream_write_UINT32(s, length); - stream_write(s, crypt_client_random, length); + Stream_Write_UINT32(s, length); + Stream_Write(s, crypt_client_random, length); + Stream_SealLength(s); if (transport_write(rdp->mcs->transport, s) < 0) { return FALSE; } + Stream_Free(s, TRUE); + /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(client_random, rdp)) { @@ -297,6 +303,7 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) } rdp->do_crypt = TRUE; + if (rdp->settings->SaltedChecksum) rdp->do_secure_checksum = TRUE; @@ -346,10 +353,10 @@ static BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) return FALSE; } - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, rand_len); - if(stream_get_left(s) < rand_len + 8) /* include 8 bytes of padding */ + Stream_Read_UINT32(s, rand_len); + if(Stream_GetRemainingLength(s) < rand_len + 8) /* include 8 bytes of padding */ return FALSE; key_len = rdp->settings->RdpServerRsaKey->ModulusLength; @@ -361,9 +368,9 @@ static BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) } memset(crypt_client_random, 0, sizeof(crypt_client_random)); - stream_read(s, crypt_client_random, rand_len); + Stream_Read(s, crypt_client_random, rand_len); /* 8 zero bytes of padding */ - stream_seek(s, 8); + Stream_Seek(s, 8); mod = rdp->settings->RdpServerRsaKey->Modulus; priv_exp = rdp->settings->RdpServerRsaKey->PrivateExponent; crypto_rsa_private_decrypt(crypt_client_random, rand_len - 8, key_len, mod, priv_exp, client_random); @@ -525,14 +532,14 @@ BOOL rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s) width = rdp->settings->DesktopWidth; height = rdp->settings->DesktopHeight; - stream_get_mark(s, mark); + Stream_GetPointer(s, mark); if (!rdp_recv_demand_active(rdp, s)) { UINT16 channelId; - stream_set_mark(s, mark); + Stream_SetPointer(s, mark); rdp_recv_get_active_header(rdp, s, &channelId); - /* Was stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); + /* Was Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH); * but the headers aren't always that length, * so that could result in a bad offset. */ diff --git a/libfreerdp/core/errinfo.h b/libfreerdp/core/errinfo.h index aab6ff340..54c1ee7d6 100644 --- a/libfreerdp/core/errinfo.h +++ b/libfreerdp/core/errinfo.h @@ -22,106 +22,6 @@ #include <freerdp/freerdp.h> -/* Protocol-independent codes */ -#define ERRINFO_RPC_INITIATED_DISCONNECT 0x00000001 -#define ERRINFO_RPC_INITIATED_LOGOFF 0x00000002 -#define ERRINFO_IDLE_TIMEOUT 0x00000003 -#define ERRINFO_LOGON_TIMEOUT 0x00000004 -#define ERRINFO_DISCONNECTED_BY_OTHER_CONNECTION 0x00000005 -#define ERRINFO_OUT_OF_MEMORY 0x00000006 -#define ERRINFO_SERVER_DENIED_CONNECTION 0x00000007 -#define ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES 0x00000009 -#define ERRINFO_SERVER_FRESH_CREDENTIALS_REQUIRED 0x0000000A -#define ERRINFO_RPC_INITIATED_DISCONNECT_BY_USER 0x0000000B -#define ERRINFO_LOGOFF_BY_USER 0x0000000C - -/* Protocol-independent licensing codes */ -#define ERRINFO_LICENSE_INTERNAL 0x00000100 -#define ERRINFO_LICENSE_NO_LICENSE_SERVER 0x00000101 -#define ERRINFO_LICENSE_NO_LICENSE 0x00000102 -#define ERRINFO_LICENSE_BAD_CLIENT_MSG 0x00000103 -#define ERRINFO_LICENSE_HWID_DOESNT_MATCH_LICENSE 0x00000104 -#define ERRINFO_LICENSE_BAD_CLIENT_LICENSE 0x00000105 -#define ERRINFO_LICENSE_CANT_FINISH_PROTOCOL 0x00000106 -#define ERRINFO_LICENSE_CLIENT_ENDED_PROTOCOL 0x00000107 -#define ERRINFO_LICENSE_BAD_CLIENT_ENCRYPTION 0x00000108 -#define ERRINFO_LICENSE_CANT_UPGRADE_LICENSE 0x00000109 -#define ERRINFO_LICENSE_NO_REMOTE_CONNECTIONS 0x0000010A - -/* RDP specific codes */ -#define ERRINFO_UNKNOWN_DATA_PDU_TYPE 0x000010C9 -#define ERRINFO_UNKNOWN_PDU_TYPE 0x000010CA -#define ERRINFO_DATA_PDU_SEQUENCE 0x000010CB -#define ERRINFO_CONTROL_PDU_SEQUENCE 0x000010CD -#define ERRINFO_INVALID_CONTROL_PDU_ACTION 0x000010CE -#define ERRINFO_INVALID_INPUT_PDU_TYPE 0x000010CF -#define ERRINFO_INVALID_INPUT_PDU_MOUSE 0x000010D0 -#define ERRINFO_INVALID_REFRESH_RECT_PDU 0x000010D1 -#define ERRINFO_CREATE_USER_DATA_FAILED 0x000010D2 -#define ERRINFO_CONNECT_FAILED 0x000010D3 -#define ERRINFO_CONFIRM_ACTIVE_HAS_WRONG_SHAREID 0x000010D4 -#define ERRINFO_CONFIRM_ACTIVE_HAS_WRONG_ORIGINATOR 0x000010D5 -#define ERRINFO_PERSISTENT_KEY_PDU_BAD_LENGTH 0x000010DA -#define ERRINFO_PERSISTENT_KEY_PDU_ILLEGAL_FIRST 0x000010DB -#define ERRINFO_PERSISTENT_KEY_PDU_TOO_MANY_TOTAL_KEYS 0x000010DC -#define ERRINFO_PERSISTENT_KEY_PDU_TOO_MANY_CACHE_KEYS 0x000010DD -#define ERRINFO_INPUT_PDU_BAD_LENGTH 0x000010DE -#define ERRINFO_BITMAP_CACHE_ERROR_PDU_BAD_LENGTH 0x000010DF -#define ERRINFO_SECURITY_DATA_TOO_SHORT 0x000010E0 -#define ERRINFO_VCHANNEL_DATA_TOO_SHORT 0x000010E1 -#define ERRINFO_SHARE_DATA_TOO_SHORT 0x000010E2 -#define ERRINFO_BAD_SUPPRESS_OUTPUT_PDU 0x000010E3 -#define ERRINFO_CONFIRM_ACTIVE_PDU_TOO_SHORT 0x000010E5 -#define ERRINFO_CAPABILITY_SET_TOO_SMALL 0x000010E7 -#define ERRINFO_CAPABILITY_SET_TOO_LARGE 0x000010E8 -#define ERRINFO_NO_CURSOR_CACHE 0x000010E9 -#define ERRINFO_BAD_CAPABILITIES 0x000010EA -#define ERRINFO_VIRTUAL_CHANNEL_DECOMPRESSION 0x000010EC -#define ERRINFO_INVALID_VC_COMPRESSION_TYPE 0x000010ED -#define ERRINFO_INVALID_CHANNEL_ID 0x000010EF -#define ERRINFO_VCHANNELS_TOO_MANY 0x000010F0 -#define ERRINFO_REMOTEAPP_NOT_ENABLED 0x000010F3 -#define ERRINFO_CACHE_CAP_NOT_SET 0x000010F4 -#define ERRINFO_BITMAP_CACHE_ERROR_PDU_BAD_LENGTH2 0x000010F5 -#define ERRINFO_OFFSCREEN_CACHE_ERROR_PDU_BAD_LENGTH 0x000010F6 -#define ERRINFO_DRAWNINEGRID_CACHE_ERROR_PDU_BAD_LENGTH 0x000010F7 -#define ERRINFO_GDIPLUS_PDU_BAD_LENGTH 0x000010F8 -#define ERRINFO_SECURITY_DATA_TOO_SHORT2 0x00001111 -#define ERRINFO_SECURITY_DATA_TOO_SHORT3 0x00001112 -#define ERRINFO_SECURITY_DATA_TOO_SHORT4 0x00001113 -#define ERRINFO_SECURITY_DATA_TOO_SHORT5 0x00001114 -#define ERRINFO_SECURITY_DATA_TOO_SHORT6 0x00001115 -#define ERRINFO_SECURITY_DATA_TOO_SHORT7 0x00001116 -#define ERRINFO_SECURITY_DATA_TOO_SHORT8 0x00001117 -#define ERRINFO_SECURITY_DATA_TOO_SHORT9 0x00001118 -#define ERRINFO_SECURITY_DATA_TOO_SHORT10 0x00001119 -#define ERRINFO_SECURITY_DATA_TOO_SHORT11 0x0000111A -#define ERRINFO_SECURITY_DATA_TOO_SHORT12 0x0000111B -#define ERRINFO_SECURITY_DATA_TOO_SHORT13 0x0000111C -#define ERRINFO_SECURITY_DATA_TOO_SHORT14 0x0000111D -#define ERRINFO_SECURITY_DATA_TOO_SHORT15 0x0000111E -#define ERRINFO_SECURITY_DATA_TOO_SHORT16 0x0000111F -#define ERRINFO_SECURITY_DATA_TOO_SHORT17 0x00001120 -#define ERRINFO_SECURITY_DATA_TOO_SHORT18 0x00001121 -#define ERRINFO_SECURITY_DATA_TOO_SHORT19 0x00001122 -#define ERRINFO_SECURITY_DATA_TOO_SHORT20 0x00001123 -#define ERRINFO_SECURITY_DATA_TOO_SHORT21 0x00001124 -#define ERRINFO_SECURITY_DATA_TOO_SHORT22 0x00001125 -#define ERRINFO_SECURITY_DATA_TOO_SHORT23 0x00001126 -#define ERRINFO_BAD_MONITOR_DATA 0x00001129 -#define ERRINFO_VC_DECOMPRESSED_REASSEMBLE_FAILED 0x0000112A -#define ERRINFO_VC_DATA_TOO_LONG 0x0000112B -#define ERRINFO_GRAPHICS_MODE_NOT_SUPPORTED 0x0000112D -#define ERRINFO_GRAPHICS_SUBSYSTEM_RESET_FAILED 0x0000112E -#define ERRINFO_UPDATE_SESSION_KEY_FAILED 0x00001191 -#define ERRINFO_DECRYPT_FAILED 0x00001192 -#define ERRINFO_ENCRYPT_FAILED 0x00001193 -#define ERRINFO_ENCRYPTION_PACKAGE_MISMATCH 0x00001194 -#define ERRINFO_DECRYPT_FAILED2 0x00001195 - -#define ERRINFO_SUCCESS 0x00000000 -#define ERRINFO_NONE 0xFFFFFFFF - struct _ERRINFO { UINT32 code; diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 56d06a983..b8569fc61 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -26,10 +26,10 @@ #include <string.h> #include <winpr/crt.h> +#include <winpr/stream.h> #include <freerdp/api.h> #include <freerdp/crypto/per.h> -#include <winpr/stream.h> #include "orders.h" #include "update.h" @@ -76,9 +76,9 @@ UINT16 fastpath_header_length(wStream* s) { BYTE length1; - stream_seek_BYTE(s); - stream_read_BYTE(s, length1); - stream_rewind(s, 2); + Stream_Seek_UINT8(s); + Stream_Read_UINT8(s, length1); + Stream_Rewind(s, 2); return ((length1 & 0x80) != 0 ? 3 : 2); } @@ -94,9 +94,9 @@ UINT16 fastpath_read_header(rdpFastPath* fastpath, wStream* s) BYTE header; UINT16 length; - stream_read_BYTE(s, header); + Stream_Read_UINT8(s, header); - if (fastpath != NULL) + if (fastpath) { fastpath->encryptionFlags = (header & 0xC0) >> 6; fastpath->numberEvents = (header & 0x3C) >> 2; @@ -111,7 +111,7 @@ static INLINE void fastpath_read_update_header(wStream* s, BYTE* updateCode, BYT { BYTE updateHeader; - stream_read_BYTE(s, updateHeader); + Stream_Read_UINT8(s, updateHeader); *updateCode = updateHeader & 0x0F; *fragmentation = (updateHeader >> 4) & 0x03; *compression = (updateHeader >> 6) & 0x03; @@ -124,16 +124,16 @@ static INLINE void fastpath_write_update_header(wStream* s, BYTE updateCode, BYT updateHeader |= updateCode & 0x0F; updateHeader |= (fragmentation & 0x03) << 4; updateHeader |= (compression & 0x03) << 6; - stream_write_BYTE(s, updateHeader); + Stream_Write_UINT8(s, updateHeader); } BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, wStream* s, UINT16 *length) { BYTE header; - stream_read_BYTE(s, header); + Stream_Read_UINT8(s, header); - if (fastpath != NULL) + if (fastpath) { fastpath->encryptionFlags = (header & 0xC0) >> 6; fastpath->numberEvents = (header & 0x3C) >> 2; @@ -142,7 +142,7 @@ BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, wStream* s, UINT16 *length) if (!per_read_length(s, length)) return FALSE; - *length = *length - stream_get_length(s); + *length = *length - Stream_GetPosition(s); return TRUE; } @@ -151,12 +151,13 @@ static BOOL fastpath_recv_orders(rdpFastPath* fastpath, wStream* s) rdpUpdate* update = fastpath->rdp->update; UINT16 numberOrders; - stream_read_UINT16(s, numberOrders); /* numberOrders (2 bytes) */ + Stream_Read_UINT16(s, numberOrders); /* numberOrders (2 bytes) */ while (numberOrders > 0) { if (!update_recv_order(update, s)) return FALSE; + numberOrders--; } @@ -169,20 +170,21 @@ static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s) rdpUpdate* update = fastpath->rdp->update; rdpContext* context = update->context; - if(stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, updateType); /* updateType (2 bytes) */ + + Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */ switch (updateType) { case UPDATE_TYPE_BITMAP: - if(!update_read_bitmap(update, s, &update->bitmap_update)) + if (!update_read_bitmap(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)) + if (!update_read_palette(update, s, &update->palette_update)) return FALSE; IFCALL(update->Palette, context, &update->palette_update); break; @@ -194,7 +196,7 @@ static BOOL fastpath_recv_update_synchronize(rdpFastPath* fastpath, wStream* s) { /* server 2008 can send invalid synchronize packet with missing padding, so don't return FALSE even if the packet is invalid */ - stream_skip(s, 2); /* size (2 bytes), MUST be set to zero */ + Stream_SafeSeek(s, 2); /* size (2 bytes), MUST be set to zero */ return TRUE; } @@ -242,6 +244,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s case FASTPATH_UPDATETYPE_PTR_DEFAULT: update->pointer->pointer_system.type = SYSPTR_DEFAULT; IFCALL(pointer->PointerSystem, context, &pointer->pointer_system); + break; case FASTPATH_UPDATETYPE_PTR_POSITION: @@ -276,96 +279,181 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s return status; } +const char* fastpath_get_fragmentation_string(BYTE fragmentation) +{ + if (fragmentation == FASTPATH_FRAGMENT_SINGLE) + return "FASTPATH_FRAGMENT_SINGLE"; + else if (fragmentation == FASTPATH_FRAGMENT_LAST) + return "FASTPATH_FRAGMENT_LAST"; + else if (fragmentation == FASTPATH_FRAGMENT_FIRST) + return "FASTPATH_FRAGMENT_FIRST"; + else if (fragmentation == FASTPATH_FRAGMENT_NEXT) + return "FASTPATH_FRAGMENT_NEXT"; + + return "FASTPATH_FRAGMENT_UNKNOWN"; +} + static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) { int status; UINT16 size; + UINT32 roff; + UINT32 rlen; + rdpRdp* rdp; int next_pos; + BYTE* buffer; + wStream* cs; UINT32 totalSize; BYTE updateCode; BYTE fragmentation; BYTE compression; BYTE compressionFlags; - wStream* update_stream; - wStream* comp_stream; - rdpRdp* rdp; - UINT32 roff; - UINT32 rlen; + rdpTransport* transport; status = 0; rdp = fastpath->rdp; + transport = fastpath->rdp->transport; fastpath_read_update_header(s, &updateCode, &fragmentation, &compression); if (compression == FASTPATH_OUTPUT_COMPRESSION_USED) - stream_read_BYTE(s, compressionFlags); + Stream_Read_UINT8(s, compressionFlags); else compressionFlags = 0; - stream_read_UINT16(s, size); + Stream_Read_UINT16(s, size); - if (stream_get_left(s) < size) + if (Stream_GetRemainingLength(s) < size) return -1; - next_pos = stream_get_pos(s) + size; - comp_stream = s; + cs = s; + next_pos = Stream_GetPosition(s) + size; if (compressionFlags & PACKET_COMPRESSED) { - if (decompress_rdp(rdp->mppc_dec, s->pointer, size, compressionFlags, &roff, &rlen)) + if (decompress_rdp(rdp->mppc_dec, Stream_Pointer(s), size, compressionFlags, &roff, &rlen)) { - comp_stream = stream_new(0); - comp_stream->buffer = rdp->mppc_dec->history_buf + roff; - comp_stream->pointer = comp_stream->buffer; - comp_stream->capacity = rlen; - size = comp_stream->capacity; + size = rlen; + buffer = rdp->mppc_dec->history_buf + roff; + + cs = StreamPool_Take(transport->ReceivePool, size); + + Stream_SetPosition(cs, 0); + Stream_Write(cs, buffer, size); + Stream_SealLength(cs); + Stream_SetPosition(cs, 0); } else { fprintf(stderr, "decompress_rdp() failed\n"); - stream_seek(s, size); + Stream_Seek(s, size); } } - update_stream = NULL; if (fragmentation == FASTPATH_FRAGMENT_SINGLE) { - totalSize = size; - update_stream = comp_stream; - } - else - { - if (fragmentation == FASTPATH_FRAGMENT_FIRST) - stream_set_pos(fastpath->updateData, 0); - - stream_check_size(fastpath->updateData, size); - stream_copy(fastpath->updateData, comp_stream, size); - if (stream_get_length(fastpath->updateData) > rdp->settings->MultifragMaxRequestSize) + if (fastpath->fragmentation != -1) { - fprintf(stderr, "fastpath PDU is bigger than MultifragMaxRequestSize\n"); + fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_SINGLE\n"); return -1; } - if (fragmentation == FASTPATH_FRAGMENT_LAST) - { - update_stream = fastpath->updateData; - totalSize = stream_get_length(update_stream); - stream_set_pos(update_stream, 0); - } - } - - if (update_stream) - { - status = fastpath_recv_update(fastpath, updateCode, totalSize, update_stream); + totalSize = size; + status = fastpath_recv_update(fastpath, updateCode, totalSize, cs); if (status < 0) return -1; } + else + { + if (fragmentation == FASTPATH_FRAGMENT_FIRST) + { + if (fastpath->fragmentation != -1) + { + fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_FIRST\n"); + return -1; + } - stream_set_pos(s, next_pos); + fastpath->fragmentation = FASTPATH_FRAGMENT_FIRST; - if (comp_stream != s) - free(comp_stream); + totalSize = size; + + if (totalSize > transport->settings->MultifragMaxRequestSize) + { + fprintf(stderr, "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n", + totalSize, transport->settings->MultifragMaxRequestSize); + return -1; + } + + fastpath->updateData = StreamPool_Take(transport->ReceivePool, size); + Stream_SetPosition(fastpath->updateData, 0); + + Stream_Copy(fastpath->updateData, cs, size); + } + else if (fragmentation == FASTPATH_FRAGMENT_NEXT) + { + if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) && + (fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT)) + { + fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_NEXT\n"); + return -1; + } + + fastpath->fragmentation = FASTPATH_FRAGMENT_NEXT; + + totalSize = Stream_GetPosition(fastpath->updateData) + size; + + if (totalSize > transport->settings->MultifragMaxRequestSize) + { + fprintf(stderr, "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n", + totalSize, transport->settings->MultifragMaxRequestSize); + return -1; + } + + Stream_EnsureCapacity(fastpath->updateData, totalSize); + + Stream_Copy(fastpath->updateData, cs, size); + } + else if (fragmentation == FASTPATH_FRAGMENT_LAST) + { + if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) && + (fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT)) + { + fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_LAST\n"); + return -1; + } + + fastpath->fragmentation = -1; + + totalSize = Stream_GetPosition(fastpath->updateData) + size; + + if (totalSize > transport->settings->MultifragMaxRequestSize) + { + fprintf(stderr, "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n", + totalSize, transport->settings->MultifragMaxRequestSize); + return -1; + } + + Stream_EnsureCapacity(fastpath->updateData, totalSize); + + Stream_Copy(fastpath->updateData, cs, 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) + return -1; + } + } + + Stream_SetPosition(s, next_pos); + + if (cs != s) + Stream_Release(cs); return status; } @@ -377,7 +465,7 @@ int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s) IFCALL(update->BeginPaint, update->context); - while (stream_get_left(s) >= 3) + while (Stream_GetRemainingLength(s) >= 3) { if (fastpath_recv_update_data(fastpath, s) < 0) return -1; @@ -392,10 +480,10 @@ static BOOL fastpath_read_input_event_header(wStream* s, BYTE* eventFlags, BYTE* { BYTE eventHeader; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, eventHeader); /* eventHeader (1 byte) */ + Stream_Read_UINT8(s, eventHeader); /* eventHeader (1 byte) */ *eventFlags = (eventHeader & 0x1F); *eventCode = (eventHeader >> 5); @@ -408,12 +496,13 @@ static BOOL fastpath_recv_input_event_scancode(rdpFastPath* fastpath, wStream* s UINT16 flags; UINT16 code; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, code); /* keyCode (1 byte) */ + Stream_Read_UINT8(s, code); /* keyCode (1 byte) */ flags = 0; + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) flags |= KBD_FLAGS_RELEASE; else @@ -433,12 +522,12 @@ static BOOL fastpath_recv_input_event_mouse(rdpFastPath* fastpath, wStream* s, B UINT16 xPos; UINT16 yPos; - if (stream_get_left(s) < 6) + 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) */ + 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); @@ -451,12 +540,12 @@ static BOOL fastpath_recv_input_event_mousex(rdpFastPath* fastpath, wStream* s, UINT16 xPos; UINT16 yPos; - if (stream_get_left(s) < 6) + 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) */ + 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); @@ -475,12 +564,13 @@ static BOOL fastpath_recv_input_event_unicode(rdpFastPath* fastpath, wStream* s, UINT16 unicodeCode; UINT16 flags; - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, unicodeCode); /* unicodeCode (2 bytes) */ + Stream_Read_UINT16(s, unicodeCode); /* unicodeCode (2 bytes) */ flags = 0; + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) flags |= KBD_FLAGS_RELEASE; else @@ -545,10 +635,10 @@ int fastpath_recv_inputs(rdpFastPath* fastpath, wStream* s) * as one additional byte here. */ - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return -1; - stream_read_BYTE(s, fastpath->numberEvents); /* eventHeader (1 byte) */ + Stream_Read_UINT8(s, fastpath->numberEvents); /* eventHeader (1 byte) */ } for (i = 0; i < fastpath->numberEvents; i++) @@ -564,17 +654,43 @@ static UINT32 fastpath_get_sec_bytes(rdpRdp* rdp) { UINT32 sec_bytes; + sec_bytes = 0; + if (rdp->do_crypt) { sec_bytes = 8; + if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) sec_bytes += 4; } - else - sec_bytes = 0; + return sec_bytes; } +wStream* fastpath_input_pdu_init_header(rdpFastPath* fastpath) +{ + rdpRdp *rdp; + wStream* s; + + rdp = fastpath->rdp; + + s = transport_send_stream_init(rdp->transport, 256); + + Stream_Seek(s, 3); /* fpInputHeader, length1 and length2 */ + + if (rdp->do_crypt) + { + rdp->sec_flags |= SEC_ENCRYPT; + + if (rdp->do_secure_checksum) + rdp->sec_flags |= SEC_SECURE_CHECKSUM; + } + + Stream_Seek(s, fastpath_get_sec_bytes(rdp)); + + return s; +} + wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE eventCode) { rdpRdp *rdp; @@ -582,28 +698,23 @@ wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE ev rdp = fastpath->rdp; - s = transport_send_stream_init(rdp->transport, 256); - stream_seek(s, 3); /* fpInputHeader, length1 and length2 */ - if (rdp->do_crypt) { - rdp->sec_flags |= SEC_ENCRYPT; - if (rdp->do_secure_checksum) - rdp->sec_flags |= SEC_SECURE_CHECKSUM; - } - stream_seek(s, fastpath_get_sec_bytes(rdp)); - stream_write_BYTE(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */ + s = fastpath_input_pdu_init_header(fastpath); + Stream_Write_UINT8(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */ + return s; } -BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s) +BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNumEvents) { - rdpRdp *rdp; + rdpRdp* rdp; UINT16 length; BYTE eventHeader; int sec_bytes; rdp = fastpath->rdp; - length = stream_get_length(s); + length = Stream_GetPosition(s); + if (length >= (2 << 14)) { fprintf(stderr, "Maximum FastPath PDU length is 32767\n"); @@ -612,52 +723,79 @@ BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s) eventHeader = FASTPATH_INPUT_ACTION_FASTPATH; eventHeader |= (1 << 2); /* numberEvents */ + 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_set_pos(s, 0); - stream_write_BYTE(s, eventHeader); + Stream_SetPosition(s, 0); + Stream_Write_UINT8(s, eventHeader); sec_bytes = fastpath_get_sec_bytes(fastpath->rdp); + /* - * We always encode length in two bytes, eventhough we could use + * We always encode length in two bytes, even though we could use * only one byte if length <= 0x7F. It is just easier that way, * because we can leave room for fixed-length header, store all * the data first and then store the header. */ - stream_write_UINT16_be(s, 0x8000 | length); + Stream_Write_UINT16_BE(s, 0x8000 | length); if (sec_bytes > 0) { BYTE* fpInputEvents; UINT16 fpInputEvents_length; - fpInputEvents = stream_get_tail(s) + sec_bytes; + fpInputEvents = Stream_Pointer(s) + sec_bytes; fpInputEvents_length = length - 3 - sec_bytes; + if (rdp->sec_flags & SEC_SECURE_CHECKSUM) - security_salted_mac_signature(rdp, fpInputEvents, fpInputEvents_length, TRUE, stream_get_tail(s)); + security_salted_mac_signature(rdp, fpInputEvents, fpInputEvents_length, TRUE, Stream_Pointer(s)); else - security_mac_signature(rdp, fpInputEvents, fpInputEvents_length, stream_get_tail(s)); + security_mac_signature(rdp, fpInputEvents, fpInputEvents_length, Stream_Pointer(s)); + security_encrypt(fpInputEvents, fpInputEvents_length, rdp); } rdp->sec_flags = 0; - stream_set_pos(s, length); + Stream_SetPosition(s, length); + Stream_SealLength(s); + if (transport_write(fastpath->rdp->transport, s) < 0) return FALSE; return TRUE; } +BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s) +{ + return fastpath_send_multiple_input_pdu(fastpath, s, 1); +} + wStream* fastpath_update_pdu_init(rdpFastPath* fastpath) { wStream* s; + s = transport_send_stream_init(fastpath->rdp->transport, FASTPATH_MAX_PACKET_SIZE); - stream_seek(s, 3); /* fpOutputHeader, length1 and length2 */ - stream_seek(s, fastpath_get_sec_bytes(fastpath->rdp)); - stream_seek(s, 3); /* updateHeader, size */ + + Stream_Seek(s, 3); /* fpOutputHeader, length1 and length2 */ + Stream_Seek(s, fastpath_get_sec_bytes(fastpath->rdp)); + Stream_Seek(s, 3); /* updateHeader, size */ + + return s; +} + +wStream* fastpath_update_pdu_init_new(rdpFastPath* fastpath) +{ + wStream* s; + + s = Stream_New(NULL, FASTPATH_MAX_PACKET_SIZE); + + Stream_Seek(s, 3); /* fpOutputHeader, length1 and length2 */ + Stream_Seek(s, fastpath_get_sec_bytes(fastpath->rdp)); + Stream_Seek(s, 3); /* updateHeader, size */ + return s; } @@ -689,26 +827,27 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s result = TRUE; rdp = fastpath->rdp; + update = comp_update = ls = NULL; + try_comp = rdp->settings->CompressionEnabled; + sec_bytes = fastpath_get_sec_bytes(rdp); maxLength = FASTPATH_MAX_PACKET_SIZE - (6 + sec_bytes); - totalLength = stream_get_length(s) - (6 + sec_bytes); - stream_set_pos(s, 0); - update = stream_new(0); - try_comp = rdp->settings->CompressionEnabled; - comp_update = stream_new(0); + totalLength = Stream_GetPosition(s) - (6 + sec_bytes); + Stream_SetPosition(s, 0); - for (fragment = 0; totalLength > 0 || fragment == 0; fragment++) + for (fragment = 0; (totalLength > 0) || (fragment == 0); fragment++) { - stream_get_mark(s, holdp); + Stream_GetPointer(s, holdp); ls = s; dlen = MIN(maxLength, totalLength); cflags = 0; comp_flags = 0; header_bytes = 6 + sec_bytes; pdu_data_bytes = dlen; + if (try_comp) { - if (compress_rdp(rdp->mppc_enc, ls->pointer + header_bytes, dlen)) + if (compress_rdp(rdp->mppc_enc, Stream_Pointer(ls) + header_bytes, dlen)) { if (rdp->mppc_enc->flags & PACKET_COMPRESSED) { @@ -717,12 +856,14 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s comp_flags = FASTPATH_OUTPUT_COMPRESSION_USED; header_bytes = 7 + sec_bytes; bm = (BYTE*) (rdp->mppc_enc->outputBuffer - header_bytes); - stream_attach(comp_update, bm, pdu_data_bytes + header_bytes); + comp_update = Stream_New(bm, pdu_data_bytes + header_bytes); ls = comp_update; } } else + { fprintf(stderr, "fastpath_send_update_pdu: mppc_encode failed\n"); + } } totalLength -= dlen; @@ -733,45 +874,53 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s else fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT; - stream_get_mark(ls, bm); + Stream_GetPointer(ls, bm); header = 0; - if (sec_bytes > 0) - header |= (FASTPATH_OUTPUT_ENCRYPTED << 6); - stream_write_BYTE(ls, header); /* fpOutputHeader (1 byte) */ - stream_write_BYTE(ls, 0x80 | (pduLength >> 8)); /* length1 */ - stream_write_BYTE(ls, pduLength & 0xFF); /* length2 */ if (sec_bytes > 0) - stream_seek(ls, sec_bytes); + header |= (FASTPATH_OUTPUT_ENCRYPTED << 6); + + Stream_Write_UINT8(ls, header); /* fpOutputHeader (1 byte) */ + Stream_Write_UINT8(ls, 0x80 | (pduLength >> 8)); /* length1 */ + Stream_Write_UINT8(ls, pduLength & 0xFF); /* length2 */ + + if (sec_bytes > 0) + Stream_Seek(ls, sec_bytes); fastpath_write_update_header(ls, updateCode, fragmentation, comp_flags); /* extra byte if compressed */ if (ls == comp_update) { - stream_write_BYTE(ls, cflags); + Stream_Write_UINT8(ls, cflags); bytes_to_crypt = pdu_data_bytes + 4; } else + { bytes_to_crypt = pdu_data_bytes + 3; + } - stream_write_UINT16(ls, pdu_data_bytes); + Stream_Write_UINT16(ls, pdu_data_bytes); - stream_attach(update, bm, pduLength); - stream_seek(update, pduLength); + update = Stream_New(bm, pduLength); + Stream_Seek(update, pduLength); if (sec_bytes > 0) { /* does this work ? */ ptr_to_crypt = bm + 3 + sec_bytes; ptr_sig = bm + 3; + if (rdp->sec_flags & SEC_SECURE_CHECKSUM) security_salted_mac_signature(rdp, ptr_to_crypt, bytes_to_crypt, TRUE, ptr_sig); else security_mac_signature(rdp, ptr_to_crypt, bytes_to_crypt, ptr_sig); + security_encrypt(ptr_to_crypt, bytes_to_crypt, rdp); } + Stream_SealLength(s); + if (transport_write(fastpath->rdp->transport, update) < 0) { result = FALSE; @@ -779,13 +928,11 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s } /* Reserve 6 + sec_bytes bytes for the next fragment header, if any. */ - stream_set_mark(s, holdp + dlen); + Stream_SetPointer(s, holdp + dlen); } - stream_detach(update); - stream_detach(comp_update); - stream_free(update); - stream_free(comp_update); + Stream_Free(update, FALSE); + Stream_Free(comp_update, FALSE); return result; } @@ -795,16 +942,22 @@ rdpFastPath* fastpath_new(rdpRdp* rdp) rdpFastPath* fastpath; fastpath = (rdpFastPath*) malloc(sizeof(rdpFastPath)); - ZeroMemory(fastpath, sizeof(rdpFastPath)); - fastpath->rdp = rdp; - fastpath->updateData = stream_new(4096); + if (fastpath) + { + ZeroMemory(fastpath, sizeof(rdpFastPath)); + + fastpath->rdp = rdp; + fastpath->fragmentation = -1; + } return fastpath; } void fastpath_free(rdpFastPath* fastpath) { - stream_free(fastpath->updateData); - free(fastpath); + if (fastpath) + { + free(fastpath); + } } diff --git a/libfreerdp/core/fastpath.h b/libfreerdp/core/fastpath.h index e7bcab46c..243196959 100644 --- a/libfreerdp/core/fastpath.h +++ b/libfreerdp/core/fastpath.h @@ -101,6 +101,7 @@ struct rdp_fastpath BYTE encryptionFlags; BYTE numberEvents; wStream* updateData; + int fragmentation; }; UINT16 fastpath_header_length(wStream* s); @@ -109,10 +110,13 @@ BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, wStream* s, UINT16 *length) int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s); int fastpath_recv_inputs(rdpFastPath* fastpath, wStream* s); +wStream* fastpath_input_pdu_init_header(rdpFastPath* fastpath); wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE eventCode); +BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iEventCount); BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s); wStream* fastpath_update_pdu_init(rdpFastPath* fastpath); +wStream* fastpath_update_pdu_init_new(rdpFastPath* fastpath); BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s); BOOL fastpath_send_surfcmd_frame_marker(rdpFastPath* fastpath, UINT16 frameAction, UINT32 frameId); diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index b1d05fb82..9b4643ccd 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -73,7 +73,7 @@ BOOL freerdp_connect(freerdp* instance) extension_load_and_init_plugins(rdp->extension); extension_pre_connect(rdp->extension); - if (status != TRUE) + if (!status) { if (!connectErrorCode) { @@ -84,6 +84,7 @@ BOOL freerdp_connect(freerdp* instance) } status = rdp_client_connect(rdp); + /* --authonly tests the connection without a UI */ if (instance->settings->AuthenticationOnly) { @@ -105,7 +106,7 @@ BOOL freerdp_connect(freerdp* instance) IFCALLRET(instance->PostConnect, status, instance); update_post_connect(instance->update); - if (status != TRUE) + if (!status) { fprintf(stderr, "freerdp_post_connect failed\n"); @@ -123,31 +124,31 @@ BOOL freerdp_connect(freerdp* instance) rdpUpdate* update; pcap_record record; - s = stream_new(1024); - instance->update->pcap_rfx = pcap_open(instance->settings->PlayRemoteFxFile, FALSE); - - if (instance->update->pcap_rfx) - instance->update->play_rfx = TRUE; - update = instance->update; - while (instance->update->play_rfx && pcap_has_next_record(update->pcap_rfx)) + s = StreamPool_Take(rdp->transport->ReceivePool, 0); + instance->update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE); + + if (update->pcap_rfx) + update->play_rfx = TRUE; + + while (update->play_rfx && pcap_has_next_record(update->pcap_rfx)) { pcap_get_next_record_header(update->pcap_rfx, &record); - s->buffer = (BYTE*) realloc(s->buffer, record.length); - record.data = s->buffer; - s->capacity = record.length; + Stream_EnsureCapacity(s, record.length); + record.data = Stream_Buffer(s); pcap_get_next_record_content(update->pcap_rfx, &record); - stream_set_pos(s, 0); + Stream_SetPosition(s, 0); update->BeginPaint(update->context); - update_recv_surfcmds(update, s->capacity, s); + update_recv_surfcmds(update, Stream_Capacity(s), s); update->EndPaint(update->context); } - free(s->buffer); + Stream_Release(s); + return TRUE; } } @@ -156,7 +157,9 @@ BOOL freerdp_connect(freerdp* instance) { connectErrorCode = UNDEFINEDCONNECTERROR; } - + + SetEvent(rdp->transport->connectedEvent); + return status; } @@ -272,6 +275,22 @@ BOOL freerdp_shall_disconnect(freerdp* instance) return instance->context->rdp->disconnect; } +FREERDP_API BOOL freerdp_focus_required(freerdp* instance) +{ + rdpRdp* rdp; + BOOL bRetCode = FALSE; + + rdp = instance->context->rdp; + + if (rdp->resendFocus) + { + bRetCode = TRUE; + rdp->resendFocus = FALSE; + } + + return bRetCode; +} + void freerdp_get_version(int* major, int* minor, int* revision) { if (major != NULL) @@ -340,7 +359,7 @@ void freerdp_context_new(freerdp* instance) */ void freerdp_context_free(freerdp* instance) { - if (instance->context == NULL) + if (!instance->context) return; IFCALL(instance->ContextFree, instance, instance->context); @@ -348,6 +367,8 @@ void freerdp_context_free(freerdp* instance) rdp_free(instance->context->rdp); graphics_free(instance->context->graphics); + free(instance->context->client); + free(instance->context); instance->context = NULL; } diff --git a/libfreerdp/core/gateway/http.c b/libfreerdp/core/gateway/http.c index 9c2ee81fb..ca1845479 100644 --- a/libfreerdp/core/gateway/http.c +++ b/libfreerdp/core/gateway/http.c @@ -24,6 +24,7 @@ #include <winpr/crt.h> #include <winpr/print.h> #include <winpr/stream.h> +#include <winpr/string.h> #include "http.h" @@ -249,7 +250,7 @@ wStream* http_request_write(HttpContext* http_context, HttpRequest* http_request Stream_Write(s, "\0", 1); /* append null terminator */ Stream_Rewind(s, 1); /* don't include null terminator in length */ - Stream_Length(s) = Stream_Position(s); + Stream_Length(s) = Stream_GetPosition(s); return s; } @@ -280,31 +281,36 @@ void http_request_free(HttpRequest* http_request) } } -void http_response_parse_header_status_line(HttpResponse* http_response, char* status_line) +BOOL http_response_parse_header_status_line(HttpResponse* http_response, char* status_line) { char* separator; char* status_code; char* reason_phrase; separator = strchr(status_line, ' '); + if (!separator) + return FALSE; status_code = separator + 1; separator = strchr(status_code, ' '); + if (!separator) + return FALSE; reason_phrase = separator + 1; *separator = '\0'; http_response->StatusCode = atoi(status_code); http_response->ReasonPhrase = _strdup(reason_phrase); *separator = ' '; + return TRUE; } void http_response_parse_header_field(HttpResponse* http_response, char* name, char* value) { - if (strcmp(name, "Content-Length") == 0) + if (_stricmp(name, "Content-Length") == 0) { http_response->ContentLength = atoi(value); } - else if (strcmp(name, "Authorization") == 0) + else if (_stricmp(name, "Authorization") == 0) { char* separator; @@ -320,7 +326,7 @@ void http_response_parse_header_field(HttpResponse* http_response, char* name, c *separator = ' '; } } - else if (strcmp(name, "WWW-Authenticate") == 0) + else if (_stricmp(name, "WWW-Authenticate") == 0) { char* separator; @@ -348,36 +354,63 @@ void http_response_parse_header_field(HttpResponse* http_response, char* name, c } } -void http_response_parse_header(HttpResponse* http_response) +BOOL http_response_parse_header(HttpResponse* http_response) { int count; char* line; char* name; char* value; - char* separator; + char* colon_pos; + char* end_of_header; + char end_of_header_char; + char c; - http_response_parse_header_status_line(http_response, http_response->lines[0]); + if (!http_response_parse_header_status_line(http_response, http_response->lines[0])) + return FALSE; for (count = 1; count < http_response->count; count++) { line = http_response->lines[count]; - separator = strstr(line, ": "); + /** + * name end_of_header + * | | + * v v + * <header name> : <header value> + * ^ ^ + * | | + * colon_pos value + */ + colon_pos = strchr(line, ':'); + if ((colon_pos == NULL) || (colon_pos == line)) + return FALSE; - if (separator == NULL) - continue; - - separator[0] = '\0'; - separator[1] = '\0'; + /* retrieve the position just after header name */ + for(end_of_header = colon_pos; end_of_header != line; end_of_header--) + { + c = end_of_header[-1]; + if (c != ' ' && c != '\t' && c != ':') + break; + } + if (end_of_header == line) + return FALSE; + end_of_header_char = *end_of_header; + *end_of_header = '\0'; name = line; - value = separator + 2; + + /* eat space and tabs before header value */ + for (value = colon_pos + 1; *value; value++) + { + if ((*value != ' ') && (*value != '\t')) + break; + } http_response_parse_header_field(http_response, name, value); - separator[0] = ':'; - separator[1] = ' '; + *end_of_header = end_of_header_char; } + return TRUE; } void http_response_print(HttpResponse* http_response) @@ -435,11 +468,7 @@ HttpResponse* http_response_recv(rdpTls* tls) header_end = strstr((char*) buffer, "\r\n\r\n"); - if (header_end) - { - header_end += 2; - } - else + if (!header_end) { fprintf(stderr, "http_response_recv: invalid response:\n"); winpr_HexDump(buffer, status); @@ -447,6 +476,8 @@ HttpResponse* http_response_recv(rdpTls* tls) return NULL; } + header_end += 2; + if (header_end != NULL) { int count; @@ -478,7 +509,11 @@ HttpResponse* http_response_recv(rdpTls* tls) count++; } - http_response_parse_header(http_response); + if (!http_response_parse_header(http_response)) + { + http_response_free(http_response); + return NULL; + } if (http_response->ContentLength > 0) { diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index d60ab3381..d07ff21d6 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -105,7 +105,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) Stream_EnsureCapacity(rpc->client->pdu->s, Stream_Length(fragment)); Stream_Write(rpc->client->pdu->s, buffer, Stream_Length(fragment)); - Stream_Length(rpc->client->pdu->s) = Stream_Position(rpc->client->pdu->s); + Stream_Length(rpc->client->pdu->s) = Stream_GetPosition(rpc->client->pdu->s); rpc_client_fragment_pool_return(rpc, fragment); @@ -195,7 +195,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) rpc->client->pdu->Flags = RPC_PDU_FLAG_STUB; rpc->client->pdu->CallId = rpc->StubCallId; - Stream_Length(rpc->client->pdu->s) = Stream_Position(rpc->client->pdu->s); + Stream_Length(rpc->client->pdu->s) = Stream_GetPosition(rpc->client->pdu->s); rpc->StubFragCount = 0; rpc->StubCallId = 0; @@ -219,12 +219,12 @@ int rpc_client_on_read_event(rdpRpc* rpc) if (!rpc->client->RecvFrag) rpc->client->RecvFrag = rpc_client_fragment_pool_take(rpc); - position = Stream_Position(rpc->client->RecvFrag); + position = Stream_GetPosition(rpc->client->RecvFrag); - if (Stream_Position(rpc->client->RecvFrag) < RPC_COMMON_FIELDS_LENGTH) + if (Stream_GetPosition(rpc->client->RecvFrag) < RPC_COMMON_FIELDS_LENGTH) { status = rpc_out_read(rpc, Stream_Pointer(rpc->client->RecvFrag), - RPC_COMMON_FIELDS_LENGTH - Stream_Position(rpc->client->RecvFrag)); + RPC_COMMON_FIELDS_LENGTH - Stream_GetPosition(rpc->client->RecvFrag)); if (status < 0) { @@ -235,7 +235,7 @@ int rpc_client_on_read_event(rdpRpc* rpc) Stream_Seek(rpc->client->RecvFrag, status); } - if (Stream_Position(rpc->client->RecvFrag) >= RPC_COMMON_FIELDS_LENGTH) + if (Stream_GetPosition(rpc->client->RecvFrag) >= RPC_COMMON_FIELDS_LENGTH) { header = (rpcconn_common_hdr_t*) Stream_Buffer(rpc->client->RecvFrag); @@ -243,14 +243,14 @@ int rpc_client_on_read_event(rdpRpc* rpc) { fprintf(stderr, "rpc_client_frag_read: invalid fragment size: %d (max: %d)\n", header->frag_length, rpc->max_recv_frag); - winpr_HexDump(Stream_Buffer(rpc->client->RecvFrag), Stream_Position(rpc->client->RecvFrag)); + winpr_HexDump(Stream_Buffer(rpc->client->RecvFrag), Stream_GetPosition(rpc->client->RecvFrag)); return -1; } - if (Stream_Position(rpc->client->RecvFrag) < header->frag_length) + if (Stream_GetPosition(rpc->client->RecvFrag) < header->frag_length) { status = rpc_out_read(rpc, Stream_Pointer(rpc->client->RecvFrag), - header->frag_length - Stream_Position(rpc->client->RecvFrag)); + header->frag_length - Stream_GetPosition(rpc->client->RecvFrag)); if (status < 0) { @@ -269,13 +269,13 @@ int rpc_client_on_read_event(rdpRpc* rpc) if (status < 0) return -1; - status = Stream_Position(rpc->client->RecvFrag) - position; + status = Stream_GetPosition(rpc->client->RecvFrag) - position; - if (Stream_Position(rpc->client->RecvFrag) >= header->frag_length) + if (Stream_GetPosition(rpc->client->RecvFrag) >= header->frag_length) { /* complete fragment received */ - Stream_Length(rpc->client->RecvFrag) = Stream_Position(rpc->client->RecvFrag); + Stream_Length(rpc->client->RecvFrag) = Stream_GetPosition(rpc->client->RecvFrag); Stream_SetPosition(rpc->client->RecvFrag, 0); Queue_Enqueue(rpc->client->FragmentQueue, rpc->client->RecvFrag); @@ -415,7 +415,7 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc) if (pdu) { fprintf(stderr, "Receiving PDU (length: %d, CallId: %d)\n", pdu->s->length, pdu->CallId); - winpr_HexDump(pdu->s->buffer, pdu->s->length); + winpr_HexDump(Stream_Buffer(pdu->s), Stream_Length(pdu->s)); fprintf(stderr, "\n"); } #endif diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 1aa2f9a5e..7d2b4a7fc 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -121,7 +121,7 @@ DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], UINT32 count, if (buffer3Length > 0) Stream_Write(s, buffer3, buffer3Length); /* buffer3 (variable) */ - Stream_Length(s) = Stream_Position(s); + Stream_Length(s) = Stream_GetPosition(s); status = rpc_write(tsg->rpc, Stream_Buffer(s), Stream_Length(s), TsProxySendToServerOpnum); diff --git a/libfreerdp/core/gateway/tsg.h b/libfreerdp/core/gateway/tsg.h index 40ba028a1..23b10155b 100644 --- a/libfreerdp/core/gateway/tsg.h +++ b/libfreerdp/core/gateway/tsg.h @@ -61,8 +61,8 @@ struct rdp_tsg LPWSTR MachineName; TSG_STATE state; BOOL PendingPdu; - BOOL BytesRead; - BOOL BytesAvailable; + UINT32 BytesRead; + UINT32 BytesAvailable; UINT32 StubOffset; UINT32 StubLength; rdpSettings* settings; diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 2904fe619..316f4f968 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -179,7 +179,7 @@ BOOL gcc_read_conference_create_request(wStream* s, rdpSettings* settings) /* userData::value (OCTET_STRING) */ if (!per_read_length(s, &length)) return FALSE; - if (stream_get_left(s) < length) + if (Stream_GetRemainingLength(s) < length) return FALSE; if (!gcc_read_client_data_blocks(s, settings, length)) return FALSE; @@ -201,7 +201,7 @@ void gcc_write_conference_create_request(wStream* s, wStream* user_data) per_write_object_identifier(s, t124_02_98_oid); /* ITU-T T.124 (02/98) OBJECT_IDENTIFIER */ /* ConnectData::connectPDU (OCTET_STRING) */ - per_write_length(s, stream_get_length(user_data) + 14); /* connectPDU length */ + per_write_length(s, Stream_GetPosition(user_data) + 14); /* connectPDU length */ /* ConnectGCCPDU */ per_write_choice(s, 0); /* From ConnectGCCPDU select conferenceCreateRequest (0) of type ConferenceCreateRequest */ @@ -219,7 +219,7 @@ void gcc_write_conference_create_request(wStream* s, wStream* user_data) per_write_octet_string(s, h221_cs_key, 4, 4); /* h221NonStandard, client-to-server H.221 key, "Duca" */ /* userData::value (OCTET_STRING) */ - per_write_octet_string(s, user_data->buffer, stream_get_length(user_data), 0); /* array of client data blocks */ + per_write_octet_string(s, user_data->buffer, Stream_GetPosition(user_data), 0); /* array of client data blocks */ } BOOL gcc_read_conference_create_response(wStream* s, rdpSettings* settings) @@ -278,7 +278,7 @@ void gcc_write_conference_create_response(wStream* s, wStream* user_data) per_write_object_identifier(s, t124_02_98_oid); /* ConnectData::connectPDU (OCTET_STRING) */ - per_write_length(s, stream_get_length(user_data) + 2); + per_write_length(s, Stream_GetPosition(user_data) + 2); /* ConnectGCCPDU */ per_write_choice(s, 0x14); @@ -302,7 +302,7 @@ void gcc_write_conference_create_response(wStream* s, wStream* user_data) per_write_octet_string(s, h221_sc_key, 4, 4); /* h221NonStandard, server-to-client H.221 key, "McDn" */ /* userData (OCTET_STRING) */ - per_write_octet_string(s, user_data->buffer, stream_get_length(user_data), 0); /* array of server data blocks */ + per_write_octet_string(s, user_data->buffer, Stream_GetPosition(user_data), 0); /* array of server data blocks */ } BOOL gcc_read_client_data_blocks(wStream* s, rdpSettings* settings, int length) @@ -313,7 +313,7 @@ BOOL gcc_read_client_data_blocks(wStream* s, rdpSettings* settings, int length) while (length > 0) { - pos = stream_get_pos(s); + pos = Stream_GetPosition(s); if(!gcc_read_user_data_header(s, &type, &blockLength)) return FALSE; @@ -349,7 +349,7 @@ BOOL gcc_read_client_data_blocks(wStream* s, rdpSettings* settings, int length) } length -= blockLength; - stream_set_pos(s, pos + blockLength); + Stream_SetPosition(s, pos + blockLength); } return TRUE; @@ -399,7 +399,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpSettings* settings, int length) while (offset < length) { - holdp = s->pointer; + holdp = Stream_Pointer(s); if (!gcc_read_user_data_header(s, &type, &blockLength)) { @@ -438,7 +438,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpSettings* settings, int length) break; } offset += blockLength; - s->pointer = holdp + blockLength; + Stream_Pointer(s) = holdp + blockLength; } return TRUE; @@ -453,13 +453,13 @@ void gcc_write_server_data_blocks(wStream* s, rdpSettings* settings) BOOL gcc_read_user_data_header(wStream* s, UINT16* type, UINT16* length) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT16(s, *type); /* type */ - stream_read_UINT16(s, *length); /* length */ + Stream_Read_UINT16(s, *type); /* type */ + Stream_Read_UINT16(s, *length); /* length */ - if (stream_get_left(s) < *length - 4) + if (Stream_GetRemainingLength(s) < *length - 4) return FALSE; return TRUE; @@ -475,8 +475,8 @@ BOOL gcc_read_user_data_header(wStream* s, UINT16* type, UINT16* length) void gcc_write_user_data_header(wStream* s, UINT16 type, UINT16 length) { - stream_write_UINT16(s, type); /* type */ - stream_write_UINT16(s, length); /* length */ + Stream_Write_UINT16(s, type); /* type */ + Stream_Write_UINT16(s, length); /* length */ } /** @@ -501,29 +501,29 @@ BOOL gcc_read_client_core_data(wStream* s, rdpSettings* settings, UINT16 blockLe if (blockLength < 128) return FALSE; - stream_read_UINT32(s, version); /* version */ + Stream_Read_UINT32(s, version); /* version */ settings->RdpVersion = (version == RDP_VERSION_4 ? 4 : 7); - stream_read_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ - stream_read_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ - stream_read_UINT16(s, colorDepth); /* ColorDepth */ - stream_seek_UINT16(s); /* SASSequence (Secure Access Sequence) */ - stream_read_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ - stream_read_UINT32(s, settings->ClientBuild); /* ClientBuild */ + Stream_Read_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ + Stream_Read_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ + Stream_Read_UINT16(s, colorDepth); /* ColorDepth */ + Stream_Seek_UINT16(s); /* SASSequence (Secure Access Sequence) */ + Stream_Read_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ + Stream_Read_UINT32(s, settings->ClientBuild); /* ClientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), 32 / 2, &str, 0, NULL, NULL); - stream_seek(s, 32); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), 32 / 2, &str, 0, NULL, NULL); + Stream_Seek(s, 32); sprintf_s(settings->ClientHostname, 31, "%s", str); settings->ClientHostname[31] = 0; free(str); str = NULL; - stream_read_UINT32(s, settings->KeyboardType); /* KeyboardType */ - stream_read_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ - stream_read_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ + Stream_Read_UINT32(s, settings->KeyboardType); /* KeyboardType */ + Stream_Read_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ + Stream_Read_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ - stream_seek(s, 64); /* imeFileName */ + Stream_Seek(s, 64); /* imeFileName */ blockLength -= 128; @@ -538,56 +538,56 @@ BOOL gcc_read_client_core_data(wStream* s, rdpSettings* settings, UINT16 blockLe { if (blockLength < 2) break; - stream_read_UINT16(s, postBeta2ColorDepth); /* postBeta2ColorDepth */ + Stream_Read_UINT16(s, postBeta2ColorDepth); /* postBeta2ColorDepth */ blockLength -= 2; if (blockLength < 2) break; - stream_seek_UINT16(s); /* clientProductID */ + Stream_Seek_UINT16(s); /* clientProductID */ blockLength -= 2; if (blockLength < 4) break; - stream_seek_UINT32(s); /* serialNumber */ + Stream_Seek_UINT32(s); /* serialNumber */ blockLength -= 4; if (blockLength < 2) break; - stream_read_UINT16(s, highColorDepth); /* highColorDepth */ + Stream_Read_UINT16(s, highColorDepth); /* highColorDepth */ blockLength -= 2; if (blockLength < 2) break; - stream_read_UINT16(s, supportedColorDepths); /* supportedColorDepths */ + Stream_Read_UINT16(s, supportedColorDepths); /* supportedColorDepths */ blockLength -= 2; if (blockLength < 2) break; - stream_read_UINT16(s, settings->EarlyCapabilityFlags); /* earlyCapabilityFlags */ + Stream_Read_UINT16(s, settings->EarlyCapabilityFlags); /* earlyCapabilityFlags */ blockLength -= 2; if (blockLength < 64) break; - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), 64 / 2, &str, 0, NULL, NULL); - stream_seek(s, 64); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), 64 / 2, &str, 0, NULL, NULL); + Stream_Seek(s, 64); sprintf_s(settings->ClientProductId, 32, "%s", str); free(str); blockLength -= 64; if (blockLength < 1) break; - stream_read_BYTE(s, settings->PerformanceFlags); /* connectionType */ + Stream_Read_UINT8(s, settings->PerformanceFlags); /* connectionType */ blockLength -= 1; if (blockLength < 1) break; - stream_seek_BYTE(s); /* pad1octet */ + Stream_Seek_UINT8(s); /* pad1octet */ blockLength -= 1; if (blockLength < 4) break; - stream_read_UINT32(s, serverSelectedProtocol); /* serverSelectedProtocol */ + Stream_Read_UINT32(s, serverSelectedProtocol); /* serverSelectedProtocol */ blockLength -= 4; if (settings->SelectedProtocol != serverSelectedProtocol) @@ -675,13 +675,13 @@ void gcc_write_client_core_data(wStream* s, rdpSettings* settings) clientNameLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientHostname, -1, &clientName, 0); clientDigProductIdLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientProductId, -1, &clientDigProductId, 0); - stream_write_UINT32(s, version); /* Version */ - stream_write_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ - stream_write_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ - stream_write_UINT16(s, RNS_UD_COLOR_8BPP); /* ColorDepth, ignored because of postBeta2ColorDepth */ - stream_write_UINT16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ - stream_write_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ - stream_write_UINT32(s, settings->ClientBuild); /* ClientBuild */ + Stream_Write_UINT32(s, version); /* Version */ + Stream_Write_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ + Stream_Write_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ + Stream_Write_UINT16(s, RNS_UD_COLOR_8BPP); /* ColorDepth, ignored because of postBeta2ColorDepth */ + Stream_Write_UINT16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ + Stream_Write_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ + Stream_Write_UINT32(s, settings->ClientBuild); /* ClientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ @@ -691,19 +691,19 @@ void gcc_write_client_core_data(wStream* s, rdpSettings* settings) clientName[clientNameLength-1] = 0; } - stream_write(s, clientName, (clientNameLength * 2)); - stream_write_zero(s, 32 - (clientNameLength * 2)); + Stream_Write(s, clientName, (clientNameLength * 2)); + Stream_Zero(s, 32 - (clientNameLength * 2)); free(clientName); - stream_write_UINT32(s, settings->KeyboardType); /* KeyboardType */ - stream_write_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ - stream_write_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ + Stream_Write_UINT32(s, settings->KeyboardType); /* KeyboardType */ + Stream_Write_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ + Stream_Write_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ - stream_write_zero(s, 64); /* imeFileName */ + Stream_Zero(s, 64); /* imeFileName */ - stream_write_UINT16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */ - stream_write_UINT16(s, 1); /* clientProductID */ - stream_write_UINT32(s, 0); /* serialNumber (should be initialized to 0) */ + Stream_Write_UINT16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */ + Stream_Write_UINT16(s, 1); /* clientProductID */ + Stream_Write_UINT32(s, 0); /* serialNumber (should be initialized to 0) */ highColorDepth = MIN(settings->ColorDepth, 24); @@ -727,10 +727,10 @@ void gcc_write_client_core_data(wStream* s, rdpSettings* settings) earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION; } - stream_write_UINT16(s, highColorDepth); /* highColorDepth */ - stream_write_UINT16(s, supportedColorDepths); /* supportedColorDepths */ + Stream_Write_UINT16(s, highColorDepth); /* highColorDepth */ + Stream_Write_UINT16(s, supportedColorDepths); /* supportedColorDepths */ - stream_write_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ + Stream_Write_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ /* clientDigProductId (64 bytes, null-terminated unicode, truncated to 31 characters) */ if (clientDigProductIdLength >= 32) @@ -738,14 +738,14 @@ void gcc_write_client_core_data(wStream* s, rdpSettings* settings) clientDigProductIdLength = 32; clientDigProductId[clientDigProductIdLength-1] = 0; } - stream_write(s, clientDigProductId, (clientDigProductIdLength * 2) ); - stream_write_zero(s, 64 - (clientDigProductIdLength * 2) ); + Stream_Write(s, clientDigProductId, (clientDigProductIdLength * 2) ); + Stream_Zero(s, 64 - (clientDigProductIdLength * 2) ); free(clientDigProductId); - stream_write_BYTE(s, connectionType); /* connectionType */ - stream_write_BYTE(s, 0); /* pad1octet */ + Stream_Write_UINT8(s, connectionType); /* connectionType */ + Stream_Write_UINT8(s, 0); /* pad1octet */ - stream_write_UINT32(s, settings->SelectedProtocol); /* serverSelectedProtocol */ + Stream_Write_UINT32(s, settings->SelectedProtocol); /* serverSelectedProtocol */ } BOOL gcc_read_server_core_data(wStream* s, rdpSettings* settings) @@ -753,10 +753,10 @@ BOOL gcc_read_server_core_data(wStream* s, rdpSettings* settings) UINT32 version; UINT32 clientRequestedProtocols; - if(stream_get_left(s) < 8) + if(Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, version); /* version */ - stream_read_UINT32(s, clientRequestedProtocols); /* clientRequestedProtocols */ + Stream_Read_UINT32(s, version); /* version */ + Stream_Read_UINT32(s, clientRequestedProtocols); /* clientRequestedProtocols */ if (version == RDP_VERSION_4 && settings->RdpVersion > 4) settings->RdpVersion = 4; @@ -770,8 +770,8 @@ void gcc_write_server_core_data(wStream* s, rdpSettings* settings) { gcc_write_user_data_header(s, SC_CORE, 12); - stream_write_UINT32(s, settings->RdpVersion == 4 ? RDP_VERSION_4 : RDP_VERSION_5_PLUS); - stream_write_UINT32(s, settings->RequestedProtocols); /* clientRequestedProtocols */ + Stream_Write_UINT32(s, settings->RdpVersion == 4 ? RDP_VERSION_4 : RDP_VERSION_5_PLUS); + Stream_Write_UINT32(s, settings->RequestedProtocols); /* clientRequestedProtocols */ } /** @@ -788,13 +788,13 @@ BOOL gcc_read_client_security_data(wStream* s, rdpSettings* settings, UINT16 blo if (settings->DisableEncryption) { - stream_read_UINT32(s, settings->EncryptionMethods); /* encryptionMethods */ + Stream_Read_UINT32(s, settings->EncryptionMethods); /* encryptionMethods */ if (settings->EncryptionMethods == 0) - stream_read_UINT32(s, settings->EncryptionMethods); /* extEncryptionMethods */ + Stream_Read_UINT32(s, settings->EncryptionMethods); /* extEncryptionMethods */ } else { - stream_seek(s, 8); + Stream_Seek(s, 8); } return TRUE; } @@ -812,14 +812,14 @@ void gcc_write_client_security_data(wStream* s, rdpSettings* settings) if (settings->DisableEncryption) { - stream_write_UINT32(s, settings->EncryptionMethods); /* encryptionMethods */ - stream_write_UINT32(s, 0); /* extEncryptionMethods */ + Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethods */ + Stream_Write_UINT32(s, 0); /* extEncryptionMethods */ } else { /* French locale, disable encryption */ - stream_write_UINT32(s, 0); /* encryptionMethods */ - stream_write_UINT32(s, settings->EncryptionMethods); /* extEncryptionMethods */ + Stream_Write_UINT32(s, 0); /* encryptionMethods */ + Stream_Write_UINT32(s, settings->EncryptionMethods); /* extEncryptionMethods */ } } @@ -828,10 +828,10 @@ BOOL gcc_read_server_security_data(wStream* s, rdpSettings* settings) BYTE* data; UINT32 length; - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ - stream_read_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ + Stream_Read_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ + Stream_Read_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ if (settings->EncryptionMethods == 0 && settings->EncryptionLevel == 0) { @@ -842,19 +842,19 @@ BOOL gcc_read_server_security_data(wStream* s, rdpSettings* settings) return TRUE; } - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, settings->ServerRandomLength); /* serverRandomLen */ - stream_read_UINT32(s, settings->ServerCertificateLength); /* serverCertLen */ + Stream_Read_UINT32(s, settings->ServerRandomLength); /* serverRandomLen */ + Stream_Read_UINT32(s, settings->ServerCertificateLength); /* serverCertLen */ - if (stream_get_left(s) < settings->ServerRandomLength + settings->ServerCertificateLength) + if (Stream_GetRemainingLength(s) < settings->ServerRandomLength + settings->ServerCertificateLength) return FALSE; if (settings->ServerRandomLength > 0) { /* serverRandom */ settings->ServerRandom = (BYTE*) malloc(settings->ServerRandomLength); - stream_read(s, settings->ServerRandom, settings->ServerRandomLength); + Stream_Read(s, settings->ServerRandom, settings->ServerRandomLength); } else { @@ -865,7 +865,7 @@ BOOL gcc_read_server_security_data(wStream* s, rdpSettings* settings) { /* serverCertificate */ settings->ServerCertificate = (BYTE*) malloc(settings->ServerCertificateLength); - stream_read(s, settings->ServerCertificate, settings->ServerCertificateLength); + Stream_Read(s, settings->ServerCertificate, settings->ServerCertificateLength); certificate_free(settings->RdpServerCertificate); settings->RdpServerCertificate = certificate_new(); @@ -999,8 +999,8 @@ void gcc_write_server_security_data(wStream* s, rdpSettings* settings) gcc_write_user_data_header(s, SC_SECURITY, headerLen); - stream_write_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ - stream_write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ + Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ + Stream_Write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE && settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE) @@ -1008,35 +1008,35 @@ void gcc_write_server_security_data(wStream* s, rdpSettings* settings) return; } - stream_write_UINT32(s, serverRandomLen); /* serverRandomLen */ - stream_write_UINT32(s, serverCertLen); /* serverCertLen */ + Stream_Write_UINT32(s, serverRandomLen); /* serverRandomLen */ + Stream_Write_UINT32(s, serverCertLen); /* serverCertLen */ settings->ServerRandomLength = serverRandomLen; settings->ServerRandom = (BYTE*) malloc(serverRandomLen); crypto_nonce(settings->ServerRandom, serverRandomLen); - stream_write(s, settings->ServerRandom, serverRandomLen); + Stream_Write(s, settings->ServerRandom, serverRandomLen); - sigData = stream_get_tail(s); + sigData = Stream_Pointer(s); - stream_write_UINT32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */ - stream_write_UINT32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */ - stream_write_UINT32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */ - stream_write_UINT16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */ + Stream_Write_UINT32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */ + Stream_Write_UINT32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */ + Stream_Write_UINT32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */ + Stream_Write_UINT16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */ - stream_write_UINT16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */ - stream_write(s, "RSA1", 4); /* magic */ - stream_write_UINT32(s, keyLen + 8); /* keylen */ - stream_write_UINT32(s, keyLen * 8); /* bitlen */ - stream_write_UINT32(s, keyLen - 1); /* datalen */ + Stream_Write_UINT16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */ + Stream_Write(s, "RSA1", 4); /* magic */ + Stream_Write_UINT32(s, keyLen + 8); /* keylen */ + Stream_Write_UINT32(s, keyLen * 8); /* bitlen */ + Stream_Write_UINT32(s, keyLen - 1); /* datalen */ - stream_write(s, settings->RdpServerRsaKey->exponent, expLen); - stream_write(s, settings->RdpServerRsaKey->Modulus, keyLen); - stream_write_zero(s, 8); + Stream_Write(s, settings->RdpServerRsaKey->exponent, expLen); + Stream_Write(s, settings->RdpServerRsaKey->Modulus, keyLen); + Stream_Zero(s, 8); - sigDataLen = stream_get_tail(s) - sigData; + sigDataLen = Stream_Pointer(s) - sigData; - stream_write_UINT16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ - stream_write_UINT16(s, keyLen + 8); /* wSignatureBlobLen */ + Stream_Write_UINT16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ + Stream_Write_UINT16(s, keyLen + 8); /* wSignatureBlobLen */ memcpy(signature, initial_signature, sizeof(initial_signature)); @@ -1047,8 +1047,8 @@ void gcc_write_server_security_data(wStream* s, rdpSettings* settings) crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, tssk_modulus, tssk_privateExponent, encryptedSignature); - stream_write(s, encryptedSignature, sizeof(encryptedSignature)); - stream_write_zero(s, 8); + Stream_Write(s, encryptedSignature, sizeof(encryptedSignature)); + Stream_Zero(s, 8); } /** @@ -1065,7 +1065,7 @@ BOOL gcc_read_client_network_data(wStream* s, rdpSettings* settings, UINT16 bloc if (blockLength < 4) return FALSE; - stream_read_UINT32(s, settings->ChannelCount); /* channelCount */ + Stream_Read_UINT32(s, settings->ChannelCount); /* channelCount */ if (blockLength < 4 + settings->ChannelCount * 12) return FALSE; if (settings->ChannelCount > 16) @@ -1075,8 +1075,8 @@ BOOL gcc_read_client_network_data(wStream* s, rdpSettings* settings, UINT16 bloc for (i = 0; i < settings->ChannelCount; i++) { /* CHANNEL_DEF */ - stream_read(s, settings->ChannelDefArray[i].Name, 8); /* name (8 bytes) */ - stream_read_UINT32(s, settings->ChannelDefArray[i].options); /* options (4 bytes) */ + Stream_Read(s, settings->ChannelDefArray[i].Name, 8); /* name (8 bytes) */ + Stream_Read_UINT32(s, settings->ChannelDefArray[i].options); /* options (4 bytes) */ settings->ChannelDefArray[i].ChannelId = MCS_GLOBAL_CHANNEL_ID + 1 + i; } @@ -1100,14 +1100,14 @@ void gcc_write_client_network_data(wStream* s, rdpSettings* settings) length = settings->ChannelCount * 12 + 8; gcc_write_user_data_header(s, CS_NET, length); - stream_write_UINT32(s, settings->ChannelCount); /* channelCount */ + Stream_Write_UINT32(s, settings->ChannelCount); /* channelCount */ /* channelDefArray */ for (i = 0; i < settings->ChannelCount; i++) { /* CHANNEL_DEF */ - stream_write(s, settings->ChannelDefArray[i].Name, 8); /* name (8 bytes) */ - stream_write_UINT32(s, settings->ChannelDefArray[i].options); /* options (4 bytes) */ + Stream_Write(s, settings->ChannelDefArray[i].Name, 8); /* name (8 bytes) */ + Stream_Write_UINT32(s, settings->ChannelDefArray[i].options); /* options (4 bytes) */ } } } @@ -1119,10 +1119,10 @@ BOOL gcc_read_server_network_data(wStream* s, rdpSettings* settings) UINT16 channelCount; UINT16 channelId; - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT16(s, MCSChannelId); /* MCSChannelId */ - stream_read_UINT16(s, channelCount); /* channelCount */ + Stream_Read_UINT16(s, MCSChannelId); /* MCSChannelId */ + Stream_Read_UINT16(s, channelCount); /* channelCount */ if (channelCount != settings->ChannelCount) { @@ -1130,17 +1130,17 @@ BOOL gcc_read_server_network_data(wStream* s, rdpSettings* settings) settings->ChannelCount, channelCount); } - if(stream_get_left(s) < channelCount * 2) + if(Stream_GetRemainingLength(s) < channelCount * 2) return FALSE; for (i = 0; i < channelCount; i++) { - stream_read_UINT16(s, channelId); /* channelId */ + Stream_Read_UINT16(s, channelId); /* channelId */ settings->ChannelDefArray[i].ChannelId = channelId; } if (channelCount % 2 == 1) - return stream_skip(s, 2); /* padding */ + return Stream_SafeSeek(s, 2); /* padding */ return TRUE; } @@ -1151,16 +1151,16 @@ void gcc_write_server_network_data(wStream* s, rdpSettings* settings) gcc_write_user_data_header(s, SC_NET, 8 + settings->ChannelCount * 2 + (settings->ChannelCount % 2 == 1 ? 2 : 0)); - stream_write_UINT16(s, MCS_GLOBAL_CHANNEL_ID); /* MCSChannelId */ - stream_write_UINT16(s, settings->ChannelCount); /* channelCount */ + Stream_Write_UINT16(s, MCS_GLOBAL_CHANNEL_ID); /* MCSChannelId */ + Stream_Write_UINT16(s, settings->ChannelCount); /* channelCount */ for (i = 0; i < settings->ChannelCount; i++) { - stream_write_UINT16(s, settings->ChannelDefArray[i].ChannelId); + Stream_Write_UINT16(s, settings->ChannelDefArray[i].ChannelId); } if (settings->ChannelCount % 2 == 1) - stream_write_UINT16(s, 0); + Stream_Write_UINT16(s, 0); } /** @@ -1177,13 +1177,13 @@ BOOL gcc_read_client_cluster_data(wStream* s, rdpSettings* settings, UINT16 bloc if (blockLength < 4) return FALSE; - stream_read_UINT32(s, flags); /* flags */ + Stream_Read_UINT32(s, flags); /* flags */ if ((flags & REDIRECTED_SESSIONID_FIELD_VALID)) { if(blockLength < 8) return FALSE; - stream_read_UINT32(s, settings->RedirectedSessionId); /* redirectedSessionID */ + Stream_Read_UINT32(s, settings->RedirectedSessionId); /* redirectedSessionID */ } return TRUE; @@ -1207,8 +1207,8 @@ void gcc_write_client_cluster_data(wStream* s, rdpSettings* settings) if (settings->ConsoleSession || settings->RedirectedSessionId) flags |= REDIRECTED_SESSIONID_FIELD_VALID; - stream_write_UINT32(s, flags); /* flags */ - stream_write_UINT32(s, settings->RedirectedSessionId); /* redirectedSessionID */ + Stream_Write_UINT32(s, flags); /* flags */ + Stream_Write_UINT32(s, settings->RedirectedSessionId); /* redirectedSessionID */ } /** @@ -1242,8 +1242,8 @@ void gcc_write_client_monitor_data(wStream* s, rdpSettings* settings) length = (20 * settings->MonitorCount) + 12; gcc_write_user_data_header(s, CS_MONITOR, length); - stream_write_UINT32(s, 0); /* flags */ - stream_write_UINT32(s, settings->MonitorCount); /* monitorCount */ + Stream_Write_UINT32(s, 0); /* flags */ + Stream_Write_UINT32(s, settings->MonitorCount); /* monitorCount */ for (i = 0; i < settings->MonitorCount; i++) { @@ -1253,11 +1253,11 @@ void gcc_write_client_monitor_data(wStream* s, rdpSettings* settings) bottom = settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height - 1; flags = settings->MonitorDefArray[i].is_primary ? MONITOR_PRIMARY : 0; - stream_write_UINT32(s, left); /* left */ - stream_write_UINT32(s, top); /* top */ - stream_write_UINT32(s, right); /* right */ - stream_write_UINT32(s, bottom); /* bottom */ - stream_write_UINT32(s, flags); /* flags */ + Stream_Write_UINT32(s, left); /* left */ + Stream_Write_UINT32(s, top); /* top */ + Stream_Write_UINT32(s, right); /* right */ + Stream_Write_UINT32(s, bottom); /* bottom */ + Stream_Write_UINT32(s, flags); /* flags */ } } } diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 60caf5bf1..cee59322a 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -54,12 +54,12 @@ BOOL rdp_read_server_auto_reconnect_cookie(wStream* s, rdpSettings* settings) ARC_SC_PRIVATE_PACKET* autoReconnectCookie; autoReconnectCookie = settings->ServerAutoReconnectCookie; - if (stream_get_left(s) < 4+4+4+16) + if (Stream_GetRemainingLength(s) < 4+4+4+16) return FALSE; - stream_read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ - stream_read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ - stream_read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ - stream_read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */ + Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ + Stream_Read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ + Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ + Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */ return TRUE; } @@ -75,13 +75,13 @@ BOOL rdp_read_client_auto_reconnect_cookie(wStream* s, rdpSettings* settings) ARC_CS_PRIVATE_PACKET* autoReconnectCookie; autoReconnectCookie = settings->ClientAutoReconnectCookie; - if (stream_get_left(s) < 28) + if (Stream_GetRemainingLength(s) < 28) return FALSE; - stream_read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ - stream_read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ - stream_read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ - stream_read(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */ + Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ + Stream_Read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ + Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ + Stream_Read(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */ return TRUE; } @@ -98,10 +98,10 @@ void rdp_write_client_auto_reconnect_cookie(wStream* s, rdpSettings* settings) ARC_CS_PRIVATE_PACKET* autoReconnectCookie; autoReconnectCookie = settings->ClientAutoReconnectCookie; - stream_write_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ - stream_write_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ - stream_write_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ - stream_write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */ + Stream_Write_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ + Stream_Write_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ + Stream_Write_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ + Stream_Write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */ } /** @@ -118,41 +118,41 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings) UINT16 cbClientDir; UINT16 cbAutoReconnectLen; - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT16(s, clientAddressFamily); /* clientAddressFamily */ - stream_read_UINT16(s, cbClientAddress); /* cbClientAddress */ + Stream_Read_UINT16(s, clientAddressFamily); /* clientAddressFamily */ + Stream_Read_UINT16(s, cbClientAddress); /* cbClientAddress */ settings->IPv6Enabled = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? TRUE : FALSE); - if (stream_get_left(s) < cbClientAddress) + if (Stream_GetRemainingLength(s) < cbClientAddress) return FALSE; - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL); - stream_seek(s, cbClientAddress); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL); + Stream_Seek(s, cbClientAddress); - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, cbClientDir); /* cbClientDir */ + Stream_Read_UINT16(s, cbClientDir); /* cbClientDir */ - if (stream_get_left(s) < cbClientDir) + if (Stream_GetRemainingLength(s) < cbClientDir) return FALSE; if (settings->ClientDir) free(settings->ClientDir); - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbClientDir / 2, &settings->ClientDir, 0, NULL, NULL); - stream_seek(s, cbClientDir); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientDir / 2, &settings->ClientDir, 0, NULL, NULL); + Stream_Seek(s, cbClientDir); if (!rdp_read_client_time_zone(s, settings)) return FALSE; - if (stream_get_left(s) < 10) + if (Stream_GetRemainingLength(s) < 10) return FALSE; - stream_seek_UINT32(s); /* clientSessionId, should be set to 0 */ - stream_read_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ + Stream_Seek_UINT32(s); /* clientSessionId, should be set to 0 */ + Stream_Read_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ - stream_read_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ + Stream_Read_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ if (cbAutoReconnectLen > 0) return rdp_read_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ @@ -187,26 +187,26 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings) cbAutoReconnectLen = (int) settings->ClientAutoReconnectCookie->cbLen; - stream_write_UINT16(s, clientAddressFamily); /* clientAddressFamily */ + Stream_Write_UINT16(s, clientAddressFamily); /* clientAddressFamily */ - stream_write_UINT16(s, cbClientAddress + 2); /* cbClientAddress */ + Stream_Write_UINT16(s, cbClientAddress + 2); /* cbClientAddress */ if (cbClientAddress > 0) - stream_write(s, clientAddress, cbClientAddress); /* clientAddress */ - stream_write_UINT16(s, 0); + Stream_Write(s, clientAddress, cbClientAddress); /* clientAddress */ + Stream_Write_UINT16(s, 0); - stream_write_UINT16(s, cbClientDir + 2); /* cbClientDir */ + Stream_Write_UINT16(s, cbClientDir + 2); /* cbClientDir */ if (cbClientDir > 0) - stream_write(s, clientDir, cbClientDir); /* clientDir */ - stream_write_UINT16(s, 0); + Stream_Write(s, clientDir, cbClientDir); /* clientDir */ + Stream_Write_UINT16(s, 0); rdp_write_client_time_zone(s, settings); /* clientTimeZone */ - stream_write_UINT32(s, 0); /* clientSessionId, should be set to 0 */ - stream_write_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ + Stream_Write_UINT32(s, 0); /* clientSessionId, should be set to 0 */ + Stream_Write_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ - stream_write_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ + Stream_Write_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ if (cbAutoReconnectLen > 0) rdp_write_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ @@ -234,72 +234,72 @@ BOOL rdp_read_info_packet(wStream* s, rdpSettings* settings) UINT16 cbAlternateShell; UINT16 cbWorkingDir; - if (stream_get_left(s) < 18) // invalid packet + if (Stream_GetRemainingLength(s) < 18) // invalid packet return FALSE; - stream_seek_UINT32(s); /* CodePage */ - stream_read_UINT32(s, flags); /* flags */ + Stream_Seek_UINT32(s); /* CodePage */ + Stream_Read_UINT32(s, flags); /* flags */ settings->AutoLogonEnabled = ((flags & INFO_AUTOLOGON) ? TRUE : FALSE); settings->RemoteApplicationMode = ((flags & INFO_RAIL) ? TRUE : FALSE); settings->RemoteConsoleAudio = ((flags & INFO_REMOTECONSOLEAUDIO) ? TRUE : FALSE); settings->CompressionEnabled = ((flags & INFO_COMPRESSION) ? TRUE : FALSE); - stream_read_UINT16(s, cbDomain); /* cbDomain */ - stream_read_UINT16(s, cbUserName); /* cbUserName */ - stream_read_UINT16(s, cbPassword); /* cbPassword */ - stream_read_UINT16(s, cbAlternateShell); /* cbAlternateShell */ - stream_read_UINT16(s, cbWorkingDir); /* cbWorkingDir */ + Stream_Read_UINT16(s, cbDomain); /* cbDomain */ + Stream_Read_UINT16(s, cbUserName); /* cbUserName */ + Stream_Read_UINT16(s, cbPassword); /* cbPassword */ + Stream_Read_UINT16(s, cbAlternateShell); /* cbAlternateShell */ + Stream_Read_UINT16(s, cbWorkingDir); /* cbWorkingDir */ - if (stream_get_left(s) < cbDomain + 2) + if (Stream_GetRemainingLength(s) < cbDomain + 2) return FALSE; if (cbDomain > 0) { - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbDomain / 2, &settings->Domain, 0, NULL, NULL); - stream_seek(s, cbDomain); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbDomain / 2, &settings->Domain, 0, NULL, NULL); + Stream_Seek(s, cbDomain); } - stream_seek(s, 2); + Stream_Seek(s, 2); - if (stream_get_left(s) < cbUserName + 2) + if (Stream_GetRemainingLength(s) < cbUserName + 2) return FALSE; if (cbUserName > 0) { - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbUserName / 2, &settings->Username, 0, NULL, NULL); - stream_seek(s, cbUserName); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbUserName / 2, &settings->Username, 0, NULL, NULL); + Stream_Seek(s, cbUserName); } - stream_seek(s, 2); + Stream_Seek(s, 2); - if (stream_get_left(s) < cbPassword + 2) + if (Stream_GetRemainingLength(s) < cbPassword + 2) return FALSE; if (cbPassword > 0) { - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbPassword / 2, &settings->Password, 0, NULL, NULL); - stream_seek(s, cbPassword); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbPassword / 2, &settings->Password, 0, NULL, NULL); + Stream_Seek(s, cbPassword); } - stream_seek(s, 2); + Stream_Seek(s, 2); - if (stream_get_left(s) < cbAlternateShell + 2) + if (Stream_GetRemainingLength(s) < cbAlternateShell + 2) return FALSE; if (cbAlternateShell > 0) { - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbAlternateShell / 2, &settings->AlternateShell, 0, NULL, NULL); - stream_seek(s, cbAlternateShell); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbAlternateShell / 2, &settings->AlternateShell, 0, NULL, NULL); + Stream_Seek(s, cbAlternateShell); } - stream_seek(s, 2); + Stream_Seek(s, 2); - if (stream_get_left(s) < cbWorkingDir + 2) + if (Stream_GetRemainingLength(s) < cbWorkingDir + 2) return FALSE; if (cbWorkingDir > 0) { - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbWorkingDir / 2, &settings->ShellWorkingDirectory, 0, NULL, NULL); - stream_seek(s, cbWorkingDir); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbWorkingDir / 2, &settings->ShellWorkingDirectory, 0, NULL, NULL); + Stream_Seek(s, cbWorkingDir); } - stream_seek(s, 2); + Stream_Seek(s, 2); if (settings->RdpVersion >= 5) return rdp_read_extended_info_packet(s, settings); /* extraInfo */ @@ -382,34 +382,34 @@ void rdp_write_info_packet(wStream* s, rdpSettings* settings) cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->ShellWorkingDirectory, -1, &workingDir, 0) * 2; - stream_write_UINT32(s, 0); /* CodePage */ - stream_write_UINT32(s, flags); /* flags */ + Stream_Write_UINT32(s, 0); /* CodePage */ + Stream_Write_UINT32(s, flags); /* flags */ - stream_write_UINT16(s, cbDomain); /* cbDomain */ - stream_write_UINT16(s, cbUserName); /* cbUserName */ - stream_write_UINT16(s, cbPassword); /* cbPassword */ - stream_write_UINT16(s, cbAlternateShell); /* cbAlternateShell */ - stream_write_UINT16(s, cbWorkingDir); /* cbWorkingDir */ + Stream_Write_UINT16(s, cbDomain); /* cbDomain */ + Stream_Write_UINT16(s, cbUserName); /* cbUserName */ + Stream_Write_UINT16(s, cbPassword); /* cbPassword */ + Stream_Write_UINT16(s, cbAlternateShell); /* cbAlternateShell */ + Stream_Write_UINT16(s, cbWorkingDir); /* cbWorkingDir */ if (cbDomain > 0) - stream_write(s, domain, cbDomain); - stream_write_UINT16(s, 0); + Stream_Write(s, domain, cbDomain); + Stream_Write_UINT16(s, 0); if (cbUserName > 0) - stream_write(s, userName, cbUserName); - stream_write_UINT16(s, 0); + Stream_Write(s, userName, cbUserName); + Stream_Write_UINT16(s, 0); if (cbPassword > 0) - stream_write(s, password, cbPassword); - stream_write_UINT16(s, 0); + Stream_Write(s, password, cbPassword); + Stream_Write_UINT16(s, 0); if (cbAlternateShell > 0) - stream_write(s, alternateShell, cbAlternateShell); - stream_write_UINT16(s, 0); + Stream_Write(s, alternateShell, cbAlternateShell); + Stream_Write_UINT16(s, 0); if (cbWorkingDir > 0) - stream_write(s, workingDir, cbWorkingDir); - stream_write_UINT16(s, 0); + Stream_Write(s, workingDir, cbWorkingDir); + Stream_Write_UINT16(s, 0); free(domain); free(userName); @@ -475,12 +475,20 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s) BOOL rdp_send_client_info(rdpRdp* rdp) { wStream* s; + BOOL status; - //rdp->settings->crypt_flags |= SEC_INFO_PKT; rdp->sec_flags |= SEC_INFO_PKT; - s = rdp_send_stream_init(rdp); + + s = Stream_New(NULL, 2048); + rdp_init_stream(rdp, s); + rdp_write_info_packet(s, rdp->settings); - return rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID); + + status = rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID); + + Stream_Free(s, TRUE); + + return status; } BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s) @@ -488,14 +496,14 @@ BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s) UINT32 cbDomain; UINT32 cbUserName; - if (stream_get_left(s) < (4 + 52 + 4 + 512 + 4)) + if (Stream_GetRemainingLength(s) < (4 + 52 + 4 + 512 + 4)) return FALSE; - stream_read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */ - stream_seek(s, 52); /* domain (52 bytes) */ - stream_read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */ - stream_seek(s, 512); /* userName (512 bytes) */ - stream_seek_UINT32(s); /* sessionId (4 bytes) */ + Stream_Read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */ + Stream_Seek(s, 52); /* domain (52 bytes) */ + Stream_Read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */ + Stream_Seek(s, 512); /* userName (512 bytes) */ + Stream_Seek_UINT32(s); /* sessionId (4 bytes) */ return TRUE; } @@ -505,31 +513,31 @@ BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s) UINT32 cbDomain; UINT32 cbUserName; - if (stream_get_left(s) < (2 + 4 + 4 + 4 + 4 + 558)) + if (Stream_GetRemainingLength(s) < (2 + 4 + 4 + 4 + 4 + 558)) return FALSE; - stream_seek_UINT16(s); /* version (2 bytes) */ - stream_seek_UINT32(s); /* size (4 bytes) */ - stream_seek_UINT32(s); /* sessionId (4 bytes) */ - stream_read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */ - stream_read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */ - stream_seek(s, 558); /* pad */ + Stream_Seek_UINT16(s); /* version (2 bytes) */ + Stream_Seek_UINT32(s); /* size (4 bytes) */ + Stream_Seek_UINT32(s); /* sessionId (4 bytes) */ + Stream_Read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */ + Stream_Read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */ + Stream_Seek(s, 558); /* pad */ - if (stream_get_left(s) < cbDomain+cbUserName) + if (Stream_GetRemainingLength(s) < cbDomain+cbUserName) return FALSE; - stream_seek(s, cbDomain); /* domain */ - stream_seek(s, cbUserName); /* userName */ + Stream_Seek(s, cbDomain); /* domain */ + Stream_Seek(s, cbUserName); /* userName */ return TRUE; } BOOL rdp_recv_logon_plain_notify(rdpRdp* rdp, wStream* s) { - if (stream_get_left(s) < 576) + if (Stream_GetRemainingLength(s) < 576) return FALSE; - stream_seek(s, 576); /* pad */ + Stream_Seek(s, 576); /* pad */ return TRUE; } @@ -539,11 +547,11 @@ BOOL rdp_recv_logon_error_info(rdpRdp* rdp, wStream* s) UINT32 errorNotificationData; UINT32 errorNotificationType; - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, errorNotificationData); /* errorNotificationData (4 bytes) */ - stream_read_UINT32(s, errorNotificationType); /* errorNotificationType (4 bytes) */ + Stream_Read_UINT32(s, errorNotificationData); /* errorNotificationData (4 bytes) */ + Stream_Read_UINT32(s, errorNotificationType); /* errorNotificationType (4 bytes) */ IFCALL(rdp->instance->LogonErrorInfo, rdp->instance, errorNotificationData, errorNotificationType); @@ -556,20 +564,20 @@ BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s) UINT32 fieldsPresent; UINT16 Length; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) return FALSE; - stream_read_UINT16(s, Length); /* The total size in bytes of this structure */ - stream_read_UINT32(s, fieldsPresent); /* fieldsPresent (4 bytes) */ + Stream_Read_UINT16(s, Length); /* The total size in bytes of this structure */ + Stream_Read_UINT32(s, fieldsPresent); /* fieldsPresent (4 bytes) */ /* logonFields */ if (fieldsPresent & LOGON_EX_AUTORECONNECTCOOKIE) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */ + Stream_Read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */ if (rdp_read_server_auto_reconnect_cookie(s, rdp->settings) == FALSE) return FALSE; @@ -577,19 +585,19 @@ BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s) if (fieldsPresent & LOGON_EX_LOGONERRORS) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */ + Stream_Read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */ if (rdp_recv_logon_error_info(rdp, s) == FALSE) return FALSE; } - if (stream_get_left(s) < 570) + if (Stream_GetRemainingLength(s) < 570) return FALSE; - stream_seek(s, 570); /* pad */ + Stream_Seek(s, 570); /* pad */ return TRUE; } @@ -598,9 +606,9 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s) { UINT32 infoType; - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, infoType); /* infoType (4 bytes) */ + Stream_Read_UINT32(s, infoType); /* infoType (4 bytes) */ //fprintf(stderr, "%s\n", INFO_TYPE_LOGON_STRINGS[infoType]); diff --git a/libfreerdp/core/input.c b/libfreerdp/core/input.c index 06e31f84d..848a66505 100644 --- a/libfreerdp/core/input.c +++ b/libfreerdp/core/input.c @@ -31,14 +31,14 @@ void rdp_write_client_input_pdu_header(wStream* s, UINT16 number) { - stream_write_UINT16(s, 1); /* numberEvents (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + Stream_Write_UINT16(s, 1); /* numberEvents (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ } void rdp_write_input_event_header(wStream* s, UINT32 time, UINT16 type) { - stream_write_UINT32(s, time); /* eventTime (4 bytes) */ - stream_write_UINT16(s, type); /* messageType (2 bytes) */ + Stream_Write_UINT32(s, time); /* eventTime (4 bytes) */ + Stream_Write_UINT16(s, type); /* messageType (2 bytes) */ } wStream* rdp_client_input_pdu_init(rdpRdp* rdp, UINT16 type) @@ -57,8 +57,8 @@ void rdp_send_client_input_pdu(rdpRdp* rdp, wStream* s) void input_write_synchronize_event(wStream* s, UINT32 flags) { - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ - stream_write_UINT32(s, flags); /* toggleFlags (4 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + Stream_Write_UINT32(s, flags); /* toggleFlags (4 bytes) */ } void input_send_synchronize_event(rdpInput* input, UINT32 flags) @@ -73,9 +73,9 @@ void input_send_synchronize_event(rdpInput* input, UINT32 flags) void input_write_keyboard_event(wStream* s, UINT16 flags, UINT16 code) { - stream_write_UINT16(s, flags); /* keyboardFlags (2 bytes) */ - stream_write_UINT16(s, code); /* keyCode (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + Stream_Write_UINT16(s, flags); /* keyboardFlags (2 bytes) */ + Stream_Write_UINT16(s, code); /* keyCode (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ } void input_send_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) @@ -90,9 +90,9 @@ void input_send_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) void input_write_unicode_keyboard_event(wStream* s, UINT16 flags, UINT16 code) { - stream_write_UINT16(s, flags); /* keyboardFlags (2 bytes) */ - stream_write_UINT16(s, code); /* unicodeCode (2 bytes) */ - stream_write_UINT16(s, 0); /* pad2Octets (2 bytes) */ + Stream_Write_UINT16(s, flags); /* keyboardFlags (2 bytes) */ + Stream_Write_UINT16(s, code); /* unicodeCode (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ } void input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) @@ -119,9 +119,9 @@ void input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 cod void input_write_mouse_event(wStream* s, UINT16 flags, UINT16 x, UINT16 y) { - stream_write_UINT16(s, flags); /* pointerFlags (2 bytes) */ - stream_write_UINT16(s, x); /* xPos (2 bytes) */ - stream_write_UINT16(s, y); /* yPos (2 bytes) */ + Stream_Write_UINT16(s, flags); /* pointerFlags (2 bytes) */ + Stream_Write_UINT16(s, x); /* xPos (2 bytes) */ + Stream_Write_UINT16(s, y); /* yPos (2 bytes) */ } void input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) @@ -136,9 +136,9 @@ void input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) void input_write_extended_mouse_event(wStream* s, UINT16 flags, UINT16 x, UINT16 y) { - stream_write_UINT16(s, flags); /* pointerFlags (2 bytes) */ - stream_write_UINT16(s, x); /* xPos (2 bytes) */ - stream_write_UINT16(s, y); /* yPos (2 bytes) */ + Stream_Write_UINT16(s, flags); /* pointerFlags (2 bytes) */ + Stream_Write_UINT16(s, x); /* xPos (2 bytes) */ + Stream_Write_UINT16(s, y); /* yPos (2 bytes) */ } void input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) @@ -151,6 +151,21 @@ void input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UI rdp_send_client_input_pdu(rdp, s); } +void input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y) +{ + /* send a tab up like mstsc.exe */ + input_send_keyboard_event(input, KBD_FLAGS_RELEASE, 0x0f); + + /* send the toggle key states */ + input_send_synchronize_event(input, (toggleStates & 0x1F)); + + /* send another tab up like mstsc.exe */ + input_send_keyboard_event(input, KBD_FLAGS_RELEASE, 0x0f); + + /* finish with a mouse pointer position like mstsc.exe */ + input_send_extended_mouse_event(input, PTR_FLAGS_MOVE, x, y); +} + void input_send_fastpath_synchronize_event(rdpInput* input, UINT32 flags) { wStream* s; @@ -170,7 +185,7 @@ void input_send_fastpath_keyboard_event(rdpInput* input, UINT16 flags, UINT16 co eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0; eventFlags |= (flags & KBD_FLAGS_EXTENDED) ? FASTPATH_INPUT_KBDFLAGS_EXTENDED : 0; s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_SCANCODE); - stream_write_BYTE(s, code); /* keyCode (1 byte) */ + Stream_Write_UINT8(s, code); /* keyCode (1 byte) */ fastpath_send_input_pdu(rdp->fastpath, s); } @@ -182,7 +197,7 @@ void input_send_fastpath_unicode_keyboard_event(rdpInput* input, UINT16 flags, U eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0; s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_UNICODE); - stream_write_UINT16(s, code); /* unicodeCode (2 bytes) */ + Stream_Write_UINT16(s, code); /* unicodeCode (2 bytes) */ fastpath_send_input_pdu(rdp->fastpath, s); } @@ -206,15 +221,44 @@ void input_send_fastpath_extended_mouse_event(rdpInput* input, UINT16 flags, UIN fastpath_send_input_pdu(rdp->fastpath, s); } +void input_send_fastpath_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y) +{ + wStream* s; + rdpRdp* rdp = input->context->rdp; + BYTE eventFlags = 0; + + s = fastpath_input_pdu_init_header(rdp->fastpath); + /* send a tab up like mstsc.exe */ + eventFlags = FASTPATH_INPUT_KBDFLAGS_RELEASE | FASTPATH_INPUT_EVENT_SCANCODE << 5; + Stream_Write_UINT8(s, eventFlags); /* Key Release event (1 byte) */ + Stream_Write_UINT8(s, 0x0f); /* keyCode (1 byte) */ + + /* send the toggle key states */ + eventFlags = (toggleStates & 0x1F) | FASTPATH_INPUT_EVENT_SYNC << 5; + Stream_Write_UINT8(s, eventFlags); /* toggle state (1 byte) */ + + /* send another tab up like mstsc.exe */ + eventFlags = FASTPATH_INPUT_KBDFLAGS_RELEASE | FASTPATH_INPUT_EVENT_SCANCODE << 5; + Stream_Write_UINT8(s, eventFlags); /* Key Release event (1 byte) */ + Stream_Write_UINT8(s, 0x0f); /* keyCode (1 byte) */ + + /* finish with a mouse pointer position like mstsc.exe */ + eventFlags = 0 | FASTPATH_INPUT_EVENT_MOUSE << 5; + Stream_Write_UINT8(s, eventFlags); /* Mouse Pointer event (1 byte) */ + input_write_extended_mouse_event(s, PTR_FLAGS_MOVE, x, y); + + fastpath_send_multiple_input_pdu(rdp->fastpath, s, 4); +} + static BOOL input_recv_sync_event(rdpInput* input, wStream* s) { UINT32 toggleFlags; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) return FALSE; - stream_seek(s, 2); /* pad2Octets (2 bytes) */ - stream_read_UINT32(s, toggleFlags); /* toggleFlags (4 bytes) */ + Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ + Stream_Read_UINT32(s, toggleFlags); /* toggleFlags (4 bytes) */ IFCALL(input->SynchronizeEvent, input, toggleFlags); @@ -225,12 +269,12 @@ static BOOL input_recv_keyboard_event(rdpInput* input, wStream* s) { UINT16 keyboardFlags, keyCode; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) return FALSE; - stream_read_UINT16(s, keyboardFlags); /* keyboardFlags (2 bytes) */ - stream_read_UINT16(s, keyCode); /* keyCode (2 bytes) */ - stream_seek(s, 2); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, keyboardFlags); /* keyboardFlags (2 bytes) */ + Stream_Read_UINT16(s, keyCode); /* keyCode (2 bytes) */ + Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ IFCALL(input->KeyboardEvent, input, keyboardFlags, keyCode); @@ -241,12 +285,12 @@ static BOOL input_recv_unicode_keyboard_event(rdpInput* input, wStream* s) { UINT16 keyboardFlags, unicodeCode; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) return FALSE; - stream_read_UINT16(s, keyboardFlags); /* keyboardFlags (2 bytes) */ - stream_read_UINT16(s, unicodeCode); /* unicodeCode (2 bytes) */ - stream_seek(s, 2); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, keyboardFlags); /* keyboardFlags (2 bytes) */ + Stream_Read_UINT16(s, unicodeCode); /* unicodeCode (2 bytes) */ + Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ /* * According to the specification, the slow path Unicode Keyboard Event @@ -270,12 +314,12 @@ static BOOL input_recv_mouse_event(rdpInput* input, wStream* s) { UINT16 pointerFlags, xPos, yPos; - if (stream_get_left(s) < 6) + 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) */ + 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(input->MouseEvent, input, pointerFlags, xPos, yPos); @@ -286,12 +330,12 @@ static BOOL input_recv_extended_mouse_event(rdpInput* input, wStream* s) { UINT16 pointerFlags, xPos, yPos; - if (stream_get_left(s) < 6) + 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) */ + 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(input->ExtendedMouseEvent, input, pointerFlags, xPos, yPos); @@ -302,11 +346,11 @@ static BOOL input_recv_event(rdpInput* input, wStream* s) { UINT16 messageType; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) return FALSE; - stream_seek(s, 4); /* eventTime (4 bytes), ignored by the server */ - stream_read_UINT16(s, messageType); /* messageType (2 bytes) */ + Stream_Seek(s, 4); /* eventTime (4 bytes), ignored by the server */ + Stream_Read_UINT16(s, messageType); /* messageType (2 bytes) */ switch (messageType) { @@ -338,7 +382,7 @@ static BOOL input_recv_event(rdpInput* input, wStream* s) default: fprintf(stderr, "Unknown messageType %u\n", messageType); /* Each input event uses 6 bytes. */ - stream_seek(s, 6); + Stream_Seek(s, 6); break; } @@ -349,14 +393,14 @@ BOOL input_recv(rdpInput* input, wStream* s) { UINT16 i, numberEvents; - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT16(s, numberEvents); /* numberEvents (2 bytes) */ - stream_seek(s, 2); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, numberEvents); /* numberEvents (2 bytes) */ + Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ /* Each input event uses 6 exactly bytes. */ - if (stream_get_left(s) < 6 * numberEvents) + if (Stream_GetRemainingLength(s) < 6 * numberEvents) return FALSE; for (i = 0; i < numberEvents; i++) @@ -379,6 +423,7 @@ void input_register_client_callbacks(rdpInput* input) input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event; input->MouseEvent = input_send_fastpath_mouse_event; input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event; + input->FocusInEvent = input_send_fastpath_focus_in_event; } else { @@ -387,6 +432,7 @@ void input_register_client_callbacks(rdpInput* input) input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event; input->MouseEvent = input_send_mouse_event; input->ExtendedMouseEvent = input_send_extended_mouse_event; + input->FocusInEvent = input_send_focus_in_event; } input->asynchronous = settings->AsyncInput; @@ -430,6 +476,11 @@ void freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT IFCALL(input->ExtendedMouseEvent, input, flags, x, y); } +void freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y) +{ + IFCALL(input->FocusInEvent, input, toggleStates, x, y); +} + int input_process_events(rdpInput* input) { return input_message_queue_process_pending_messages(input); diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index be43a21ca..b98d41e9a 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -126,12 +126,12 @@ void license_print_scope_list(SCOPE_LIST* scopeList) BOOL license_read_preamble(wStream* s, BYTE* bMsgType, BYTE* flags, UINT16* wMsgSize) { /* preamble (4 bytes) */ - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_BYTE(s, *bMsgType); /* bMsgType (1 byte) */ - stream_read_BYTE(s, *flags); /* flags (1 byte) */ - stream_read_UINT16(s, *wMsgSize); /* wMsgSize (2 bytes) */ + Stream_Read_UINT8(s, *bMsgType); /* bMsgType (1 byte) */ + Stream_Read_UINT8(s, *flags); /* flags (1 byte) */ + Stream_Read_UINT16(s, *wMsgSize); /* wMsgSize (2 bytes) */ return TRUE; } @@ -148,9 +148,9 @@ BOOL license_read_preamble(wStream* s, BYTE* bMsgType, BYTE* flags, UINT16* wMsg void license_write_preamble(wStream* s, BYTE bMsgType, BYTE flags, UINT16 wMsgSize) { /* preamble (4 bytes) */ - stream_write_BYTE(s, bMsgType); /* bMsgType (1 byte) */ - stream_write_BYTE(s, flags); /* flags (1 byte) */ - stream_write_UINT16(s, wMsgSize); /* wMsgSize (2 bytes) */ + Stream_Write_UINT8(s, bMsgType); /* bMsgType (1 byte) */ + Stream_Write_UINT8(s, flags); /* flags (1 byte) */ + Stream_Write_UINT16(s, wMsgSize); /* wMsgSize (2 bytes) */ } /** @@ -163,8 +163,8 @@ wStream* license_send_stream_init(rdpLicense* license) { wStream* s; - s = transport_send_stream_init(license->rdp->transport, 4096); - stream_seek(s, LICENSE_PACKET_HEADER_MAX_LENGTH); + s = Stream_New(NULL, 4096); + Stream_Seek(s, LICENSE_PACKET_HEADER_MAX_LENGTH); return s; } @@ -185,8 +185,8 @@ BOOL license_send(rdpLicense* license, wStream* s, BYTE type) DEBUG_LICENSE("Sending %s Packet", LICENSE_MESSAGE_STRINGS[type & 0x1F]); - length = stream_get_length(s); - stream_set_pos(s, 0); + length = Stream_GetPosition(s); + Stream_SetPosition(s, 0); sec_flags = SEC_LICENSE_PKT; wMsgSize = length - LICENSE_PACKET_HEADER_MAX_LENGTH + 4; @@ -203,14 +203,17 @@ BOOL license_send(rdpLicense* license, wStream* s, BYTE type) #ifdef WITH_DEBUG_LICENSE fprintf(stderr, "Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize); - winpr_HexDump(s->pointer - 4, wMsgSize); + winpr_HexDump(Stream_Pointer(s) - 4, wMsgSize); #endif - stream_set_pos(s, length); + Stream_SetPosition(s, length); + Stream_SealLength(s); if (transport_write(license->rdp->transport, s) < 0) return FALSE; + Stream_Free(s, TRUE); + return TRUE; } @@ -252,7 +255,7 @@ BOOL license_recv(rdpLicense* license, wStream* s) if (!(securityFlags & SEC_LICENSE_PKT)) { if (!(securityFlags & SEC_ENCRYPT)) - stream_rewind(s, RDP_SECURITY_HEADER_LENGTH); + Stream_Rewind(s, RDP_SECURITY_HEADER_LENGTH); if (rdp_recv_out_of_sequence_pdu(license->rdp, s) != TRUE) { @@ -463,22 +466,22 @@ void license_decrypt_platform_challenge(rdpLicense* license) BOOL license_read_product_info(wStream* s, PRODUCT_INFO* productInfo) { - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */ + Stream_Read_UINT32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */ - stream_read_UINT32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */ + Stream_Read_UINT32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */ - if (stream_get_left(s) < productInfo->cbCompanyName + 4) + if (Stream_GetRemainingLength(s) < productInfo->cbCompanyName + 4) return FALSE; productInfo->pbCompanyName = (BYTE*) malloc(productInfo->cbCompanyName); - stream_read(s, productInfo->pbCompanyName, productInfo->cbCompanyName); + Stream_Read(s, productInfo->pbCompanyName, productInfo->cbCompanyName); - stream_read_UINT32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */ + Stream_Read_UINT32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */ - if (stream_get_left(s) < productInfo->cbProductId) + if (Stream_GetRemainingLength(s) < productInfo->cbProductId) { free(productInfo->pbCompanyName); productInfo->pbCompanyName = NULL; @@ -486,7 +489,7 @@ BOOL license_read_product_info(wStream* s, PRODUCT_INFO* productInfo) } productInfo->pbProductId = (BYTE*) malloc(productInfo->cbProductId); - stream_read(s, productInfo->pbProductId, productInfo->cbProductId); + Stream_Read(s, productInfo->pbProductId, productInfo->cbProductId); return TRUE; } @@ -540,13 +543,13 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob) { UINT16 wBlobType; - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT16(s, wBlobType); /* wBlobType (2 bytes) */ - stream_read_UINT16(s, blob->length); /* wBlobLen (2 bytes) */ + Stream_Read_UINT16(s, wBlobType); /* wBlobType (2 bytes) */ + Stream_Read_UINT16(s, blob->length); /* wBlobLen (2 bytes) */ - if (stream_get_left(s) < blob->length) + if (Stream_GetRemainingLength(s) < blob->length) return FALSE; /* @@ -564,7 +567,7 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob) blob->type = wBlobType; blob->data = (BYTE*) malloc(blob->length); - stream_read(s, blob->data, blob->length); /* blobData */ + Stream_Read(s, blob->data, blob->length); /* blobData */ return TRUE; } @@ -577,11 +580,13 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob) void license_write_binary_blob(wStream* s, LICENSE_BLOB* blob) { - stream_write_UINT16(s, blob->type); /* wBlobType (2 bytes) */ - stream_write_UINT16(s, blob->length); /* wBlobLen (2 bytes) */ + Stream_EnsureRemainingCapacity(s, blob->length + 4); + + Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */ + Stream_Write_UINT16(s, blob->length); /* wBlobLen (2 bytes) */ if (blob->length > 0) - stream_write(s, blob->data, blob->length); /* blobData */ + Stream_Write(s, blob->data, blob->length); /* blobData */ } void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob, UINT32 ModulusLength) @@ -596,13 +601,15 @@ void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blo return; } - stream_write_UINT16(s, blob->type); /* wBlobType (2 bytes) */ - stream_write_UINT16(s, length); /* wBlobLen (2 bytes) */ + Stream_EnsureRemainingCapacity(s, length + 4); + + Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */ + Stream_Write_UINT16(s, length); /* wBlobLen (2 bytes) */ if (blob->length > 0) - stream_write(s, blob->data, blob->length); /* blobData */ + Stream_Write(s, blob->data, blob->length); /* blobData */ - stream_write_zero(s, length - blob->length); + Stream_Zero(s, length - blob->length); } /** @@ -649,10 +656,10 @@ BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList) UINT32 i; UINT32 scopeCount; - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, scopeCount); /* ScopeCount (4 bytes) */ + Stream_Read_UINT32(s, scopeCount); /* ScopeCount (4 bytes) */ scopeList->count = scopeCount; scopeList->array = (LICENSE_BLOB*) malloc(sizeof(LICENSE_BLOB) * scopeCount); @@ -722,10 +729,10 @@ void license_free_scope_list(SCOPE_LIST* scopeList) BOOL license_read_license_request_packet(rdpLicense* license, wStream* s) { /* ServerRandom (32 bytes) */ - if (stream_get_left(s) < 32) + if (Stream_GetRemainingLength(s) < 32) return FALSE; - stream_read(s, license->ServerRandom, 32); + Stream_Read(s, license->ServerRandom, 32); /* ProductInfo */ if (!license_read_product_info(s, license->ProductInfo)) @@ -781,20 +788,20 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s) DEBUG_LICENSE("Receiving Platform Challenge Packet"); - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, ConnectFlags); /* ConnectFlags, Reserved (4 bytes) */ + Stream_Read_UINT32(s, ConnectFlags); /* ConnectFlags, Reserved (4 bytes) */ /* EncryptedPlatformChallenge */ license->EncryptedPlatformChallenge->type = BB_ANY_BLOB; license_read_binary_blob(s, license->EncryptedPlatformChallenge); license->EncryptedPlatformChallenge->type = BB_ENCRYPTED_DATA_BLOB; - if (stream_get_left(s) < 16) + if (Stream_GetRemainingLength(s) < 16) return FALSE; - stream_read(s, MacData, 16); /* MACData (16 bytes) */ + Stream_Read(s, MacData, 16); /* MACData (16 bytes) */ license_decrypt_platform_challenge(license); @@ -856,11 +863,11 @@ BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s) UINT32 dwErrorCode; UINT32 dwStateTransition; - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, dwErrorCode); /* dwErrorCode (4 bytes) */ - stream_read_UINT32(s, dwStateTransition); /* dwStateTransition (4 bytes) */ + Stream_Read_UINT32(s, dwErrorCode); /* dwErrorCode (4 bytes) */ + Stream_Read_UINT32(s, dwStateTransition); /* dwStateTransition (4 bytes) */ if (!license_read_binary_blob(s, license->ErrorInfo)) /* bbErrorInfo */ return FALSE; @@ -914,9 +921,9 @@ void license_write_new_license_request_packet(rdpLicense* license, wStream* s) PlatformId = CLIENT_OS_ID_WINNT_POST_52 | CLIENT_IMAGE_ID_MICROSOFT; - stream_write_UINT32(s, PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */ - stream_write_UINT32(s, PlatformId); /* PlatformId (4 bytes) */ - stream_write(s, license->ClientRandom, 32); /* ClientRandom (32 bytes) */ + Stream_Write_UINT32(s, PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */ + Stream_Write_UINT32(s, PlatformId); /* PlatformId (4 bytes) */ + Stream_Write(s, license->ClientRandom, 32); /* ClientRandom (32 bytes) */ license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret, license->ModulusLength); /* EncryptedPremasterSecret */ license_write_binary_blob(s, license->ClientUserName); /* ClientUserName */ license_write_binary_blob(s, license->ClientMachineName); /* ClientMachineName */ @@ -990,7 +997,9 @@ void license_write_platform_challenge_response_packet(rdpLicense* license, wStre { license_write_binary_blob(s, license->EncryptedPlatformChallenge); /* EncryptedPlatformChallengeResponse */ license_write_binary_blob(s, license->EncryptedHardwareId); /* EncryptedHWID */ - stream_write(s, macData, 16); /* MACData */ + + Stream_EnsureRemainingCapacity(s, 16); + Stream_Write(s, macData, 16); /* MACData */ } /** @@ -1062,8 +1071,8 @@ BOOL license_send_valid_client_error_packet(rdpLicense* license) DEBUG_LICENSE("Sending Error Alert Packet"); - stream_write_UINT32(s, STATUS_VALID_CLIENT); /* dwErrorCode */ - stream_write_UINT32(s, ST_NO_TRANSITION); /* dwStateTransition */ + Stream_Write_UINT32(s, STATUS_VALID_CLIENT); /* dwErrorCode */ + Stream_Write_UINT32(s, ST_NO_TRANSITION); /* dwStateTransition */ license_write_binary_blob(s, license->ErrorInfo); diff --git a/libfreerdp/core/mcs.c b/libfreerdp/core/mcs.c index 560df65e1..d5ea0899b 100644 --- a/libfreerdp/core/mcs.c +++ b/libfreerdp/core/mcs.c @@ -261,6 +261,7 @@ static void mcs_init_domain_parameters(DomainParameters* domainParameters, BOOL mcs_read_domain_parameters(wStream* s, DomainParameters* domainParameters) { int length; + return ber_read_sequence_tag(s, &length) && ber_read_integer(s, &(domainParameters->maxChannelIds)) && @@ -284,7 +285,7 @@ void mcs_write_domain_parameters(wStream* s, DomainParameters* domainParameters) int length; wStream* tmps; - tmps = stream_new(stream_get_size(s)); + tmps = Stream_New(NULL, Stream_Capacity(s)); ber_write_integer(tmps, domainParameters->maxChannelIds); ber_write_integer(tmps, domainParameters->maxUserIds); ber_write_integer(tmps, domainParameters->maxTokenIds); @@ -294,10 +295,10 @@ void mcs_write_domain_parameters(wStream* s, DomainParameters* domainParameters) ber_write_integer(tmps, domainParameters->maxMCSPDUsize); ber_write_integer(tmps, domainParameters->protocolVersion); - length = stream_get_length(tmps); + length = Stream_GetPosition(tmps); ber_write_sequence_tag(s, length); - stream_write(s, stream_get_head(tmps), length); - stream_free(tmps); + Stream_Write(s, Stream_Buffer(tmps), length); + Stream_Free(tmps, TRUE); } /** @@ -341,14 +342,14 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s) return FALSE; /* callingDomainSelector (OCTET_STRING) */ - if (!ber_read_octet_string_tag(s, &length) || stream_get_left(s) < length) + if (!ber_read_octet_string_tag(s, &length) || Stream_GetRemainingLength(s) < length) return FALSE; - stream_seek(s, length); + Stream_Seek(s, length); /* calledDomainSelector (OCTET_STRING) */ - if (!ber_read_octet_string_tag(s, &length) || stream_get_left(s) < length) + if (!ber_read_octet_string_tag(s, &length) || Stream_GetRemainingLength(s) < length) return FALSE; - stream_seek(s, length); + Stream_Seek(s, length); /* upwardFlag (BOOLEAN) */ if (!ber_read_BOOL(s, &upwardFlag)) @@ -366,7 +367,7 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s) if(!mcs_read_domain_parameters(s, &mcs->maximumParameters)) return FALSE; - if (!ber_read_octet_string_tag(s, &length) || stream_get_left(s) < length) + if (!ber_read_octet_string_tag(s, &length) || Stream_GetRemainingLength(s) < length) return FALSE; if (!gcc_read_conference_create_request(s, mcs->transport->settings)) @@ -388,7 +389,7 @@ void mcs_write_connect_initial(wStream* s, rdpMcs* mcs, wStream* user_data) int length; wStream* tmps; - tmps = stream_new(stream_get_size(s)); + tmps = Stream_New(NULL, Stream_Capacity(s)); /* callingDomainSelector (OCTET_STRING) */ ber_write_octet_string(tmps, callingDomainSelector, sizeof(callingDomainSelector)); @@ -409,13 +410,13 @@ void mcs_write_connect_initial(wStream* s, rdpMcs* mcs, wStream* user_data) mcs_write_domain_parameters(tmps, &mcs->maximumParameters); /* userData (OCTET_STRING) */ - ber_write_octet_string(tmps, user_data->buffer, stream_get_length(user_data)); + ber_write_octet_string(tmps, user_data->buffer, Stream_GetPosition(user_data)); - length = stream_get_length(tmps); + length = Stream_GetPosition(tmps); /* Connect-Initial (APPLICATION 101, IMPLICIT SEQUENCE) */ ber_write_application_tag(s, MCS_TYPE_CONNECT_INITIAL, length); - stream_write(s, stream_get_head(tmps), length); - stream_free(tmps); + Stream_Write(s, Stream_Buffer(tmps), length); + Stream_Free(tmps, TRUE); } /** @@ -431,18 +432,18 @@ void mcs_write_connect_response(wStream* s, rdpMcs* mcs, wStream* user_data) int length; wStream* tmps; - tmps = stream_new(stream_get_size(s)); + tmps = Stream_New(NULL, Stream_Capacity(s)); ber_write_enumerated(tmps, 0, MCS_Result_enum_length); ber_write_integer(tmps, 0); /* calledConnectId */ mcs->domainParameters = mcs->targetParameters; mcs_write_domain_parameters(tmps, &(mcs->domainParameters)); /* userData (OCTET_STRING) */ - ber_write_octet_string(tmps, user_data->buffer, stream_get_length(user_data)); + ber_write_octet_string(tmps, user_data->buffer, Stream_GetPosition(user_data)); - length = stream_get_length(tmps); + length = Stream_GetPosition(tmps); ber_write_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, length); - stream_write(s, stream_get_head(tmps), length); - stream_free(tmps); + Stream_Write(s, Stream_Buffer(tmps), length); + Stream_Free(tmps, TRUE); } /** @@ -453,37 +454,40 @@ void mcs_write_connect_response(wStream* s, rdpMcs* mcs, wStream* user_data) BOOL mcs_send_connect_initial(rdpMcs* mcs) { - wStream* s; + int status; int length; - BYTE *bm, *em; + wStream* s; + int bm, em; wStream* gcc_CCrq; wStream* client_data; - int status; - client_data = stream_new(512); + client_data = Stream_New(NULL, 512); gcc_write_client_data_blocks(client_data, mcs->transport->settings); - gcc_CCrq = stream_new(512); + gcc_CCrq = Stream_New(NULL, 512); gcc_write_conference_create_request(gcc_CCrq, client_data); - length = stream_get_length(gcc_CCrq) + 7; + length = Stream_GetPosition(gcc_CCrq) + 7; - s = transport_send_stream_init(mcs->transport, 1024); - stream_get_mark(s, bm); - stream_seek(s, 7); + s = Stream_New(NULL, 1024 + length); + + bm = Stream_GetPosition(s); + Stream_Seek(s, 7); mcs_write_connect_initial(s, mcs, gcc_CCrq); - stream_get_mark(s, em); + em = Stream_GetPosition(s); length = (em - bm); - stream_set_mark(s, bm); + Stream_SetPosition(s, bm); tpkt_write_header(s, length); tpdu_write_data(s); - stream_set_mark(s, em); + Stream_SetPosition(s, em); + Stream_SealLength(s); status = transport_write(mcs->transport, s); - stream_free(gcc_CCrq); - stream_free(client_data); + Stream_Free(s, TRUE); + Stream_Free(gcc_CCrq, TRUE); + Stream_Free(client_data, TRUE); return (status < 0 ? FALSE : TRUE); } @@ -532,39 +536,42 @@ BOOL mcs_recv_connect_response(rdpMcs* mcs, wStream* s) BOOL mcs_send_connect_response(rdpMcs* mcs) { - wStream* s; int length; - int ret; - BYTE *bm, *em; + int status; + wStream* s; + int bm, em; wStream* gcc_CCrsp; wStream* server_data; - server_data = stream_new(512); + server_data = Stream_New(NULL, 512); gcc_write_server_data_blocks(server_data, mcs->transport->settings); - gcc_CCrsp = stream_new(512); + gcc_CCrsp = Stream_New(NULL, 512); gcc_write_conference_create_response(gcc_CCrsp, server_data); - length = stream_get_length(gcc_CCrsp) + 7; + length = Stream_GetPosition(gcc_CCrsp) + 7; - s = transport_send_stream_init(mcs->transport, 1024); - stream_get_mark(s, bm); - stream_seek(s, 7); + s = Stream_New(NULL, length + 1024); + + bm = Stream_GetPosition(s); + Stream_Seek(s, 7); mcs_write_connect_response(s, mcs, gcc_CCrsp); - stream_get_mark(s, em); + em = Stream_GetPosition(s); length = (em - bm); - stream_set_mark(s, bm); + Stream_SetPosition(s, bm); tpkt_write_header(s, length); tpdu_write_data(s); - stream_set_mark(s, em); + Stream_SetPosition(s, em); + Stream_SealLength(s); - ret = transport_write(mcs->transport, s); + status = transport_write(mcs->transport, s); - stream_free(gcc_CCrsp); - stream_free(server_data); + Stream_Free(s, TRUE); + Stream_Free(gcc_CCrsp, TRUE); + Stream_Free(server_data, TRUE); - return (ret < 0) ? FALSE : TRUE; + return (status < 0) ? FALSE : TRUE; } /** @@ -580,6 +587,7 @@ BOOL mcs_recv_erect_domain_request(rdpMcs* mcs, wStream* s) enum DomainMCSPDU MCSPDU; MCSPDU = DomainMCSPDU_ErectDomainRequest; + return mcs_read_domain_mcspdu_header(s, &MCSPDU, &length); } @@ -592,18 +600,23 @@ BOOL mcs_recv_erect_domain_request(rdpMcs* mcs, wStream* s) BOOL mcs_send_erect_domain_request(rdpMcs* mcs) { wStream* s; + int status; UINT16 length = 12; - s = transport_send_stream_init(mcs->transport, length); + + s = Stream_New(NULL, length); mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ErectDomainRequest, length, 0); per_write_integer(s, 0); /* subHeight (INTEGER) */ per_write_integer(s, 0); /* subInterval (INTEGER) */ - if (transport_write(mcs->transport, s) < 0) - return FALSE; + Stream_SealLength(s); - return TRUE; + status = transport_write(mcs->transport, s); + + Stream_Free(s, TRUE); + + return (status < 0) ? FALSE : TRUE; } /** @@ -619,6 +632,7 @@ BOOL mcs_recv_attach_user_request(rdpMcs* mcs, wStream* s) enum DomainMCSPDU MCSPDU; MCSPDU = DomainMCSPDU_AttachUserRequest; + return mcs_read_domain_mcspdu_header(s, &MCSPDU, &length); } @@ -631,15 +645,20 @@ BOOL mcs_recv_attach_user_request(rdpMcs* mcs, wStream* s) BOOL mcs_send_attach_user_request(rdpMcs* mcs) { wStream* s; + int status; UINT16 length = 8; - s = transport_send_stream_init(mcs->transport, length); + + s = Stream_New(NULL, length); mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserRequest, length, 0); - if (transport_write(mcs->transport, s) < 0) - return FALSE; + Stream_SealLength(s); - return TRUE; + status = transport_write(mcs->transport, s); + + Stream_Free(s, TRUE); + + return (status < 0) ? FALSE : TRUE; } /** @@ -655,6 +674,7 @@ BOOL mcs_recv_attach_user_confirm(rdpMcs* mcs, wStream* s) enum DomainMCSPDU MCSPDU; MCSPDU = DomainMCSPDU_AttachUserConfirm; + return mcs_read_domain_mcspdu_header(s, &MCSPDU, &length) && per_read_enumerated(s, &result, MCS_Result_enum_length) && /* result */ @@ -670,9 +690,10 @@ BOOL mcs_recv_attach_user_confirm(rdpMcs* mcs, wStream* s) BOOL mcs_send_attach_user_confirm(rdpMcs* mcs) { wStream* s; + int status; UINT16 length = 11; - s = transport_send_stream_init(mcs->transport, length); + s = Stream_New(NULL, length); mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserConfirm, length, 2); @@ -680,9 +701,13 @@ BOOL mcs_send_attach_user_confirm(rdpMcs* mcs) mcs->user_id = MCS_GLOBAL_CHANNEL_ID + 1 + mcs->transport->settings->ChannelCount; per_write_integer16(s, mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ - transport_write(mcs->transport, s); + Stream_SealLength(s); - return TRUE; + status = transport_write(mcs->transport, s); + + Stream_Free(s, TRUE); + + return (status < 0) ? FALSE : TRUE; } /** @@ -699,6 +724,7 @@ BOOL mcs_recv_channel_join_request(rdpMcs* mcs, wStream* s, UINT16* channel_id) UINT16 user_id; MCSPDU = DomainMCSPDU_ChannelJoinRequest; + return mcs_read_domain_mcspdu_header(s, &MCSPDU, &length) && per_read_integer16(s, &user_id, MCS_BASE_CHANNEL_ID) && @@ -716,18 +742,23 @@ BOOL mcs_recv_channel_join_request(rdpMcs* mcs, wStream* s, UINT16* channel_id) BOOL mcs_send_channel_join_request(rdpMcs* mcs, UINT16 channel_id) { wStream* s; + int status; UINT16 length = 12; - s = transport_send_stream_init(mcs->transport, 12); + + s = Stream_New(NULL, length); mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinRequest, length, 0); per_write_integer16(s, mcs->user_id, MCS_BASE_CHANNEL_ID); per_write_integer16(s, channel_id, 0); - if (transport_write(mcs->transport, s) < 0) - return FALSE; + Stream_SealLength(s); - return TRUE; + status = transport_write(mcs->transport, s); + + Stream_Free(s, TRUE); + + return (status < 0) ? FALSE : TRUE; } /** @@ -766,8 +797,10 @@ BOOL mcs_recv_channel_join_confirm(rdpMcs* mcs, wStream* s, UINT16* channel_id) BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channel_id) { wStream* s; + int status; UINT16 length = 15; - s = transport_send_stream_init(mcs->transport, 15); + + s = Stream_New(NULL, length); mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinConfirm, length, 2); @@ -776,9 +809,13 @@ BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channel_id) per_write_integer16(s, channel_id, 0); /* requested (ChannelId) */ per_write_integer16(s, channel_id, 0); /* channelId */ - transport_write(mcs->transport, s); + Stream_SealLength(s); - return TRUE; + status = transport_write(mcs->transport, s); + + Stream_Free(s, TRUE); + + return (status < 0) ? FALSE : TRUE; } /** @@ -789,16 +826,20 @@ BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channel_id) BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs) { wStream* s; + int status; UINT16 length = 9; - s = transport_send_stream_init(mcs->transport, 9); + + s = Stream_New(NULL, length); mcs_write_domain_mcspdu_header(s, DomainMCSPDU_DisconnectProviderUltimatum, length, 1); per_write_enumerated(s, 0, 0); /* reason */ - transport_write(mcs->transport, s); + status = transport_write(mcs->transport, s); - return TRUE; + Stream_Free(s, TRUE); + + return (status < 0) ? FALSE : TRUE; } /** diff --git a/libfreerdp/core/message.c b/libfreerdp/core/message.c index 3e2900b03..720b13797 100644 --- a/libfreerdp/core/message.c +++ b/libfreerdp/core/message.c @@ -21,11 +21,18 @@ #include "config.h" #endif +#include "rdp.h" #include "message.h" +#include "transport.h" + +#include <freerdp/freerdp.h> #include <winpr/crt.h> +#include <winpr/stream.h> #include <winpr/collections.h> +#define WITH_STREAM_POOL 1 + /* Update */ static void update_message_BeginPaint(rdpContext* context) @@ -79,13 +86,15 @@ static void update_message_BitmapUpdate(rdpContext* context, BITMAP_UPDATE* bitm wParam->rectangles = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * wParam->number); CopyMemory(wParam->rectangles, bitmap->rectangles, sizeof(BITMAP_DATA) * wParam->number); - /* TODO: increment reference count to original stream instead of copying */ - for (index = 0; index < wParam->number; index++) { +#ifdef WITH_STREAM_POOL + StreamPool_AddRef(context->rdp->transport->ReceivePool, bitmap->rectangles[index].bitmapDataStream); +#else wParam->rectangles[index].bitmapDataStream = (BYTE*) malloc(wParam->rectangles[index].bitmapLength); CopyMemory(wParam->rectangles[index].bitmapDataStream, bitmap->rectangles[index].bitmapDataStream, wParam->rectangles[index].bitmapLength); +#endif } MessageQueue_Post(context->update->queue, (void*) context, @@ -145,7 +154,7 @@ static void update_message_SurfaceCommand(rdpContext* context, wStream* s) wParam = (wStream*) malloc(sizeof(wStream)); - wParam->capacity = s->capacity; + wParam->capacity = Stream_Capacity(s); wParam->buffer = (BYTE*) malloc(wParam->capacity); wParam->pointer = wParam->buffer; @@ -160,8 +169,12 @@ static void update_message_SurfaceBits(rdpContext* context, SURFACE_BITS_COMMAND wParam = (SURFACE_BITS_COMMAND*) malloc(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); CopyMemory(wParam->bitmapData, surfaceBitsCommand->bitmapData, wParam->bitmapDataLength); +#endif MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, SurfaceBits), (void*) wParam, NULL); @@ -952,7 +965,14 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in BITMAP_UPDATE* wParam = (BITMAP_UPDATE*) msg->wParam; for (index = 0; index < wParam->number; index++) + { +#ifdef WITH_STREAM_POOL + rdpContext* context = (rdpContext*) msg->context; + StreamPool_Release(context->rdp->transport->ReceivePool, wParam->rectangles[index].bitmapDataStream); +#else free(wParam->rectangles[index].bitmapDataStream); +#endif + } free(wParam); } @@ -985,17 +1005,22 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in IFCALL(proxy->SurfaceCommand, msg->context, (wStream*) msg->wParam); { wStream* s = (wStream*) msg->wParam; - free(s->buffer); - free(s); + Stream_Free(s, TRUE); } break; case Update_SurfaceBits: IFCALL(proxy->SurfaceBits, msg->context, (SURFACE_BITS_COMMAND*) msg->wParam); { +#ifdef WITH_STREAM_POOL + rdpContext* context = (rdpContext*) msg->context; + SURFACE_BITS_COMMAND* wParam = (SURFACE_BITS_COMMAND*) msg->wParam; + StreamPool_Release(context->rdp->transport->ReceivePool, wParam->bitmapData); +#else SURFACE_BITS_COMMAND* wParam = (SURFACE_BITS_COMMAND*) msg->wParam; free(wParam->bitmapData); free(wParam); +#endif } break; @@ -1495,22 +1520,6 @@ int update_message_queue_process_message(rdpUpdate* update, wMessage* message) if (message->id == WMQ_QUIT) return 0; - /** - * FIXME: - * - * Certain messages like RefreshRect, SuppressOutput and SurfaceFrameAcknowledge - * and not really output but really input events that send a message to the server. - * Right now they will race with other code making use of the transport layer. - */ - - switch (message->id) - { - case FREERDP_UPDATE_REFRESH_RECT: - case FREERDP_UPDATE_SUPPRESS_OUTPUT: - case FREERDP_UPDATE_SURFACE_FRAME_ACKNOWLEDGE: - return 1; - } - msgClass = GetMessageClass(message->id); msgType = GetMessageType(message->id); diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index 6ee58d9b7..115c1f683 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -276,22 +276,27 @@ BOOL nego_send_preconnection_pdu(rdpNego* nego) cbSize += cchPCB * 2; } - s = transport_send_stream_init(nego->transport, cbSize); - stream_write_UINT32(s, cbSize); /* cbSize */ - stream_write_UINT32(s, 0); /* Flags */ - stream_write_UINT32(s, PRECONNECTION_PDU_V2); /* Version */ - stream_write_UINT32(s, nego->preconnection_id); /* Id */ - stream_write_UINT16(s, cchPCB); /* cchPCB */ + s = Stream_New(NULL, cbSize); + + Stream_Write_UINT32(s, cbSize); /* cbSize */ + Stream_Write_UINT32(s, 0); /* Flags */ + Stream_Write_UINT32(s, PRECONNECTION_PDU_V2); /* Version */ + Stream_Write_UINT32(s, nego->preconnection_id); /* Id */ + Stream_Write_UINT16(s, cchPCB); /* cchPCB */ if (wszPCB) { - stream_write(s, wszPCB, cchPCB * 2); /* wszPCB */ + Stream_Write(s, wszPCB, cchPCB * 2); /* wszPCB */ free(wszPCB); } + Stream_SealLength(s); + if (transport_write(nego->transport, s) < 0) return FALSE; + Stream_Free(s, TRUE); + return TRUE; } @@ -462,12 +467,28 @@ void nego_attempt_rdp(rdpNego* nego) BOOL nego_recv_response(rdpNego* nego) { - wStream* s = transport_recv_stream_init(nego->transport, 1024); + int status; + wStream* s; - if (transport_read(nego->transport, s) < 0) + s = Stream_New(NULL, 1024); + + status = transport_read(nego->transport, s); + + if (status < 0) + { + Stream_Free(s, TRUE); return FALSE; + } - return ((nego_recv(nego->transport, s, nego) < 0) ? FALSE : TRUE); + status = nego_recv(nego->transport, s, nego); + + if (status < 0) + { + Stream_Free(s, TRUE); + return FALSE; + } + + return TRUE; } /** @@ -490,14 +511,14 @@ int nego_recv(rdpTransport* transport, wStream* s, void* extra) if (length == 0) return -1; - if(!tpdu_read_connection_confirm(s, &li)) + if (!tpdu_read_connection_confirm(s, &li)) return -1; if (li > 6) { /* rdpNegData (optional) */ - stream_read_BYTE(s, type); /* Type */ + Stream_Read_UINT8(s, type); /* Type */ switch (type) { @@ -563,40 +584,41 @@ BOOL nego_read_request(rdpNego* nego, wStream* s) BYTE type; tpkt_read_header(s); - if(!tpdu_read_connection_request(s, &li)) + + if (!tpdu_read_connection_request(s, &li)) return FALSE; - if (li != stream_get_left(s) + 6) + if (li != Stream_GetRemainingLength(s) + 6) { fprintf(stderr, "Incorrect TPDU length indicator.\n"); return FALSE; } - if (stream_get_left(s) > 8) + if (Stream_GetRemainingLength(s) > 8) { /* Optional routingToken or cookie, ending with CR+LF */ - while (stream_get_left(s) > 0) + while (Stream_GetRemainingLength(s) > 0) { - stream_read_BYTE(s, c); + Stream_Read_UINT8(s, c); if (c != '\x0D') continue; - stream_peek_BYTE(s, c); + Stream_Peek_UINT8(s, c); if (c != '\x0A') continue; - stream_seek_BYTE(s); + Stream_Seek_UINT8(s); break; } } - if (stream_get_left(s) >= 8) + if (Stream_GetRemainingLength(s) >= 8) { /* rdpNegData (optional) */ - stream_read_BYTE(s, type); /* Type */ + Stream_Read_UINT8(s, type); /* Type */ if (type != TYPE_RDP_NEG_REQ) { @@ -640,54 +662,61 @@ BOOL nego_send_negotiation_request(rdpNego* nego) { wStream* s; int length; - BYTE *bm, *em; + int bm, em; int cookie_length; - s = transport_send_stream_init(nego->transport, 256); - length = TPDU_CONNECTION_REQUEST_LENGTH; - stream_get_mark(s, bm); - stream_seek(s, length); + s = Stream_New(NULL, 512); - if (nego->RoutingToken != NULL) + length = TPDU_CONNECTION_REQUEST_LENGTH; + bm = Stream_GetPosition(s); + Stream_Seek(s, length); + + if (nego->RoutingToken) { - stream_write(s, nego->RoutingToken, nego->RoutingTokenLength); - length += nego->RoutingTokenLength; + Stream_Write(s, nego->RoutingToken, nego->RoutingTokenLength); + Stream_Write_UINT8(s, 0x0D); /* CR */ + Stream_Write_UINT8(s, 0x0A); /* LF */ + length += nego->RoutingTokenLength + 2; } - else if (nego->cookie != NULL) + else if (nego->cookie) { cookie_length = strlen(nego->cookie); if (cookie_length > (int) nego->cookie_max_length) cookie_length = nego->cookie_max_length; - stream_write(s, "Cookie: mstshash=", 17); - stream_write(s, (BYTE*) nego->cookie, cookie_length); - stream_write_BYTE(s, 0x0D); /* CR */ - stream_write_BYTE(s, 0x0A); /* LF */ + Stream_Write(s, "Cookie: mstshash=", 17); + Stream_Write(s, (BYTE*) nego->cookie, cookie_length); + Stream_Write_UINT8(s, 0x0D); /* CR */ + Stream_Write_UINT8(s, 0x0A); /* LF */ length += cookie_length + 19; } DEBUG_NEGO("requested_protocols: %d", nego->requested_protocols); - if (nego->requested_protocols > PROTOCOL_RDP) + if ((nego->requested_protocols > PROTOCOL_RDP) || (nego->sendNegoData)) { /* RDP_NEG_DATA must be present for TLS and NLA */ - stream_write_BYTE(s, TYPE_RDP_NEG_REQ); - stream_write_BYTE(s, 0); /* flags, must be set to zero */ - stream_write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ - stream_write_UINT32(s, nego->requested_protocols); /* requestedProtocols */ + Stream_Write_UINT8(s, TYPE_RDP_NEG_REQ); + Stream_Write_UINT8(s, 0); /* flags, must be set to zero */ + Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ + Stream_Write_UINT32(s, nego->requested_protocols); /* requestedProtocols */ length += 8; } - stream_get_mark(s, em); - stream_set_mark(s, bm); + em = Stream_GetPosition(s); + Stream_SetPosition(s, bm); tpkt_write_header(s, length); tpdu_write_connection_request(s, length - 5); - stream_set_mark(s, em); + Stream_SetPosition(s, em); + + Stream_SealLength(s); if (transport_write(nego->transport, s) < 0) return FALSE; + Stream_Free(s, TRUE); + return TRUE; } @@ -704,9 +733,9 @@ void nego_process_negotiation_request(rdpNego* nego, wStream* s) DEBUG_NEGO("RDP_NEG_REQ"); - stream_read_BYTE(s, flags); - stream_read_UINT16(s, length); - stream_read_UINT32(s, nego->requested_protocols); + Stream_Read_UINT8(s, flags); + Stream_Read_UINT16(s, length); + Stream_Read_UINT32(s, nego->requested_protocols); DEBUG_NEGO("requested_protocols: %d", nego->requested_protocols); @@ -725,16 +754,16 @@ void nego_process_negotiation_response(rdpNego* nego, wStream* s) DEBUG_NEGO("RDP_NEG_RSP"); - if (stream_get_left(s) < 7) + if (Stream_GetRemainingLength(s) < 7) { DEBUG_NEGO("RDP_INVALID_NEG_RSP"); nego->state = NEGO_STATE_FAIL; return; } - stream_read_BYTE(s, nego->flags); - stream_read_UINT16(s, length); - stream_read_UINT32(s, nego->selected_protocol); + Stream_Read_UINT8(s, nego->flags); + Stream_Read_UINT16(s, length); + Stream_Read_UINT32(s, nego->selected_protocol); nego->state = NEGO_STATE_FINAL; } @@ -753,27 +782,33 @@ void nego_process_negotiation_failure(rdpNego* nego, wStream* s) DEBUG_NEGO("RDP_NEG_FAILURE"); - stream_read_BYTE(s, flags); - stream_read_UINT16(s, length); - stream_read_UINT32(s, failureCode); + Stream_Read_UINT8(s, flags); + Stream_Read_UINT16(s, length); + Stream_Read_UINT32(s, failureCode); switch (failureCode) { case SSL_REQUIRED_BY_SERVER: DEBUG_NEGO("Error: SSL_REQUIRED_BY_SERVER"); break; + case SSL_NOT_ALLOWED_BY_SERVER: DEBUG_NEGO("Error: SSL_NOT_ALLOWED_BY_SERVER"); break; + case SSL_CERT_NOT_ON_SERVER: DEBUG_NEGO("Error: SSL_CERT_NOT_ON_SERVER"); + nego->sendNegoData = TRUE; break; + case INCONSISTENT_FLAGS: DEBUG_NEGO("Error: INCONSISTENT_FLAGS"); break; + case HYBRID_REQUIRED_BY_SERVER: DEBUG_NEGO("Error: HYBRID_REQUIRED_BY_SERVER"); break; + default: DEBUG_NEGO("Error: Unknown protocol security error %d", failureCode); break; @@ -789,54 +824,58 @@ void nego_process_negotiation_failure(rdpNego* nego, wStream* s) BOOL nego_send_negotiation_response(rdpNego* nego) { - wStream* s; - BYTE* bm; - BYTE* em; int length; + int bm, em; BOOL status; + wStream* s; rdpSettings* settings; status = TRUE; settings = nego->transport->settings; - s = transport_send_stream_init(nego->transport, 256); + s = Stream_New(NULL, 512); + length = TPDU_CONNECTION_CONFIRM_LENGTH; - stream_get_mark(s, bm); - stream_seek(s, length); + bm = Stream_GetPosition(s); + Stream_Seek(s, length); if (nego->selected_protocol > PROTOCOL_RDP) { /* RDP_NEG_DATA must be present for TLS and NLA */ - stream_write_BYTE(s, TYPE_RDP_NEG_RSP); - stream_write_BYTE(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ - stream_write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ - stream_write_UINT32(s, nego->selected_protocol); /* selectedProtocol */ + Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP); + Stream_Write_UINT8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ + Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ + Stream_Write_UINT32(s, nego->selected_protocol); /* selectedProtocol */ length += 8; } else if (!settings->RdpSecurity) { - stream_write_BYTE(s, TYPE_RDP_NEG_FAILURE); - stream_write_BYTE(s, 0); /* flags */ - stream_write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ + Stream_Write_UINT8(s, TYPE_RDP_NEG_FAILURE); + Stream_Write_UINT8(s, 0); /* flags */ + Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ /* * TODO: Check for other possibilities, * like SSL_NOT_ALLOWED_BY_SERVER. */ fprintf(stderr, "nego_send_negotiation_response: client supports only Standard RDP Security\n"); - stream_write_UINT32(s, SSL_REQUIRED_BY_SERVER); + Stream_Write_UINT32(s, SSL_REQUIRED_BY_SERVER); length += 8; status = FALSE; } - stream_get_mark(s, em); - stream_set_mark(s, bm); + em = Stream_GetPosition(s); + Stream_SetPosition(s, bm); tpkt_write_header(s, length); tpdu_write_connection_confirm(s, length - 5); - stream_set_mark(s, em); + Stream_SetPosition(s, em); + + Stream_SealLength(s); if (transport_write(nego->transport, s) < 0) return FALSE; + Stream_Free(s, TRUE); + if (status) { /* update settings with negotiated protocol security */ diff --git a/libfreerdp/core/nego.h b/libfreerdp/core/nego.h index 48e3d0410..e8f429fb8 100644 --- a/libfreerdp/core/nego.h +++ b/libfreerdp/core/nego.h @@ -100,6 +100,7 @@ struct rdp_nego BOOL security_connected; UINT32 cookie_max_length; + BOOL sendNegoData; UINT32 selected_protocol; UINT32 requested_protocols; BOOL NegotiateSecurityLayer; diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 7d87ed9c0..8ab89ebd1 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -817,8 +817,8 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, wStream* s) ber_read_octet_string_tag(s, &length); credssp->identity.DomainLength = (UINT32) length; credssp->identity.Domain = (UINT16*) malloc(length); - CopyMemory(credssp->identity.Domain, s->pointer, credssp->identity.DomainLength); - stream_seek(s, credssp->identity.DomainLength); + CopyMemory(credssp->identity.Domain, Stream_Pointer(s), credssp->identity.DomainLength); + Stream_Seek(s, credssp->identity.DomainLength); credssp->identity.DomainLength /= 2; /* [1] userName (OCTET STRING) */ @@ -826,8 +826,8 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, wStream* s) ber_read_octet_string_tag(s, &length); credssp->identity.UserLength = (UINT32) length; credssp->identity.User = (UINT16*) malloc(length); - CopyMemory(credssp->identity.User, s->pointer, credssp->identity.UserLength); - stream_seek(s, credssp->identity.UserLength); + CopyMemory(credssp->identity.User, Stream_Pointer(s), credssp->identity.UserLength); + Stream_Seek(s, credssp->identity.UserLength); credssp->identity.UserLength /= 2; /* [2] password (OCTET STRING) */ @@ -835,8 +835,8 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, wStream* s) ber_read_octet_string_tag(s, &length); credssp->identity.PasswordLength = (UINT32) length; credssp->identity.Password = (UINT16*) malloc(length); - CopyMemory(credssp->identity.Password, s->pointer, credssp->identity.PasswordLength); - stream_seek(s, credssp->identity.PasswordLength); + CopyMemory(credssp->identity.Password, Stream_Pointer(s), credssp->identity.PasswordLength); + Stream_Seek(s, credssp->identity.PasswordLength); credssp->identity.PasswordLength /= 2; credssp->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; @@ -891,8 +891,7 @@ void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials) int length; int ts_password_creds_length; - s = stream_new(0); - stream_attach(s, ts_credentials->pvBuffer, ts_credentials->cbBuffer); + s = Stream_New(ts_credentials->pvBuffer, ts_credentials->cbBuffer); /* TSCredentials (SEQUENCE) */ ber_read_sequence_tag(s, &length); @@ -907,8 +906,7 @@ void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials) credssp_read_ts_password_creds(credssp, s); - stream_detach(s); - stream_free(s); + Stream_Free(s, FALSE); } void credssp_write_ts_credentials(rdpCredssp* credssp, wStream* s) @@ -945,14 +943,13 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp) wStream* s; int length; - s = stream_new(0); length = credssp_skip_ts_credentials(credssp); sspi_SecBufferAlloc(&credssp->ts_credentials, length); - stream_attach(s, credssp->ts_credentials.pvBuffer, length); + s = Stream_New(credssp->ts_credentials.pvBuffer, length); credssp_write_ts_credentials(credssp, s); - stream_detach(s); - stream_free(s); + + Stream_Free(s, FALSE); } SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp) @@ -1091,7 +1088,7 @@ void credssp_send(rdpCredssp* credssp) length = nego_tokens_length + pub_key_auth_length + auth_info_length; ts_request_length = credssp_skip_ts_request(length); - s = stream_new(ts_request_length); + s = Stream_New(NULL, ts_request_length); /* TSRequest */ length = der_get_content_length(ts_request_length); @@ -1128,8 +1125,11 @@ void credssp_send(rdpCredssp* credssp) ber_write_octet_string(s, credssp->pubKeyAuth.pvBuffer, credssp->pubKeyAuth.cbBuffer); } + Stream_SealLength(s); + transport_write(credssp->transport, s); - stream_free(s); + + Stream_Free(s, TRUE); } /** @@ -1145,15 +1145,15 @@ int credssp_recv(rdpCredssp* credssp) int status; UINT32 version; - s = stream_new(4096); + s = Stream_New(NULL, 4096); status = transport_read(credssp->transport, s); - s->capacity = status; + Stream_Length(s) = status; if (status < 0) { fprintf(stderr, "credssp_recv() error: %d\n", status); - stream_free(s); + Stream_Free(s, TRUE); return -1; } @@ -1170,10 +1170,10 @@ int credssp_recv(rdpCredssp* credssp) !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 */ - stream_get_left(s) < length) + Stream_GetRemainingLength(s) < length) return -1; sspi_SecBufferAlloc(&credssp->negoToken, length); - stream_read(s, credssp->negoToken.pvBuffer, length); + Stream_Read(s, credssp->negoToken.pvBuffer, length); credssp->negoToken.cbBuffer = length; } @@ -1181,10 +1181,10 @@ int credssp_recv(rdpCredssp* credssp) if (ber_read_contextual_tag(s, 2, &length, TRUE) != FALSE) { if(!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */ - stream_get_left(s) < length) + Stream_GetRemainingLength(s) < length) return -1; sspi_SecBufferAlloc(&credssp->authInfo, length); - stream_read(s, credssp->authInfo.pvBuffer, length); + Stream_Read(s, credssp->authInfo.pvBuffer, length); credssp->authInfo.cbBuffer = length; } @@ -1192,14 +1192,14 @@ int credssp_recv(rdpCredssp* credssp) if (ber_read_contextual_tag(s, 3, &length, TRUE) != FALSE) { if(!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */ - stream_get_left(s) < length) + Stream_GetRemainingLength(s) < length) return -1; sspi_SecBufferAlloc(&credssp->pubKeyAuth, length); - stream_read(s, credssp->pubKeyAuth.pvBuffer, length); + Stream_Read(s, credssp->pubKeyAuth.pvBuffer, length); credssp->pubKeyAuth.cbBuffer = length; } - stream_free(s); + Stream_Free(s, TRUE); return 0; } diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index 32e4b1bed..6fef8dff2 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -99,7 +99,7 @@ static const char* const ALTSEC_DRAWING_ORDER_STRINGS[] = #endif /* WITH_DEBUG_ORDERS */ -static const BYTE PRIMARY_DRAWING_ORDER_FIELD_BYTES[] = +const BYTE PRIMARY_DRAWING_ORDER_FIELD_BYTES[] = { DSTBLT_ORDER_FIELD_BYTES, PATBLT_ORDER_FIELD_BYTES, @@ -135,16 +135,43 @@ static const BYTE CBR2_BPP[] = 0, 0, 0, 8, 16, 24, 32 }; +static const BYTE BPP_CBR2[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0 +}; + static const BYTE CBR23_BPP[] = { 0, 0, 0, 8, 16, 24, 32 }; +static const BYTE BPP_CBR23[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0 +}; + static const BYTE BMF_BPP[] = { 0, 1, 0, 8, 16, 24, 32 }; +static const BYTE BPP_BMF[] = +{ + 0, 1, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0 +}; + static INLINE BOOL update_read_coord(wStream* s, INT32* coord, BOOL delta) { INT8 lsi8; @@ -152,18 +179,37 @@ static INLINE BOOL update_read_coord(wStream* s, INT32* coord, BOOL delta) if (delta) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, lsi8); + + Stream_Read_UINT8(s, lsi8); *coord += lsi8; } else { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, lsi16); + + Stream_Read_UINT16(s, lsi16); *coord = lsi16; } + + return TRUE; +} + +static INLINE BOOL update_write_coord(wStream* s, INT32 coord) +{ + Stream_Write_UINT16(s, coord); + return TRUE; +} + +static INLINE BOOL update_write_coord_delta(wStream* s, INT32 prevCoord, INT32 nextCoord) +{ + INT8 lsi8; + + lsi8 = nextCoord - prevCoord; + Stream_Write_UINT8(s, lsi8); + return TRUE; } @@ -171,14 +217,30 @@ static INLINE BOOL update_read_color(wStream* s, UINT32* color) { BYTE byte; - if (stream_get_left(s) < 3) + if (Stream_GetRemainingLength(s) < 3) return FALSE; - stream_read_BYTE(s, byte); + + Stream_Read_UINT8(s, byte); *color = byte; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *color |= (byte << 8); - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *color |= (byte << 16); + + return TRUE; +} + +static INLINE BOOL update_write_color(wStream* s, UINT32 color) +{ + BYTE byte; + + byte = (color & 0xFF); + Stream_Write_UINT8(s, byte); + byte = ((color >> 8) & 0xFF); + Stream_Write_UINT8(s, byte); + byte = ((color >> 16) & 0xFF); + Stream_Write_UINT8(s, byte); + return TRUE; } @@ -186,49 +248,85 @@ static INLINE void update_read_colorref(wStream* s, UINT32* color) { BYTE byte; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *color = byte; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *color |= (byte << 8); - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *color |= (byte << 16); - stream_seek_BYTE(s); + Stream_Seek_UINT8(s); } static INLINE void update_read_color_quad(wStream* s, UINT32* color) { BYTE byte; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *color = (byte << 16); - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *color |= (byte << 8); - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *color |= byte; - stream_seek_BYTE(s); + Stream_Seek_UINT8(s); +} + +static INLINE void update_write_color_quad(wStream* s, UINT32 color) +{ + BYTE byte; + + byte = (color << 16) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (color << 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = color & 0xFF; + Stream_Write_UINT8(s, byte); } static INLINE BOOL update_read_2byte_unsigned(wStream* s, UINT32* value) { BYTE byte; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte & 0x80) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; *value = (byte & 0x7F) << 8; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *value |= byte; } else { *value = (byte & 0x7F); } + + return TRUE; +} + +static INLINE BOOL update_write_2byte_unsigned(wStream* s, UINT32 value) +{ + BYTE byte; + + if (value > 0x7FFF) + return FALSE; + + if (value >= 0x7F) + { + byte = ((value & 0x7F00) >> 8); + Stream_Write_UINT8(s, byte | 0x80); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else + { + byte = (value & 0x7F); + Stream_Write_UINT8(s, byte); + } + return TRUE; } @@ -237,10 +335,10 @@ static INLINE BOOL update_read_2byte_signed(wStream* s, INT32* value) BYTE byte; BOOL negative; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); negative = (byte & 0x40) ? TRUE : FALSE; @@ -248,14 +346,54 @@ static INLINE BOOL update_read_2byte_signed(wStream* s, INT32* value) if (byte & 0x80) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + + Stream_Read_UINT8(s, byte); *value = (*value << 8) | byte; } if (negative) *value *= -1; + + return TRUE; +} + +static INLINE BOOL update_write_2byte_signed(wStream* s, INT32 value) +{ + BYTE byte; + BOOL negative = FALSE; + + if (value < 0) + { + negative = TRUE; + value *= -1; + } + + if (value > 0x3FFF) + return FALSE; + + if (value >= 0x3F) + { + byte = ((value & 0x3F00) >> 8); + + if (negative) + byte |= 0x40; + + Stream_Write_UINT8(s, byte | 0x80); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else + { + byte = (value & 0x3F); + + if (negative) + byte |= 0x40; + + Stream_Write_UINT8(s, byte); + } + return TRUE; } @@ -264,12 +402,14 @@ static INLINE BOOL update_read_4byte_unsigned(wStream* s, UINT32* value) BYTE byte; BYTE count; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + + Stream_Read_UINT8(s, byte); count = (byte & 0xC0) >> 6; - if (stream_get_left(s) < count) + + if (Stream_GetRemainingLength(s) < count) return FALSE; switch (count) @@ -280,31 +420,75 @@ static INLINE BOOL update_read_4byte_unsigned(wStream* s, UINT32* value) case 1: *value = (byte & 0x3F) << 8; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *value |= byte; break; case 2: *value = (byte & 0x3F) << 16; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *value |= (byte << 8); - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *value |= byte; break; case 3: *value = (byte & 0x3F) << 24; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *value |= (byte << 16); - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *value |= (byte << 8); - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *value |= byte; break; default: break; } + + return TRUE; +} + +static INLINE BOOL update_write_4byte_unsigned(wStream* s, UINT32 value) +{ + BYTE byte; + + if (value <= 0x3F) + { + Stream_Write_UINT8(s, value); + } + else if (value <= 0x3FFF) + { + byte = (value >> 8) & 0x3F; + Stream_Write_UINT8(s, byte | 0x40); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x3FFFFF) + { + byte = (value >> 16) & 0x3F; + Stream_Write_UINT8(s, byte | 0x80); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else if (value <= 0x3FFFFF) + { + byte = (value >> 24) & 0x3F; + Stream_Write_UINT8(s, byte | 0xC0); + byte = (value >> 16) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (value & 0xFF); + Stream_Write_UINT8(s, byte); + } + else + { + return FALSE; + } + return TRUE; } @@ -312,9 +496,9 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value) { BYTE byte; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte & 0x40) *value = (byte | ~0x3F); @@ -323,9 +507,9 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value) if (byte & 0x80) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *value = (*value << 8) | byte; } return TRUE; @@ -335,10 +519,10 @@ static INLINE void update_read_glyph_delta(wStream* s, UINT16* value) { BYTE byte; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte == 0x80) - stream_read_UINT16(s, *value); + Stream_Read_UINT16(s, *value); else *value = (byte & 0x3F); } @@ -347,40 +531,44 @@ static INLINE void update_seek_glyph_delta(wStream* s) { BYTE byte; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte & 0x80) - stream_seek_BYTE(s); + Stream_Seek_UINT8(s); } static INLINE BOOL update_read_brush(wStream* s, rdpBrush* brush, BYTE fieldFlags) { if (fieldFlags & ORDER_FIELD_01) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, brush->x); + + Stream_Read_UINT8(s, brush->x); } if (fieldFlags & ORDER_FIELD_02) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, brush->y); + + Stream_Read_UINT8(s, brush->y); } if (fieldFlags & ORDER_FIELD_03) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, brush->style); + + Stream_Read_UINT8(s, brush->style); } if (fieldFlags & ORDER_FIELD_04) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, brush->hatch); + + Stream_Read_UINT8(s, brush->hatch); } if (brush->style & CACHED_BRUSH) @@ -395,18 +583,68 @@ static INLINE BOOL update_read_brush(wStream* s, rdpBrush* brush, BYTE fieldFlag if (fieldFlags & ORDER_FIELD_05) { - if (stream_get_left(s) < 7) + if (Stream_GetRemainingLength(s) < 7) return FALSE; + brush->data = (BYTE*) brush->p8x8; - stream_read_BYTE(s, brush->data[7]); - stream_read_BYTE(s, brush->data[6]); - stream_read_BYTE(s, brush->data[5]); - stream_read_BYTE(s, brush->data[4]); - stream_read_BYTE(s, brush->data[3]); - stream_read_BYTE(s, brush->data[2]); - stream_read_BYTE(s, brush->data[1]); + Stream_Read_UINT8(s, brush->data[7]); + Stream_Read_UINT8(s, brush->data[6]); + Stream_Read_UINT8(s, brush->data[5]); + Stream_Read_UINT8(s, brush->data[4]); + Stream_Read_UINT8(s, brush->data[3]); + Stream_Read_UINT8(s, brush->data[2]); + Stream_Read_UINT8(s, brush->data[1]); brush->data[0] = brush->hatch; } + + return TRUE; +} + +static INLINE BOOL update_write_brush(wStream* s, rdpBrush* brush, BYTE fieldFlags) +{ + if (fieldFlags & ORDER_FIELD_01) + { + Stream_Write_UINT8(s, brush->x); + } + + if (fieldFlags & ORDER_FIELD_02) + { + Stream_Write_UINT8(s, brush->y); + } + + if (fieldFlags & ORDER_FIELD_03) + { + Stream_Write_UINT8(s, brush->style); + } + + if (brush->style & CACHED_BRUSH) + { + brush->hatch = brush->index; + + brush->bpp = BMF_BPP[brush->style & 0x0F]; + + if (brush->bpp == 0) + brush->bpp = 1; + } + + if (fieldFlags & ORDER_FIELD_04) + { + Stream_Write_UINT8(s, brush->hatch); + } + + if (fieldFlags & ORDER_FIELD_05) + { + brush->data = (BYTE*) brush->p8x8; + Stream_Write_UINT8(s, brush->data[7]); + Stream_Write_UINT8(s, brush->data[6]); + Stream_Write_UINT8(s, brush->data[5]); + Stream_Write_UINT8(s, brush->data[4]); + Stream_Write_UINT8(s, brush->data[3]); + Stream_Write_UINT8(s, brush->data[2]); + Stream_Write_UINT8(s, brush->data[1]); + brush->data[0] = brush->hatch; + } + return TRUE; } @@ -422,12 +660,13 @@ static INLINE BOOL update_read_delta_rects(wStream* s, DELTA_RECT* rectangles, i zeroBitsSize = ((number + 1) / 2); - if (stream_get_left(s) < zeroBitsSize) + if (Stream_GetRemainingLength(s) < zeroBitsSize) return FALSE; - stream_get_mark(s, zeroBits); - stream_seek(s, zeroBitsSize); - memset(rectangles, 0, sizeof(DELTA_RECT) * (number + 1)); + Stream_GetPointer(s, zeroBits); + Stream_Seek(s, zeroBitsSize); + + ZeroMemory(rectangles, sizeof(DELTA_RECT) * (number + 1)); for (i = 1; i < number + 1; i++) { @@ -446,7 +685,9 @@ static INLINE BOOL update_read_delta_rects(wStream* s, DELTA_RECT* rectangles, i return FALSE; } else + { rectangles[i].width = rectangles[i - 1].width; + } if (~flags & 0x10) { @@ -454,13 +695,16 @@ static INLINE BOOL update_read_delta_rects(wStream* s, DELTA_RECT* rectangles, i return FALSE; } else + { rectangles[i].height = rectangles[i - 1].height; + } rectangles[i].left = rectangles[i].left + rectangles[i - 1].left; rectangles[i].top = rectangles[i].top + rectangles[i - 1].top; flags <<= 4; } + return TRUE; } @@ -473,12 +717,13 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int zeroBitsSize = ((number + 3) / 4); - if (stream_get_left(s) < zeroBitsSize) + if (Stream_GetRemainingLength(s) < zeroBitsSize) return FALSE; - stream_get_mark(s, zeroBits); - stream_seek(s, zeroBitsSize); - memset(points, 0, sizeof(DELTA_POINT) * number); + Stream_GetPointer(s, zeroBits); + Stream_Seek(s, zeroBitsSize); + + ZeroMemory(points, sizeof(DELTA_POINT) * number); for (i = 0; i < number; i++) { @@ -501,11 +746,11 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int do {\ if (orderInfo->fieldFlags & (1 << (NO-1))) \ { \ - if (stream_get_left(s) < 1) {\ + if (Stream_GetRemainingLength(s) < 1) {\ fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \ return FALSE; \ } \ - stream_read_BYTE(s, TARGET); \ + Stream_Read_UINT8(s, TARGET); \ } \ } while(0) @@ -513,12 +758,12 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int do {\ if (orderInfo->fieldFlags & (1 << (NO-1))) \ { \ - if (stream_get_left(s) < 2) { \ + if (Stream_GetRemainingLength(s) < 2) { \ fprintf(stderr, "%s: error reading %s or %s\n", __FUNCTION__, #TARGET1, #TARGET2); \ return FALSE; \ } \ - stream_read_BYTE(s, TARGET1); \ - stream_read_BYTE(s, TARGET2); \ + Stream_Read_UINT8(s, TARGET1); \ + Stream_Read_UINT8(s, TARGET2); \ } \ } while(0) @@ -526,22 +771,22 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int do {\ if (orderInfo->fieldFlags & (1 << (NO-1))) \ { \ - if (stream_get_left(s) < 2) { \ + if (Stream_GetRemainingLength(s) < 2) { \ fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \ return FALSE; \ } \ - stream_read_UINT16(s, TARGET); \ + Stream_Read_UINT16(s, TARGET); \ } \ } while(0) #define ORDER_FIELD_UINT32(NO, TARGET) \ do {\ if (orderInfo->fieldFlags & (1 << (NO-1))) \ { \ - if (stream_get_left(s) < 4) { \ + if (Stream_GetRemainingLength(s) < 4) { \ fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \ return FALSE; \ } \ - stream_read_UINT32(s, TARGET); \ + Stream_Read_UINT32(s, TARGET); \ } \ } while(0) @@ -563,12 +808,12 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int #define FIELD_SKIP_BUFFER16(s, TARGET_LEN) \ do { \ - if (stream_get_left(s) < 2) {\ + if (Stream_GetRemainingLength(s) < 2) {\ fprintf(stderr, "%s: error reading length %s\n", __FUNCTION__, #TARGET_LEN); \ return FALSE; \ }\ - stream_read_UINT16(s, TARGET_LEN); \ - if (!stream_skip(s, TARGET_LEN)) { \ + Stream_Read_UINT16(s, TARGET_LEN); \ + if (!Stream_SafeSeek(s, TARGET_LEN)) { \ fprintf(stderr, "%s: error skipping %d bytes\n", __FUNCTION__, TARGET_LEN); \ return FALSE; \ } \ @@ -586,6 +831,30 @@ BOOL update_read_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* d return TRUE; } +BOOL update_write_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt) +{ + orderInfo->fieldFlags = 0; + + Stream_EnsureRemainingCapacity(s, 64); + + orderInfo->fieldFlags |= ORDER_FIELD_01; + update_write_coord(s, dstblt->nLeftRect); + + orderInfo->fieldFlags |= ORDER_FIELD_02; + update_write_coord(s, dstblt->nTopRect); + + orderInfo->fieldFlags |= ORDER_FIELD_03; + update_write_coord(s, dstblt->nWidth); + + orderInfo->fieldFlags |= ORDER_FIELD_04; + update_write_coord(s, dstblt->nHeight); + + orderInfo->fieldFlags |= ORDER_FIELD_05; + Stream_Write_UINT8(s, dstblt->bRop); + + return TRUE; +} + BOOL update_read_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt) { ORDER_FIELD_COORD(1, patblt->nLeftRect); @@ -598,6 +867,43 @@ BOOL update_read_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* p return update_read_brush(s, &patblt->brush, orderInfo->fieldFlags >> 7); } +BOOL update_write_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt) +{ + orderInfo->fieldFlags = 0; + + Stream_EnsureRemainingCapacity(s, 64); + + orderInfo->fieldFlags |= ORDER_FIELD_01; + update_write_coord(s, patblt->nLeftRect); + + orderInfo->fieldFlags |= ORDER_FIELD_02; + update_write_coord(s, patblt->nTopRect); + + orderInfo->fieldFlags |= ORDER_FIELD_03; + update_write_coord(s, patblt->nWidth); + + orderInfo->fieldFlags |= ORDER_FIELD_04; + update_write_coord(s, patblt->nHeight); + + orderInfo->fieldFlags |= ORDER_FIELD_05; + Stream_Write_UINT8(s, patblt->bRop); + + orderInfo->fieldFlags |= ORDER_FIELD_06; + update_write_color(s, patblt->backColor); + + orderInfo->fieldFlags |= ORDER_FIELD_07; + update_write_color(s, patblt->foreColor); + + orderInfo->fieldFlags |= ORDER_FIELD_08; + orderInfo->fieldFlags |= ORDER_FIELD_09; + orderInfo->fieldFlags |= ORDER_FIELD_10; + orderInfo->fieldFlags |= ORDER_FIELD_11; + orderInfo->fieldFlags |= ORDER_FIELD_12; + update_write_brush(s, &patblt->brush, orderInfo->fieldFlags >> 7); + + return TRUE; +} + BOOL update_read_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt) { ORDER_FIELD_COORD(1, scrblt->nLeftRect); @@ -607,6 +913,37 @@ BOOL update_read_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* s ORDER_FIELD_BYTE(5, scrblt->bRop); ORDER_FIELD_COORD(6, scrblt->nXSrc); ORDER_FIELD_COORD(7, scrblt->nYSrc); + + return TRUE; +} + +BOOL update_write_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt) +{ + orderInfo->fieldFlags = 0; + + Stream_EnsureRemainingCapacity(s, 32); + + orderInfo->fieldFlags |= ORDER_FIELD_01; + update_write_coord(s, scrblt->nLeftRect); + + orderInfo->fieldFlags |= ORDER_FIELD_02; + update_write_coord(s, scrblt->nTopRect); + + orderInfo->fieldFlags |= ORDER_FIELD_03; + update_write_coord(s, scrblt->nWidth); + + orderInfo->fieldFlags |= ORDER_FIELD_04; + update_write_coord(s, scrblt->nHeight); + + orderInfo->fieldFlags |= ORDER_FIELD_05; + Stream_Write_UINT8(s, scrblt->bRop); + + orderInfo->fieldFlags |= ORDER_FIELD_06; + update_write_coord(s, scrblt->nXSrc); + + orderInfo->fieldFlags |= ORDER_FIELD_07; + update_write_coord(s, scrblt->nYSrc); + return TRUE; } @@ -621,25 +958,63 @@ BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_REC if (orderInfo->fieldFlags & ORDER_FIELD_05) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + + Stream_Read_UINT8(s, byte); opaque_rect->color = (opaque_rect->color & 0xFFFFFF00) | byte; } - if (orderInfo->fieldFlags & ORDER_FIELD_06) { - if (stream_get_left(s) < 1) + if (orderInfo->fieldFlags & ORDER_FIELD_06) + { + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + + Stream_Read_UINT8(s, byte); opaque_rect->color = (opaque_rect->color & 0xFFFF00FF) | (byte << 8); } - if (orderInfo->fieldFlags & ORDER_FIELD_07) { - if (stream_get_left(s) < 1) + if (orderInfo->fieldFlags & ORDER_FIELD_07) + { + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + + Stream_Read_UINT8(s, byte); opaque_rect->color = (opaque_rect->color & 0xFF00FFFF) | (byte << 16); } + + return TRUE; +} + +BOOL update_write_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect) +{ + BYTE byte; + + Stream_EnsureRemainingCapacity(s, 32); + + orderInfo->fieldFlags = 0; + + orderInfo->fieldFlags |= ORDER_FIELD_01; + update_write_coord(s, opaque_rect->nLeftRect); + orderInfo->fieldFlags |= ORDER_FIELD_02; + update_write_coord(s, opaque_rect->nTopRect); + orderInfo->fieldFlags |= ORDER_FIELD_03; + update_write_coord(s, opaque_rect->nWidth); + orderInfo->fieldFlags |= ORDER_FIELD_04; + update_write_coord(s, opaque_rect->nHeight); + + orderInfo->fieldFlags |= ORDER_FIELD_05; + byte = opaque_rect->color & 0x000000FF; + Stream_Write_UINT8(s, byte); + + orderInfo->fieldFlags |= ORDER_FIELD_06; + byte = (opaque_rect->color & 0x0000FF00) >> 8; + Stream_Write_UINT8(s, byte); + + orderInfo->fieldFlags |= ORDER_FIELD_07; + byte = (opaque_rect->color & 0x00FF0000) >> 16; + Stream_Write_UINT8(s, byte); + return TRUE; } @@ -653,6 +1028,11 @@ BOOL update_read_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NI return TRUE; } +BOOL update_write_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid) +{ + return TRUE; +} + BOOL update_read_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt) { ORDER_FIELD_COORD(1, multi_dstblt->nLeftRect); @@ -664,14 +1044,19 @@ BOOL update_read_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DST if (orderInfo->fieldFlags & ORDER_FIELD_07) { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, multi_dstblt->cbData); + Stream_Read_UINT16(s, multi_dstblt->cbData); return update_read_delta_rects(s, multi_dstblt->rectangles, multi_dstblt->numRectangles); } return TRUE; } +BOOL update_write_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt) +{ + return TRUE; +} + BOOL update_read_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt) { ORDER_FIELD_COORD(1, multi_patblt->nLeftRect); @@ -689,15 +1074,20 @@ BOOL update_read_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PAT if (orderInfo->fieldFlags & ORDER_FIELD_14) { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, multi_patblt->cbData); + Stream_Read_UINT16(s, multi_patblt->cbData); if (!update_read_delta_rects(s, multi_patblt->rectangles, multi_patblt->numRectangles)) return FALSE; } return TRUE; } +BOOL update_write_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt) +{ + return TRUE; +} + BOOL update_read_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt) { ORDER_FIELD_COORD(1, multi_scrblt->nLeftRect); @@ -711,17 +1101,23 @@ BOOL update_read_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCR if (orderInfo->fieldFlags & ORDER_FIELD_09) { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, multi_scrblt->cbData); + Stream_Read_UINT16(s, multi_scrblt->cbData); return update_read_delta_rects(s, multi_scrblt->rectangles, multi_scrblt->numRectangles); } return TRUE; } +BOOL update_write_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt) +{ + return TRUE; +} + BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) { BYTE byte; + ORDER_FIELD_COORD(1, multi_opaque_rect->nLeftRect); ORDER_FIELD_COORD(2, multi_opaque_rect->nTopRect); ORDER_FIELD_COORD(3, multi_opaque_rect->nWidth); @@ -729,25 +1125,25 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT if (orderInfo->fieldFlags & ORDER_FIELD_05) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFFFF00) | byte; } if (orderInfo->fieldFlags & ORDER_FIELD_06) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFF00FF) | (byte << 8); } if (orderInfo->fieldFlags & ORDER_FIELD_07) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); multi_opaque_rect->color = (multi_opaque_rect->color & 0xFF00FFFF) | (byte << 16); } @@ -755,14 +1151,18 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT if (orderInfo->fieldFlags & ORDER_FIELD_09) { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, multi_opaque_rect->cbData); + Stream_Read_UINT16(s, multi_opaque_rect->cbData); return update_read_delta_rects(s, multi_opaque_rect->rectangles, multi_opaque_rect->numRectangles); } return TRUE; } +BOOL update_write_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) +{ + return TRUE; +} BOOL update_read_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid) { @@ -780,6 +1180,11 @@ BOOL update_read_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, M return TRUE; } +BOOL update_write_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid) +{ + return TRUE; +} + BOOL update_read_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to) { ORDER_FIELD_UINT16(1, line_to->backMode); @@ -795,6 +1200,45 @@ BOOL update_read_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* return TRUE; } +BOOL update_write_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to) +{ + Stream_EnsureRemainingCapacity(s, 32); + + orderInfo->fieldFlags = 0; + + orderInfo->fieldFlags |= ORDER_FIELD_01; + Stream_Write_UINT16(s, line_to->backMode); + + orderInfo->fieldFlags |= ORDER_FIELD_02; + update_write_coord(s, line_to->nXStart); + + orderInfo->fieldFlags |= ORDER_FIELD_03; + update_write_coord(s, line_to->nYStart); + + orderInfo->fieldFlags |= ORDER_FIELD_04; + update_write_coord(s, line_to->nXEnd); + + orderInfo->fieldFlags |= ORDER_FIELD_05; + update_write_coord(s, line_to->nYEnd); + + orderInfo->fieldFlags |= ORDER_FIELD_06; + update_write_color(s, line_to->backColor); + + orderInfo->fieldFlags |= ORDER_FIELD_07; + Stream_Write_UINT8(s, line_to->bRop2); + + orderInfo->fieldFlags |= ORDER_FIELD_08; + Stream_Write_UINT8(s, line_to->penStyle); + + orderInfo->fieldFlags |= ORDER_FIELD_09; + Stream_Write_UINT8(s, line_to->penWidth); + + orderInfo->fieldFlags |= ORDER_FIELD_10; + update_write_color(s, line_to->penColor); + + return TRUE; +} + BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline) { UINT16 word; @@ -808,9 +1252,9 @@ BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDE if (orderInfo->fieldFlags & ORDER_FIELD_07) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, polyline->cbData); + Stream_Read_UINT8(s, polyline->cbData); if (polyline->points == NULL) polyline->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * polyline->numPoints); @@ -819,6 +1263,12 @@ BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDE return update_read_delta_points(s, polyline->points, polyline->numPoints, polyline->xStart, polyline->yStart); } + + return TRUE; +} + +BOOL update_write_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline) +{ return TRUE; } @@ -836,6 +1286,45 @@ BOOL update_read_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* m memblt->colorIndex = (memblt->cacheId >> 8); memblt->cacheId = (memblt->cacheId & 0xFF); + + return TRUE; +} + +BOOL update_write_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt) +{ + UINT16 cacheId; + + Stream_EnsureRemainingCapacity(s, 32); + + cacheId = (memblt->cacheId & 0xFF) | ((memblt->colorIndex & 0xFF) << 8); + + orderInfo->fieldFlags |= ORDER_FIELD_01; + Stream_Write_UINT16(s, cacheId); + + orderInfo->fieldFlags |= ORDER_FIELD_02; + update_write_coord(s, memblt->nLeftRect); + + orderInfo->fieldFlags |= ORDER_FIELD_03; + update_write_coord(s, memblt->nTopRect); + + orderInfo->fieldFlags |= ORDER_FIELD_04; + update_write_coord(s, memblt->nWidth); + + orderInfo->fieldFlags |= ORDER_FIELD_05; + update_write_coord(s, memblt->nHeight); + + orderInfo->fieldFlags |= ORDER_FIELD_06; + Stream_Write_UINT8(s, memblt->bRop); + + orderInfo->fieldFlags |= ORDER_FIELD_07; + update_write_coord(s, memblt->nXSrc); + + orderInfo->fieldFlags |= ORDER_FIELD_08; + update_write_coord(s, memblt->nYSrc); + + orderInfo->fieldFlags |= ORDER_FIELD_09; + Stream_Write_UINT16(s, memblt->cacheIndex); + return TRUE; } @@ -861,6 +1350,11 @@ BOOL update_read_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* return TRUE; } +BOOL update_write_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt) +{ + return TRUE; +} + BOOL update_read_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap) { ORDER_FIELD_UINT32(1, save_bitmap->savedBitmapPosition); @@ -872,6 +1366,11 @@ BOOL update_read_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMA return TRUE; } +BOOL update_write_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap) +{ + return TRUE; +} + BOOL update_read_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index) { ORDER_FIELD_BYTE(1, glyph_index->cacheId); @@ -897,15 +1396,86 @@ BOOL update_read_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDE if (orderInfo->fieldFlags & ORDER_FIELD_22) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, glyph_index->cbData); - if (stream_get_left(s) < glyph_index->cbData) + Stream_Read_UINT8(s, glyph_index->cbData); + + if (Stream_GetRemainingLength(s) < glyph_index->cbData) return FALSE; - memcpy(glyph_index->data, s->pointer, glyph_index->cbData); - stream_seek(s, glyph_index->cbData); + + memcpy(glyph_index->data, Stream_Pointer(s), glyph_index->cbData); + Stream_Seek(s, glyph_index->cbData); } + + return TRUE; +} + +BOOL update_write_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index) +{ + orderInfo->fieldFlags = 0; + + Stream_EnsureRemainingCapacity(s, 64); + + orderInfo->fieldFlags |= ORDER_FIELD_01; + Stream_Write_UINT8(s, glyph_index->cacheId); + + orderInfo->fieldFlags |= ORDER_FIELD_02; + Stream_Write_UINT8(s, glyph_index->flAccel); + + orderInfo->fieldFlags |= ORDER_FIELD_03; + Stream_Write_UINT8(s, glyph_index->ulCharInc); + + orderInfo->fieldFlags |= ORDER_FIELD_04; + Stream_Write_UINT8(s, glyph_index->fOpRedundant); + + orderInfo->fieldFlags |= ORDER_FIELD_05; + update_write_color(s, glyph_index->backColor); + + orderInfo->fieldFlags |= ORDER_FIELD_06; + update_write_color(s, glyph_index->foreColor); + + orderInfo->fieldFlags |= ORDER_FIELD_07; + Stream_Write_UINT16(s, glyph_index->bkLeft); + + orderInfo->fieldFlags |= ORDER_FIELD_08; + Stream_Write_UINT16(s, glyph_index->bkTop); + + orderInfo->fieldFlags |= ORDER_FIELD_09; + Stream_Write_UINT16(s, glyph_index->bkRight); + + orderInfo->fieldFlags |= ORDER_FIELD_10; + Stream_Write_UINT16(s, glyph_index->bkBottom); + + orderInfo->fieldFlags |= ORDER_FIELD_11; + Stream_Write_UINT16(s, glyph_index->opLeft); + + orderInfo->fieldFlags |= ORDER_FIELD_12; + Stream_Write_UINT16(s, glyph_index->opTop); + + orderInfo->fieldFlags |= ORDER_FIELD_13; + Stream_Write_UINT16(s, glyph_index->opRight); + + orderInfo->fieldFlags |= ORDER_FIELD_14; + Stream_Write_UINT16(s, glyph_index->opBottom); + + orderInfo->fieldFlags |= ORDER_FIELD_15; + orderInfo->fieldFlags |= ORDER_FIELD_16; + orderInfo->fieldFlags |= ORDER_FIELD_17; + orderInfo->fieldFlags |= ORDER_FIELD_18; + orderInfo->fieldFlags |= ORDER_FIELD_19; + update_write_brush(s, &glyph_index->brush, orderInfo->fieldFlags >> 14); + + orderInfo->fieldFlags |= ORDER_FIELD_20; + Stream_Write_UINT16(s, glyph_index->x); + + orderInfo->fieldFlags |= ORDER_FIELD_21; + Stream_Write_UINT16(s, glyph_index->y); + + orderInfo->fieldFlags |= ORDER_FIELD_22; + Stream_Write_UINT8(s, glyph_index->cbData); + Stream_Write(s, glyph_index->data, glyph_index->cbData); + return TRUE; } @@ -928,18 +1498,23 @@ BOOL update_read_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ if (orderInfo->fieldFlags & ORDER_FIELD_15) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, fast_index->cbData); + Stream_Read_UINT8(s, fast_index->cbData); - if (stream_get_left(s) < fast_index->cbData) + if (Stream_GetRemainingLength(s) < fast_index->cbData) return FALSE; - memcpy(fast_index->data, s->pointer, fast_index->cbData); - stream_seek(s, fast_index->cbData); + memcpy(fast_index->data, Stream_Pointer(s), fast_index->cbData); + Stream_Seek(s, fast_index->cbData); } return TRUE; } +BOOL update_write_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index) +{ + return TRUE; +} + BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph) { BYTE* phold; @@ -962,18 +1537,18 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ if (orderInfo->fieldFlags & ORDER_FIELD_15) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, fast_glyph->cbData); + Stream_Read_UINT8(s, fast_glyph->cbData); - if (stream_get_left(s) < fast_glyph->cbData) + if (Stream_GetRemainingLength(s) < fast_glyph->cbData) return FALSE; - memcpy(fast_glyph->data, s->pointer, fast_glyph->cbData); - phold = s->pointer; + memcpy(fast_glyph->data, Stream_Pointer(s), fast_glyph->cbData); + phold = Stream_Pointer(s); - if (!stream_skip(s, 1)) + if (!Stream_SafeSeek(s, 1)) return FALSE; if (fast_glyph->cbData > 1) @@ -991,18 +1566,23 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; - if (stream_get_left(s) < glyph->cb) + if (Stream_GetRemainingLength(s) < glyph->cb) return FALSE; glyph->aj = (BYTE*) malloc(glyph->cb); - stream_read(s, glyph->aj, glyph->cb); + Stream_Read(s, glyph->aj, glyph->cb); } - s->pointer = phold + fast_glyph->cbData; + Stream_Pointer(s) = phold + fast_glyph->cbData; } return TRUE; } +BOOL update_write_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph) +{ + return TRUE; +} + BOOL update_read_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc) { ORDER_FIELD_COORD(1, polygon_sc->xStart); @@ -1014,9 +1594,9 @@ BOOL update_read_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ if (orderInfo->fieldFlags & ORDER_FIELD_07) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, polygon_sc->cbData); + Stream_Read_UINT8(s, polygon_sc->cbData); if (polygon_sc->points == NULL) polygon_sc->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * polygon_sc->numPoints); @@ -1028,6 +1608,11 @@ BOOL update_read_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ return TRUE; } +BOOL update_write_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc) +{ + return TRUE; +} + BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb) { ORDER_FIELD_COORD(1, polygon_cb->xStart); @@ -1044,9 +1629,9 @@ BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ if (orderInfo->fieldFlags & ORDER_FIELD_13) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, polygon_cb->cbData); + Stream_Read_UINT8(s, polygon_cb->cbData); if (polygon_cb->points == NULL) polygon_cb->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * polygon_cb->numPoints); @@ -1062,6 +1647,11 @@ BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ return TRUE; } +BOOL update_write_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb) +{ + return TRUE; +} + BOOL update_read_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc) { ORDER_FIELD_COORD(1, ellipse_sc->leftRect); @@ -1074,6 +1664,11 @@ BOOL update_read_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ return TRUE; } +BOOL update_write_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc) +{ + return TRUE; +} + BOOL update_read_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb) { ORDER_FIELD_COORD(1, ellipse_cb->leftRect); @@ -1087,178 +1682,326 @@ BOOL update_read_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ return update_read_brush(s, &ellipse_cb->brush, orderInfo->fieldFlags >> 8); } +BOOL update_write_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb) +{ + return TRUE; +} + /* Secondary Drawing Orders */ -BOOL update_read_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap_order, BOOL compressed, UINT16 flags) +BOOL update_read_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap, BOOL compressed, UINT16 flags) { - if (stream_get_left(s) < 9) + if (Stream_GetRemainingLength(s) < 9) return FALSE; - stream_read_BYTE(s, cache_bitmap_order->cacheId); /* cacheId (1 byte) */ - stream_seek_BYTE(s); /* pad1Octet (1 byte) */ - stream_read_BYTE(s, cache_bitmap_order->bitmapWidth); /* bitmapWidth (1 byte) */ - stream_read_BYTE(s, cache_bitmap_order->bitmapHeight); /* bitmapHeight (1 byte) */ - stream_read_BYTE(s, cache_bitmap_order->bitmapBpp); /* bitmapBpp (1 byte) */ - stream_read_UINT16(s, cache_bitmap_order->bitmapLength); /* bitmapLength (2 bytes) */ - stream_read_UINT16(s, cache_bitmap_order->cacheIndex); /* cacheIndex (2 bytes) */ + + Stream_Read_UINT8(s, cache_bitmap->cacheId); /* cacheId (1 byte) */ + Stream_Seek_UINT8(s); /* pad1Octet (1 byte) */ + Stream_Read_UINT8(s, cache_bitmap->bitmapWidth); /* bitmapWidth (1 byte) */ + Stream_Read_UINT8(s, cache_bitmap->bitmapHeight); /* bitmapHeight (1 byte) */ + Stream_Read_UINT8(s, cache_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */ + Stream_Read_UINT16(s, cache_bitmap->bitmapLength); /* bitmapLength (2 bytes) */ + Stream_Read_UINT16(s, cache_bitmap->cacheIndex); /* cacheIndex (2 bytes) */ if (compressed) { if ((flags & NO_BITMAP_COMPRESSION_HDR) == 0) { - BYTE* bitmapComprHdr = (BYTE*) &(cache_bitmap_order->bitmapComprHdr); - if (stream_get_left(s) < 8) + BYTE* bitmapComprHdr = (BYTE*) &(cache_bitmap->bitmapComprHdr); + + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */ - cache_bitmap_order->bitmapLength -= 8; + + Stream_Read(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */ + cache_bitmap->bitmapLength -= 8; } - if (stream_get_left(s) < cache_bitmap_order->bitmapLength) + if (Stream_GetRemainingLength(s) < cache_bitmap->bitmapLength) return FALSE; - stream_get_mark(s, cache_bitmap_order->bitmapDataStream); - stream_seek(s, cache_bitmap_order->bitmapLength); + Stream_GetPointer(s, cache_bitmap->bitmapDataStream); + Stream_Seek(s, cache_bitmap->bitmapLength); } else { - if (stream_get_left(s) < cache_bitmap_order->bitmapLength) + if (Stream_GetRemainingLength(s) < cache_bitmap->bitmapLength) return FALSE; - stream_get_mark(s, cache_bitmap_order->bitmapDataStream); - stream_seek(s, cache_bitmap_order->bitmapLength); /* bitmapDataStream */ + Stream_GetPointer(s, cache_bitmap->bitmapDataStream); + Stream_Seek(s, cache_bitmap->bitmapLength); /* bitmapDataStream */ } - cache_bitmap_order->compressed = compressed; + + cache_bitmap->compressed = compressed; + return TRUE; } -BOOL update_read_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, BOOL compressed, UINT16 flags) +BOOL update_write_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap, BOOL compressed, UINT16* flags) { - BYTE bitsPerPixelId; + *flags = NO_BITMAP_COMPRESSION_HDR; - cache_bitmap_v2_order->cacheId = flags & 0x0003; - cache_bitmap_v2_order->flags = (flags & 0xFF80) >> 7; + Stream_EnsureRemainingCapacity(s, 64 + cache_bitmap->bitmapLength); - bitsPerPixelId = (flags & 0x0078) >> 3; - cache_bitmap_v2_order->bitmapBpp = CBR2_BPP[bitsPerPixelId]; + if ((*flags & NO_BITMAP_COMPRESSION_HDR) == 0) + cache_bitmap->bitmapLength += 8; - if (cache_bitmap_v2_order->flags & CBR2_PERSISTENT_KEY_PRESENT) - { - if (stream_get_left(s) < 8) - return FALSE; - stream_read_UINT32(s, cache_bitmap_v2_order->key1); /* key1 (4 bytes) */ - stream_read_UINT32(s, cache_bitmap_v2_order->key2); /* key2 (4 bytes) */ - } - - if (cache_bitmap_v2_order->flags & CBR2_HEIGHT_SAME_AS_WIDTH) - { - if (!update_read_2byte_unsigned(s, &cache_bitmap_v2_order->bitmapWidth)) /* bitmapWidth */ - return FALSE; - cache_bitmap_v2_order->bitmapHeight = cache_bitmap_v2_order->bitmapWidth; - } - else - { - if (!update_read_2byte_unsigned(s, &cache_bitmap_v2_order->bitmapWidth) || /* bitmapWidth */ - !update_read_2byte_unsigned(s, &cache_bitmap_v2_order->bitmapHeight)) /* bitmapHeight */ - return FALSE; - } - - if (!update_read_4byte_unsigned(s, &cache_bitmap_v2_order->bitmapLength) || /* bitmapLength */ - !update_read_2byte_unsigned(s, &cache_bitmap_v2_order->cacheIndex)) /* cacheIndex */ - return FALSE; - - if (cache_bitmap_v2_order->flags & CBR2_DO_NOT_CACHE) - cache_bitmap_v2_order->cacheIndex = BITMAP_CACHE_WAITING_LIST_INDEX; + Stream_Write_UINT8(s, cache_bitmap->cacheId); /* cacheId (1 byte) */ + Stream_Write_UINT8(s, 0); /* pad1Octet (1 byte) */ + Stream_Write_UINT8(s, cache_bitmap->bitmapWidth); /* bitmapWidth (1 byte) */ + Stream_Write_UINT8(s, cache_bitmap->bitmapHeight); /* bitmapHeight (1 byte) */ + Stream_Write_UINT8(s, cache_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */ + Stream_Write_UINT16(s, cache_bitmap->bitmapLength); /* bitmapLength (2 bytes) */ + Stream_Write_UINT16(s, cache_bitmap->cacheIndex); /* cacheIndex (2 bytes) */ if (compressed) { - if (!(cache_bitmap_v2_order->flags & CBR2_NO_BITMAP_COMPRESSION_HDR)) + if ((*flags & NO_BITMAP_COMPRESSION_HDR) == 0) { - if (stream_get_left(s) < 8) - return FALSE; - - stream_read_UINT16(s, cache_bitmap_v2_order->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ - stream_read_UINT16(s, cache_bitmap_v2_order->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */ - stream_read_UINT16(s, cache_bitmap_v2_order->cbScanWidth); /* cbScanWidth (2 bytes) */ - stream_read_UINT16(s, cache_bitmap_v2_order->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */ - cache_bitmap_v2_order->bitmapLength = cache_bitmap_v2_order->cbCompMainBodySize; + BYTE* bitmapComprHdr = (BYTE*) &(cache_bitmap->bitmapComprHdr); + Stream_Write(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */ + cache_bitmap->bitmapLength -= 8; } - if (stream_get_left(s) < cache_bitmap_v2_order->bitmapLength) - return FALSE; - stream_get_mark(s, cache_bitmap_v2_order->bitmapDataStream); - stream_seek(s, cache_bitmap_v2_order->bitmapLength); + Stream_Write(s, cache_bitmap->bitmapDataStream, cache_bitmap->bitmapLength); } else { - if (stream_get_left(s) < cache_bitmap_v2_order->bitmapLength) - return FALSE; - stream_get_mark(s, cache_bitmap_v2_order->bitmapDataStream); - stream_seek(s, cache_bitmap_v2_order->bitmapLength); + Stream_Write(s, cache_bitmap->bitmapDataStream, cache_bitmap->bitmapLength); } - cache_bitmap_v2_order->compressed = compressed; + return TRUE; } -BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order, BOOL compressed, UINT16 flags) +BOOL update_read_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2, BOOL compressed, UINT16 flags) +{ + BYTE bitsPerPixelId; + + cache_bitmap_v2->cacheId = flags & 0x0003; + cache_bitmap_v2->flags = (flags & 0xFF80) >> 7; + + bitsPerPixelId = (flags & 0x0078) >> 3; + cache_bitmap_v2->bitmapBpp = CBR2_BPP[bitsPerPixelId]; + + if (cache_bitmap_v2->flags & CBR2_PERSISTENT_KEY_PRESENT) + { + if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT32(s, cache_bitmap_v2->key1); /* key1 (4 bytes) */ + Stream_Read_UINT32(s, cache_bitmap_v2->key2); /* key2 (4 bytes) */ + } + + if (cache_bitmap_v2->flags & CBR2_HEIGHT_SAME_AS_WIDTH) + { + if (!update_read_2byte_unsigned(s, &cache_bitmap_v2->bitmapWidth)) /* bitmapWidth */ + return FALSE; + + cache_bitmap_v2->bitmapHeight = cache_bitmap_v2->bitmapWidth; + } + else + { + if (!update_read_2byte_unsigned(s, &cache_bitmap_v2->bitmapWidth) || /* bitmapWidth */ + !update_read_2byte_unsigned(s, &cache_bitmap_v2->bitmapHeight)) /* bitmapHeight */ + return FALSE; + } + + if (!update_read_4byte_unsigned(s, &cache_bitmap_v2->bitmapLength) || /* bitmapLength */ + !update_read_2byte_unsigned(s, &cache_bitmap_v2->cacheIndex)) /* cacheIndex */ + return FALSE; + + if (cache_bitmap_v2->flags & CBR2_DO_NOT_CACHE) + cache_bitmap_v2->cacheIndex = BITMAP_CACHE_WAITING_LIST_INDEX; + + if (compressed) + { + if (!(cache_bitmap_v2->flags & CBR2_NO_BITMAP_COMPRESSION_HDR)) + { + if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT16(s, cache_bitmap_v2->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ + Stream_Read_UINT16(s, cache_bitmap_v2->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */ + Stream_Read_UINT16(s, cache_bitmap_v2->cbScanWidth); /* cbScanWidth (2 bytes) */ + Stream_Read_UINT16(s, cache_bitmap_v2->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */ + cache_bitmap_v2->bitmapLength = cache_bitmap_v2->cbCompMainBodySize; + } + + if (Stream_GetRemainingLength(s) < cache_bitmap_v2->bitmapLength) + return FALSE; + + Stream_GetPointer(s, cache_bitmap_v2->bitmapDataStream); + Stream_Seek(s, cache_bitmap_v2->bitmapLength); + } + else + { + if (Stream_GetRemainingLength(s) < cache_bitmap_v2->bitmapLength) + return FALSE; + + Stream_GetPointer(s, cache_bitmap_v2->bitmapDataStream); + Stream_Seek(s, cache_bitmap_v2->bitmapLength); + } + + cache_bitmap_v2->compressed = compressed; + + return TRUE; +} + +BOOL update_write_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2, BOOL compressed, UINT16* flags) +{ + BYTE bitsPerPixelId; + + Stream_EnsureRemainingCapacity(s, 64 + cache_bitmap_v2->bitmapLength); + + bitsPerPixelId = BPP_CBR2[cache_bitmap_v2->bitmapBpp]; + + *flags = (cache_bitmap_v2->cacheId & 0x0003) | + (bitsPerPixelId << 3) | ((cache_bitmap_v2->flags << 7) & 0xFF80); + + if (cache_bitmap_v2->flags & CBR2_PERSISTENT_KEY_PRESENT) + { + Stream_Write_UINT32(s, cache_bitmap_v2->key1); /* key1 (4 bytes) */ + Stream_Write_UINT32(s, cache_bitmap_v2->key2); /* key2 (4 bytes) */ + } + + if (cache_bitmap_v2->flags & CBR2_HEIGHT_SAME_AS_WIDTH) + { + if (!update_write_2byte_unsigned(s, cache_bitmap_v2->bitmapWidth)) /* bitmapWidth */ + return FALSE; + } + else + { + if (!update_write_2byte_unsigned(s, cache_bitmap_v2->bitmapWidth) || /* bitmapWidth */ + !update_write_2byte_unsigned(s, cache_bitmap_v2->bitmapHeight)) /* bitmapHeight */ + return FALSE; + } + + if (cache_bitmap_v2->flags & CBR2_DO_NOT_CACHE) + cache_bitmap_v2->cacheIndex = BITMAP_CACHE_WAITING_LIST_INDEX; + + if (!update_write_4byte_unsigned(s, cache_bitmap_v2->bitmapLength) || /* bitmapLength */ + !update_write_2byte_unsigned(s, cache_bitmap_v2->cacheIndex)) /* cacheIndex */ + return FALSE; + + if (compressed) + { + if (!(cache_bitmap_v2->flags & CBR2_NO_BITMAP_COMPRESSION_HDR)) + { + Stream_Write_UINT16(s, cache_bitmap_v2->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ + Stream_Write_UINT16(s, cache_bitmap_v2->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */ + Stream_Write_UINT16(s, cache_bitmap_v2->cbScanWidth); /* cbScanWidth (2 bytes) */ + Stream_Write_UINT16(s, cache_bitmap_v2->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */ + cache_bitmap_v2->bitmapLength = cache_bitmap_v2->cbCompMainBodySize; + } + + Stream_EnsureRemainingCapacity(s, cache_bitmap_v2->bitmapLength); + Stream_Write(s, cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapLength); + } + else + { + Stream_EnsureRemainingCapacity(s, cache_bitmap_v2->bitmapLength); + Stream_Write(s, cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapLength); + } + + cache_bitmap_v2->compressed = compressed; + + return TRUE; +} + +BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3, UINT16 flags) { BYTE bitsPerPixelId; BITMAP_DATA_EX* bitmapData; - cache_bitmap_v3_order->cacheId = flags & 0x00000003; - cache_bitmap_v3_order->flags = (flags & 0x0000FF80) >> 7; + cache_bitmap_v3->cacheId = flags & 0x00000003; + cache_bitmap_v3->flags = (flags & 0x0000FF80) >> 7; bitsPerPixelId = (flags & 0x00000078) >> 3; - cache_bitmap_v3_order->bpp = CBR23_BPP[bitsPerPixelId]; + cache_bitmap_v3->bpp = CBR23_BPP[bitsPerPixelId]; - if (stream_get_left(s) < 21) + if (Stream_GetRemainingLength(s) < 21) return FALSE; - stream_read_UINT16(s, cache_bitmap_v3_order->cacheIndex); /* cacheIndex (2 bytes) */ - stream_read_UINT32(s, cache_bitmap_v3_order->key1); /* key1 (4 bytes) */ - stream_read_UINT32(s, cache_bitmap_v3_order->key2); /* key2 (4 bytes) */ - bitmapData = &cache_bitmap_v3_order->bitmapData; + Stream_Read_UINT16(s, cache_bitmap_v3->cacheIndex); /* cacheIndex (2 bytes) */ + Stream_Read_UINT32(s, cache_bitmap_v3->key1); /* key1 (4 bytes) */ + Stream_Read_UINT32(s, cache_bitmap_v3->key2); /* key2 (4 bytes) */ - stream_read_BYTE(s, bitmapData->bpp); - stream_seek_BYTE(s); /* reserved1 (1 byte) */ - stream_seek_BYTE(s); /* reserved2 (1 byte) */ - stream_read_BYTE(s, bitmapData->codecID); /* codecID (1 byte) */ - stream_read_UINT16(s, bitmapData->width); /* width (2 bytes) */ - stream_read_UINT16(s, bitmapData->height); /* height (2 bytes) */ - stream_read_UINT32(s, bitmapData->length); /* length (4 bytes) */ + bitmapData = &cache_bitmap_v3->bitmapData; - if (stream_get_left(s) < bitmapData->length) + Stream_Read_UINT8(s, bitmapData->bpp); + Stream_Seek_UINT8(s); /* reserved1 (1 byte) */ + Stream_Seek_UINT8(s); /* reserved2 (1 byte) */ + Stream_Read_UINT8(s, bitmapData->codecID); /* codecID (1 byte) */ + Stream_Read_UINT16(s, bitmapData->width); /* width (2 bytes) */ + Stream_Read_UINT16(s, bitmapData->height); /* height (2 bytes) */ + Stream_Read_UINT32(s, bitmapData->length); /* length (4 bytes) */ + + if (Stream_GetRemainingLength(s) < bitmapData->length) return FALSE; + if (bitmapData->data == NULL) bitmapData->data = (BYTE*) malloc(bitmapData->length); else bitmapData->data = (BYTE*) realloc(bitmapData->data, bitmapData->length); - stream_read(s, bitmapData->data, bitmapData->length); + Stream_Read(s, bitmapData->data, bitmapData->length); + return TRUE; } -BOOL update_read_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table_order, UINT16 flags) +BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3, UINT16* flags) +{ + BYTE bitsPerPixelId; + BITMAP_DATA_EX* bitmapData; + + bitmapData = &cache_bitmap_v3->bitmapData; + + Stream_EnsureRemainingCapacity(s, 64 + bitmapData->length); + + bitsPerPixelId = BPP_CBR23[cache_bitmap_v3->bpp]; + + *flags = (cache_bitmap_v3->cacheId & 0x00000003) | + ((cache_bitmap_v3->flags << 7) & 0x0000FF80) | + ((bitsPerPixelId << 3) & 0x00000078); + + Stream_Write_UINT16(s, cache_bitmap_v3->cacheIndex); /* cacheIndex (2 bytes) */ + Stream_Write_UINT32(s, cache_bitmap_v3->key1); /* key1 (4 bytes) */ + Stream_Write_UINT32(s, cache_bitmap_v3->key2); /* key2 (4 bytes) */ + + Stream_Write_UINT8(s, bitmapData->bpp); + Stream_Write_UINT8(s, 0); /* reserved1 (1 byte) */ + Stream_Write_UINT8(s, 0); /* reserved2 (1 byte) */ + Stream_Write_UINT8(s, bitmapData->codecID); /* codecID (1 byte) */ + Stream_Write_UINT16(s, bitmapData->width); /* width (2 bytes) */ + Stream_Write_UINT16(s, bitmapData->height); /* height (2 bytes) */ + Stream_Write_UINT32(s, bitmapData->length); /* length (4 bytes) */ + + Stream_Write(s, bitmapData->data, bitmapData->length); + + return TRUE; +} + +BOOL update_read_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table, UINT16 flags) { int i; UINT32* colorTable; - if (stream_get_left(s) < 3) + if (Stream_GetRemainingLength(s) < 3) return FALSE; - stream_read_BYTE(s, cache_color_table_order->cacheIndex); /* cacheIndex (1 byte) */ - stream_read_UINT16(s, cache_color_table_order->numberColors); /* numberColors (2 bytes) */ + Stream_Read_UINT8(s, cache_color_table->cacheIndex); /* cacheIndex (1 byte) */ + Stream_Read_UINT16(s, cache_color_table->numberColors); /* numberColors (2 bytes) */ - if (cache_color_table_order->numberColors != 256) + if (cache_color_table->numberColors != 256) { /* This field MUST be set to 256 */ return FALSE; } - if (stream_get_left(s) < cache_color_table_order->numberColors * 4) + if (Stream_GetRemainingLength(s) < cache_color_table->numberColors * 4) return FALSE; - colorTable = (UINT32*) &cache_color_table_order->colorTable; + colorTable = (UINT32*) &cache_color_table->colorTable; - for (i = 0; i < (int) cache_color_table_order->numberColors; i++) + for (i = 0; i < (int) cache_color_table->numberColors; i++) { update_read_color_quad(s, &colorTable[i]); } @@ -1266,68 +2009,131 @@ BOOL update_read_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* ca return TRUE; } +BOOL update_write_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table, UINT16* flags) +{ + int i; + UINT32* colorTable; + + if (cache_color_table->numberColors != 256) + return FALSE; + + Stream_EnsureRemainingCapacity(s, 16 + (256 * 4)); + + Stream_Write_UINT8(s, cache_color_table->cacheIndex); /* cacheIndex (1 byte) */ + Stream_Write_UINT16(s, cache_color_table->numberColors); /* numberColors (2 bytes) */ + + colorTable = (UINT32*) &cache_color_table->colorTable; + + for (i = 0; i < (int) cache_color_table->numberColors; i++) + { + update_write_color_quad(s, colorTable[i]); + } + + return TRUE; +} + BOOL update_read_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_order, UINT16 flags) { int i; INT16 lsi16; GLYPH_DATA* glyph; - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_BYTE(s, cache_glyph_order->cacheId); /* cacheId (1 byte) */ - stream_read_BYTE(s, cache_glyph_order->cGlyphs); /* cGlyphs (1 byte) */ + Stream_Read_UINT8(s, cache_glyph_order->cacheId); /* cacheId (1 byte) */ + Stream_Read_UINT8(s, cache_glyph_order->cGlyphs); /* cGlyphs (1 byte) */ for (i = 0; i < (int) cache_glyph_order->cGlyphs; i++) { glyph = &cache_glyph_order->glyphData[i]; - if (stream_get_left(s) < 10) + if (Stream_GetRemainingLength(s) < 10) return FALSE; - stream_read_UINT16(s, glyph->cacheIndex); - stream_read_UINT16(s, lsi16); + Stream_Read_UINT16(s, glyph->cacheIndex); + Stream_Read_UINT16(s, lsi16); glyph->x = lsi16; - stream_read_UINT16(s, lsi16); + Stream_Read_UINT16(s, lsi16); glyph->y = lsi16; - stream_read_UINT16(s, glyph->cx); - stream_read_UINT16(s, glyph->cy); + Stream_Read_UINT16(s, glyph->cx); + Stream_Read_UINT16(s, glyph->cy); glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; - if (stream_get_left(s) < glyph->cb) + if (Stream_GetRemainingLength(s) < glyph->cb) return FALSE; glyph->aj = (BYTE*) malloc(glyph->cb); - stream_read(s, glyph->aj, glyph->cb); + Stream_Read(s, glyph->aj, glyph->cb); } if (flags & CG_GLYPH_UNICODE_PRESENT) { - return stream_skip(s, cache_glyph_order->cGlyphs * 2); + return Stream_SafeSeek(s, cache_glyph_order->cGlyphs * 2); } return TRUE; } -BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order, UINT16 flags) +BOOL update_write_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph, UINT16* flags) +{ + int i; + INT16 lsi16; + GLYPH_DATA* glyph; + + Stream_EnsureRemainingCapacity(s, 2 + cache_glyph->cGlyphs * 32); + + Stream_Write_UINT8(s, cache_glyph->cacheId); /* cacheId (1 byte) */ + Stream_Write_UINT8(s, cache_glyph->cGlyphs); /* cGlyphs (1 byte) */ + + for (i = 0; i < (int) cache_glyph->cGlyphs; i++) + { + glyph = &cache_glyph->glyphData[i]; + + Stream_Write_UINT16(s, glyph->cacheIndex); /* cacheIndex (2 bytes) */ + + lsi16 = glyph->x; + Stream_Write_UINT16(s, lsi16); /* x (2 bytes) */ + + lsi16 = glyph->y; + Stream_Write_UINT16(s, lsi16); /* y (2 bytes) */ + + Stream_Write_UINT16(s, glyph->cx); /* cx (2 bytes) */ + Stream_Write_UINT16(s, glyph->cy); /* cy (2 bytes) */ + + glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; + glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; + + Stream_Write(s, glyph->aj, glyph->cb); + } + + if (*flags & CG_GLYPH_UNICODE_PRESENT) + { + Stream_Zero(s, cache_glyph->cGlyphs * 2); + } + + return TRUE; +} + +BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16 flags) { int i; GLYPH_DATA_V2* glyph; - cache_glyph_v2_order->cacheId = (flags & 0x000F); - cache_glyph_v2_order->flags = (flags & 0x00F0) >> 4; - cache_glyph_v2_order->cGlyphs = (flags & 0xFF00) >> 8; + cache_glyph_v2->cacheId = (flags & 0x000F); + cache_glyph_v2->flags = (flags & 0x00F0) >> 4; + cache_glyph_v2->cGlyphs = (flags & 0xFF00) >> 8; - for (i = 0; i < (int) cache_glyph_v2_order->cGlyphs; i++) + for (i = 0; i < (int) cache_glyph_v2->cGlyphs; i++) { - glyph = &cache_glyph_v2_order->glyphData[i]; + glyph = &cache_glyph_v2->glyphData[i]; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, glyph->cacheIndex); + Stream_Read_UINT8(s, glyph->cacheIndex); if (!update_read_2byte_signed(s, &glyph->x) || !update_read_2byte_signed(s, &glyph->y) || @@ -1340,16 +2146,54 @@ BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_gl glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; - if (stream_get_left(s) < glyph->cb) + if (Stream_GetRemainingLength(s) < glyph->cb) return FALSE; glyph->aj = (BYTE*) malloc(glyph->cb); - stream_read(s, glyph->aj, glyph->cb); + Stream_Read(s, glyph->aj, glyph->cb); } if (flags & CG_GLYPH_UNICODE_PRESENT) { - return stream_skip(s, cache_glyph_v2_order->cGlyphs * 2); + return Stream_SafeSeek(s, cache_glyph_v2->cGlyphs * 2); + } + + return TRUE; +} + +BOOL update_write_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags) +{ + int i; + GLYPH_DATA_V2* glyph; + + Stream_EnsureRemainingCapacity(s, cache_glyph_v2->cGlyphs * 32); + + *flags = (cache_glyph_v2->cacheId & 0x000F) | + ((cache_glyph_v2->flags & 0x000F) << 4) | + ((cache_glyph_v2->cGlyphs & 0x00FF) << 8); + + for (i = 0; i < (int) cache_glyph_v2->cGlyphs; i++) + { + glyph = &cache_glyph_v2->glyphData[i]; + + Stream_Write_UINT8(s, glyph->cacheIndex); + + if (!update_write_2byte_signed(s, glyph->x) || + !update_write_2byte_signed(s, glyph->y) || + !update_write_2byte_unsigned(s, glyph->cx) || + !update_write_2byte_unsigned(s, glyph->cy)) + { + return FALSE; + } + + glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; + glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; + Stream_Write(s, glyph->aj, glyph->cb); + } + + if (*flags & CG_GLYPH_UNICODE_PRESENT) + { + Stream_Zero(s, cache_glyph_v2->cGlyphs * 2); } return TRUE; @@ -1363,10 +2207,10 @@ BOOL update_decompress_brush(wStream* s, BYTE* output, BYTE bpp) BYTE* palette; int bytesPerPixel; - palette = s->pointer + 16; + palette = Stream_Pointer(s) + 16; bytesPerPixel = ((bpp + 1) / 8); - if (stream_get_left(s) < 16) // 64 / 4 + if (Stream_GetRemainingLength(s) < 16) // 64 / 4 return FALSE; for (y = 7; y >= 0; y--) @@ -1374,7 +2218,7 @@ BOOL update_decompress_brush(wStream* s, BYTE* output, BYTE bpp) for (x = 0; x < 8; x++) { if ((x % 4) == 0) - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); index = ((byte >> ((3 - (x % 4)) * 2)) & 0x03); @@ -1384,76 +2228,149 @@ BOOL update_decompress_brush(wStream* s, BYTE* output, BYTE bpp) } } } + return TRUE; } -BOOL update_read_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush_order, UINT16 flags) +BOOL update_compress_brush(wStream* s, BYTE* input, BYTE bpp) +{ + return FALSE; +} + +BOOL update_read_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush, UINT16 flags) { int i; int size; BYTE iBitmapFormat; BOOL compressed = FALSE; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) return FALSE; - stream_read_BYTE(s, cache_brush_order->index); /* cacheEntry (1 byte) */ + Stream_Read_UINT8(s, cache_brush->index); /* cacheEntry (1 byte) */ - stream_read_BYTE(s, iBitmapFormat); /* iBitmapFormat (1 byte) */ - cache_brush_order->bpp = BMF_BPP[iBitmapFormat]; + Stream_Read_UINT8(s, iBitmapFormat); /* iBitmapFormat (1 byte) */ + cache_brush->bpp = BMF_BPP[iBitmapFormat]; - stream_read_BYTE(s, cache_brush_order->cx); /* cx (1 byte) */ - stream_read_BYTE(s, cache_brush_order->cy); /* cy (1 byte) */ - stream_read_BYTE(s, cache_brush_order->style); /* style (1 byte) */ - stream_read_BYTE(s, cache_brush_order->length); /* iBytes (1 byte) */ + Stream_Read_UINT8(s, cache_brush->cx); /* cx (1 byte) */ + Stream_Read_UINT8(s, cache_brush->cy); /* cy (1 byte) */ + Stream_Read_UINT8(s, cache_brush->style); /* style (1 byte) */ + Stream_Read_UINT8(s, cache_brush->length); /* iBytes (1 byte) */ - if ((cache_brush_order->cx == 8) && (cache_brush_order->cy == 8)) + if ((cache_brush->cx == 8) && (cache_brush->cy == 8)) { - size = (cache_brush_order->bpp == 1) ? 8 : 8 * 8 * cache_brush_order->bpp; + size = (cache_brush->bpp == 1) ? 8 : 8 * 8 * cache_brush->bpp; - if (cache_brush_order->bpp == 1) + if (cache_brush->bpp == 1) { - if (cache_brush_order->length != 8) + if (cache_brush->length != 8) { - fprintf(stderr, "incompatible 1bpp brush of length:%d\n", cache_brush_order->length); + fprintf(stderr, "incompatible 1bpp brush of length:%d\n", cache_brush->length); return TRUE; // should be FALSE ? } /* rows are encoded in reverse order */ - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; for (i = 7; i >= 0; i--) { - stream_read_BYTE(s, cache_brush_order->data[i]); + Stream_Read_UINT8(s, cache_brush->data[i]); } } else { - if ((iBitmapFormat == BMF_8BPP) && (cache_brush_order->length == 20)) + if ((iBitmapFormat == BMF_8BPP) && (cache_brush->length == 20)) compressed = TRUE; - else if ((iBitmapFormat == BMF_16BPP) && (cache_brush_order->length == 24)) + else if ((iBitmapFormat == BMF_16BPP) && (cache_brush->length == 24)) compressed = TRUE; - else if ((iBitmapFormat == BMF_32BPP) && (cache_brush_order->length == 32)) + else if ((iBitmapFormat == BMF_32BPP) && (cache_brush->length == 32)) compressed = TRUE; if (compressed != FALSE) { /* compressed brush */ - if (!update_decompress_brush(s, cache_brush_order->data, cache_brush_order->bpp)) + if (!update_decompress_brush(s, cache_brush->data, cache_brush->bpp)) return FALSE; } else { /* uncompressed brush */ - int scanline = (cache_brush_order->bpp / 8) * 8; + int scanline = (cache_brush->bpp / 8) * 8; - if (stream_get_left(s) < scanline * 8) + if (Stream_GetRemainingLength(s) < scanline * 8) return FALSE; for (i = 7; i >= 0; i--) { - stream_read(s, &cache_brush_order->data[i * scanline], scanline); + Stream_Read(s, &cache_brush->data[i * scanline], scanline); + } + } + } + } + + return TRUE; +} + +BOOL update_write_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush, UINT16* flags) +{ + int i; + int size; + BYTE iBitmapFormat; + BOOL compressed = FALSE; + + Stream_EnsureRemainingCapacity(s, 64); + + iBitmapFormat = BPP_BMF[cache_brush->bpp]; + + Stream_Write_UINT8(s, cache_brush->index); /* cacheEntry (1 byte) */ + Stream_Write_UINT8(s, iBitmapFormat); /* iBitmapFormat (1 byte) */ + + Stream_Write_UINT8(s, cache_brush->cx); /* cx (1 byte) */ + Stream_Write_UINT8(s, cache_brush->cy); /* cy (1 byte) */ + Stream_Write_UINT8(s, cache_brush->style); /* style (1 byte) */ + Stream_Write_UINT8(s, cache_brush->length); /* iBytes (1 byte) */ + + 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) + { + fprintf(stderr, "incompatible 1bpp brush of length:%d\n", cache_brush->length); + return FALSE; + } + + for (i = 7; i >= 0; i--) + { + Stream_Write_UINT8(s, cache_brush->data[i]); + } + } + else + { + if ((iBitmapFormat == BMF_8BPP) && (cache_brush->length == 20)) + compressed = TRUE; + else if ((iBitmapFormat == BMF_16BPP) && (cache_brush->length == 24)) + compressed = TRUE; + else if ((iBitmapFormat == BMF_32BPP) && (cache_brush->length == 32)) + compressed = TRUE; + + if (compressed != FALSE) + { + /* compressed brush */ + if (!update_compress_brush(s, cache_brush->data, cache_brush->bpp)) + return FALSE; + } + else + { + /* uncompressed brush */ + int scanline = (cache_brush->bpp / 8) * 8; + + for (i = 7; i >= 0; i--) + { + Stream_Write(s, &cache_brush->data[i * scanline], scanline); } } } @@ -1470,22 +2387,26 @@ BOOL update_read_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITM BOOL deleteListPresent; OFFSCREEN_DELETE_LIST* deleteList; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) return FALSE; - stream_read_UINT16(s, flags); /* flags (2 bytes) */ + + Stream_Read_UINT16(s, flags); /* flags (2 bytes) */ create_offscreen_bitmap->id = flags & 0x7FFF; deleteListPresent = (flags & 0x8000) ? TRUE : FALSE; - stream_read_UINT16(s, create_offscreen_bitmap->cx); /* cx (2 bytes) */ - stream_read_UINT16(s, create_offscreen_bitmap->cy); /* cy (2 bytes) */ + Stream_Read_UINT16(s, create_offscreen_bitmap->cx); /* cx (2 bytes) */ + Stream_Read_UINT16(s, create_offscreen_bitmap->cy); /* cy (2 bytes) */ deleteList = &(create_offscreen_bitmap->deleteList); + if (deleteListPresent) { int i; - if (stream_get_left(s) < 2) + + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, deleteList->cIndices); + + Stream_Read_UINT16(s, deleteList->cIndices); if (deleteList->cIndices > deleteList->sIndices) { @@ -1493,26 +2414,75 @@ BOOL update_read_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITM deleteList->indices = realloc(deleteList->indices, deleteList->sIndices * 2); } - if (stream_get_left(s) < 2 * deleteList->cIndices) + if (Stream_GetRemainingLength(s) < 2 * deleteList->cIndices) return FALSE; for (i = 0; i < (int) deleteList->cIndices; i++) { - stream_read_UINT16(s, deleteList->indices[i]); + Stream_Read_UINT16(s, deleteList->indices[i]); } } else { deleteList->cIndices = 0; } + + return TRUE; +} + +BOOL update_write_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap) +{ + UINT16 flags; + BOOL deleteListPresent; + OFFSCREEN_DELETE_LIST* deleteList; + + deleteList = &(create_offscreen_bitmap->deleteList); + + Stream_EnsureRemainingCapacity(s, 8 + deleteList->cIndices * 2); + + flags = create_offscreen_bitmap->id & 0x7FFF; + + deleteListPresent = (deleteList->cIndices > 0) ? TRUE : FALSE; + + if (deleteListPresent) + flags |= 0x8000; + + Stream_Write_UINT16(s, flags); /* flags (2 bytes) */ + + Stream_Write_UINT16(s, create_offscreen_bitmap->cx); /* cx (2 bytes) */ + Stream_Write_UINT16(s, create_offscreen_bitmap->cy); /* cy (2 bytes) */ + + if (deleteListPresent) + { + int i; + + Stream_Write_UINT16(s, deleteList->cIndices); + + for (i = 0; i < (int) deleteList->cIndices; i++) + { + Stream_Write_UINT16(s, deleteList->indices[i]); + } + } + return TRUE; } BOOL update_read_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface) { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, switch_surface->bitmapId); /* bitmapId (2 bytes) */ + + Stream_Read_UINT16(s, switch_surface->bitmapId); /* bitmapId (2 bytes) */ + + return TRUE; +} + +BOOL update_write_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface) +{ + Stream_EnsureRemainingCapacity(s, 2); + + Stream_Write_UINT16(s, switch_surface->bitmapId); /* bitmapId (2 bytes) */ + return TRUE; } @@ -1520,132 +2490,194 @@ BOOL update_read_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITM { NINE_GRID_BITMAP_INFO* nineGridInfo; - if (stream_get_left(s) < 19) + if (Stream_GetRemainingLength(s) < 19) return FALSE; - stream_read_BYTE(s, create_nine_grid_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */ - stream_read_UINT16(s, create_nine_grid_bitmap->bitmapId); /* bitmapId (2 bytes) */ + + Stream_Read_UINT8(s, create_nine_grid_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */ + Stream_Read_UINT16(s, create_nine_grid_bitmap->bitmapId); /* bitmapId (2 bytes) */ nineGridInfo = &(create_nine_grid_bitmap->nineGridInfo); - stream_read_UINT32(s, nineGridInfo->flFlags); /* flFlags (4 bytes) */ - stream_read_UINT16(s, nineGridInfo->ulLeftWidth); /* ulLeftWidth (2 bytes) */ - stream_read_UINT16(s, nineGridInfo->ulRightWidth); /* ulRightWidth (2 bytes) */ - stream_read_UINT16(s, nineGridInfo->ulTopHeight); /* ulTopHeight (2 bytes) */ - stream_read_UINT16(s, nineGridInfo->ulBottomHeight); /* ulBottomHeight (2 bytes) */ + Stream_Read_UINT32(s, nineGridInfo->flFlags); /* flFlags (4 bytes) */ + Stream_Read_UINT16(s, nineGridInfo->ulLeftWidth); /* ulLeftWidth (2 bytes) */ + Stream_Read_UINT16(s, nineGridInfo->ulRightWidth); /* ulRightWidth (2 bytes) */ + Stream_Read_UINT16(s, nineGridInfo->ulTopHeight); /* ulTopHeight (2 bytes) */ + Stream_Read_UINT16(s, nineGridInfo->ulBottomHeight); /* ulBottomHeight (2 bytes) */ update_read_colorref(s, &nineGridInfo->crTransparent); /* crTransparent (4 bytes) */ return TRUE; } BOOL update_read_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, frame_marker->action); /* action (4 bytes) */ + Stream_Read_UINT32(s, frame_marker->action); /* action (4 bytes) */ + return TRUE; +} + +BOOL update_write_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker) +{ return TRUE; } BOOL update_read_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first) { - if (stream_get_left(s) < 10) // 8 + 2 at least + if (Stream_GetRemainingLength(s) < 10) // 8 + 2 at least return FALSE; - stream_read_BYTE(s, stream_bitmap_first->bitmapFlags); /* bitmapFlags (1 byte) */ - stream_read_BYTE(s, stream_bitmap_first->bitmapBpp); /* bitmapBpp (1 byte) */ - stream_read_UINT16(s, stream_bitmap_first->bitmapType); /* bitmapType (2 bytes) */ - stream_read_UINT16(s, stream_bitmap_first->bitmapWidth); /* bitmapWidth (2 bytes) */ - stream_read_UINT16(s, stream_bitmap_first->bitmapHeight); /* bitmapHeigth (2 bytes) */ - if (stream_bitmap_first->bitmapFlags & STREAM_BITMAP_V2) { - if (stream_get_left(s) < 4) + Stream_Read_UINT8(s, stream_bitmap_first->bitmapFlags); /* bitmapFlags (1 byte) */ + Stream_Read_UINT8(s, stream_bitmap_first->bitmapBpp); /* bitmapBpp (1 byte) */ + Stream_Read_UINT16(s, stream_bitmap_first->bitmapType); /* bitmapType (2 bytes) */ + Stream_Read_UINT16(s, stream_bitmap_first->bitmapWidth); /* bitmapWidth (2 bytes) */ + Stream_Read_UINT16(s, stream_bitmap_first->bitmapHeight); /* bitmapHeigth (2 bytes) */ + + if (stream_bitmap_first->bitmapFlags & STREAM_BITMAP_V2) + { + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, stream_bitmap_first->bitmapSize); /* bitmapSize (4 bytes) */ - } else { - if (stream_get_left(s) < 2) + + Stream_Read_UINT32(s, stream_bitmap_first->bitmapSize); /* bitmapSize (4 bytes) */ + } + else + { + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, stream_bitmap_first->bitmapSize); /* bitmapSize (2 bytes) */ + + Stream_Read_UINT16(s, stream_bitmap_first->bitmapSize); /* bitmapSize (2 bytes) */ } FIELD_SKIP_BUFFER16(s, stream_bitmap_first->bitmapBlockSize); /* bitmapBlockSize(2 bytes) + bitmapBlock */ + + return TRUE; +} + +BOOL update_write_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first) +{ return TRUE; } BOOL update_read_stream_bitmap_next_order(wStream* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next) { - if (stream_get_left(s) < 5) + if (Stream_GetRemainingLength(s) < 5) return FALSE; - stream_read_BYTE(s, stream_bitmap_next->bitmapFlags); /* bitmapFlags (1 byte) */ - stream_read_UINT16(s, stream_bitmap_next->bitmapType); /* bitmapType (2 bytes) */ + + Stream_Read_UINT8(s, stream_bitmap_next->bitmapFlags); /* bitmapFlags (1 byte) */ + Stream_Read_UINT16(s, stream_bitmap_next->bitmapType); /* bitmapType (2 bytes) */ FIELD_SKIP_BUFFER16(s, stream_bitmap_next->bitmapBlockSize); /* bitmapBlockSize(2 bytes) + bitmapBlock */ + + return TRUE; +} + +BOOL update_write_stream_bitmap_next_order(wStream* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next) +{ return TRUE; } BOOL update_read_draw_gdiplus_first_order(wStream* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first) { - if (stream_get_left(s) < 11) + if (Stream_GetRemainingLength(s) < 11) return FALSE; - stream_seek_BYTE(s); /* pad1Octet (1 byte) */ - stream_read_UINT16(s, draw_gdiplus_first->cbSize); /* cbSize (2 bytes) */ - stream_read_UINT32(s, draw_gdiplus_first->cbTotalSize); /* cbTotalSize (4 bytes) */ - stream_read_UINT32(s, draw_gdiplus_first->cbTotalEmfSize); /* cbTotalEmfSize (4 bytes) */ - return stream_skip(s, draw_gdiplus_first->cbSize); /* emfRecords */ + Stream_Seek_UINT8(s); /* pad1Octet (1 byte) */ + Stream_Read_UINT16(s, draw_gdiplus_first->cbSize); /* cbSize (2 bytes) */ + Stream_Read_UINT32(s, draw_gdiplus_first->cbTotalSize); /* cbTotalSize (4 bytes) */ + Stream_Read_UINT32(s, draw_gdiplus_first->cbTotalEmfSize); /* cbTotalEmfSize (4 bytes) */ + + return Stream_SafeSeek(s, draw_gdiplus_first->cbSize); /* emfRecords */ +} + +BOOL update_write_draw_gdiplus_first_order(wStream* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first) +{ + return TRUE; } BOOL update_read_draw_gdiplus_next_order(wStream* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next) { - if (stream_get_left(s) < 3) + if (Stream_GetRemainingLength(s) < 3) return FALSE; - stream_seek_BYTE(s); /* pad1Octet (1 byte) */ + + Stream_Seek_UINT8(s); /* pad1Octet (1 byte) */ FIELD_SKIP_BUFFER16(s, draw_gdiplus_next->cbSize); /* cbSize(2 bytes) + emfRecords */ + + return TRUE; +} + +BOOL update_write_draw_gdiplus_next_order(wStream* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next) +{ return TRUE; } BOOL update_read_draw_gdiplus_end_order(wStream* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end) { - if (stream_get_left(s) < 11) + if (Stream_GetRemainingLength(s) < 11) return FALSE; - stream_seek_BYTE(s); /* pad1Octet (1 byte) */ - stream_read_UINT16(s, draw_gdiplus_end->cbSize); /* cbSize (2 bytes) */ - stream_read_UINT32(s, draw_gdiplus_end->cbTotalSize); /* cbTotalSize (4 bytes) */ - stream_read_UINT32(s, draw_gdiplus_end->cbTotalEmfSize); /* cbTotalEmfSize (4 bytes) */ - return stream_skip(s, draw_gdiplus_end->cbSize); /* emfRecords */ + Stream_Seek_UINT8(s); /* pad1Octet (1 byte) */ + Stream_Read_UINT16(s, draw_gdiplus_end->cbSize); /* cbSize (2 bytes) */ + Stream_Read_UINT32(s, draw_gdiplus_end->cbTotalSize); /* cbTotalSize (4 bytes) */ + Stream_Read_UINT32(s, draw_gdiplus_end->cbTotalEmfSize); /* cbTotalEmfSize (4 bytes) */ + + return Stream_SafeSeek(s, draw_gdiplus_end->cbSize); /* emfRecords */ +} + +BOOL update_write_draw_gdiplus_end_order(wStream* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end) +{ + return TRUE; } BOOL update_read_draw_gdiplus_cache_first_order(wStream* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first) { - if (stream_get_left(s) < 11) + if (Stream_GetRemainingLength(s) < 11) return FALSE; - stream_read_BYTE(s, draw_gdiplus_cache_first->flags); /* flags (1 byte) */ - stream_read_UINT16(s, draw_gdiplus_cache_first->cacheType); /* cacheType (2 bytes) */ - stream_read_UINT16(s, draw_gdiplus_cache_first->cacheIndex); /* cacheIndex (2 bytes) */ - stream_read_UINT16(s, draw_gdiplus_cache_first->cbSize); /* cbSize (2 bytes) */ - stream_read_UINT32(s, draw_gdiplus_cache_first->cbTotalSize); /* cbTotalSize (4 bytes) */ - return stream_skip(s, draw_gdiplus_cache_first->cbSize); /* emfRecords */ + Stream_Read_UINT8(s, draw_gdiplus_cache_first->flags); /* flags (1 byte) */ + Stream_Read_UINT16(s, draw_gdiplus_cache_first->cacheType); /* cacheType (2 bytes) */ + Stream_Read_UINT16(s, draw_gdiplus_cache_first->cacheIndex); /* cacheIndex (2 bytes) */ + Stream_Read_UINT16(s, draw_gdiplus_cache_first->cbSize); /* cbSize (2 bytes) */ + Stream_Read_UINT32(s, draw_gdiplus_cache_first->cbTotalSize); /* cbTotalSize (4 bytes) */ + + return Stream_SafeSeek(s, draw_gdiplus_cache_first->cbSize); /* emfRecords */ +} + +BOOL update_write_draw_gdiplus_cache_first_order(wStream* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first) +{ + return TRUE; } BOOL update_read_draw_gdiplus_cache_next_order(wStream* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next) { - if (stream_get_left(s) < 7) + if (Stream_GetRemainingLength(s) < 7) return FALSE; - stream_read_BYTE(s, draw_gdiplus_cache_next->flags); /* flags (1 byte) */ - stream_read_UINT16(s, draw_gdiplus_cache_next->cacheType); /* cacheType (2 bytes) */ - stream_read_UINT16(s, draw_gdiplus_cache_next->cacheIndex); /* cacheIndex (2 bytes) */ - FIELD_SKIP_BUFFER16(s, draw_gdiplus_cache_next->cbSize); /* cbSize(2 bytes) + emfRecords */ - return TRUE; + Stream_Read_UINT8(s, draw_gdiplus_cache_next->flags); /* flags (1 byte) */ + Stream_Read_UINT16(s, draw_gdiplus_cache_next->cacheType); /* cacheType (2 bytes) */ + Stream_Read_UINT16(s, draw_gdiplus_cache_next->cacheIndex); /* cacheIndex (2 bytes) */ + FIELD_SKIP_BUFFER16(s, draw_gdiplus_cache_next->cbSize); /* cbSize(2 bytes) + emfRecords */ + + return TRUE; +} + +BOOL update_write_draw_gdiplus_cache_next_order(wStream* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next) +{ + return TRUE; } BOOL update_read_draw_gdiplus_cache_end_order(wStream* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end) { - if (stream_get_left(s) < 11) + if (Stream_GetRemainingLength(s) < 11) return FALSE; - stream_read_BYTE(s, draw_gdiplus_cache_end->flags); /* flags (1 byte) */ - stream_read_UINT16(s, draw_gdiplus_cache_end->cacheType); /* cacheType (2 bytes) */ - stream_read_UINT16(s, draw_gdiplus_cache_end->cacheIndex); /* cacheIndex (2 bytes) */ - stream_read_UINT16(s, draw_gdiplus_cache_end->cbSize); /* cbSize (2 bytes) */ - stream_read_UINT32(s, draw_gdiplus_cache_end->cbTotalSize); /* cbTotalSize (4 bytes) */ - return stream_skip(s, draw_gdiplus_cache_end->cbSize); /* emfRecords */ + Stream_Read_UINT8(s, draw_gdiplus_cache_end->flags); /* flags (1 byte) */ + Stream_Read_UINT16(s, draw_gdiplus_cache_end->cacheType); /* cacheType (2 bytes) */ + Stream_Read_UINT16(s, draw_gdiplus_cache_end->cacheIndex); /* cacheIndex (2 bytes) */ + Stream_Read_UINT16(s, draw_gdiplus_cache_end->cbSize); /* cbSize (2 bytes) */ + Stream_Read_UINT32(s, draw_gdiplus_cache_end->cbTotalSize); /* cbTotalSize (4 bytes) */ + + return Stream_SafeSeek(s, draw_gdiplus_cache_end->cbSize); /* emfRecords */ +} + +BOOL update_write_draw_gdiplus_cache_end_order(wStream* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end) +{ + return TRUE; } BOOL update_read_field_flags(wStream* s, UINT32* fieldFlags, BYTE flags, BYTE fieldBytes) @@ -1664,15 +2696,49 @@ BOOL update_read_field_flags(wStream* s, UINT32* fieldFlags, BYTE flags, BYTE fi fieldBytes = 0; } - if (stream_get_left(s) < fieldBytes) + if (Stream_GetRemainingLength(s) < fieldBytes) return FALSE; *fieldFlags = 0; for (i = 0; i < fieldBytes; i++) { - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *fieldFlags |= byte << (i * 8); } + + return TRUE; +} + +BOOL update_write_field_flags(wStream* s, UINT32 fieldFlags, BYTE flags, BYTE fieldBytes) +{ + BYTE byte; + + if (fieldBytes == 1) + { + byte = fieldFlags & 0xFF; + Stream_Write_UINT8(s, byte); + } + else if (fieldBytes == 2) + { + byte = fieldFlags & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (fieldFlags >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + } + else if (fieldBytes == 3) + { + byte = fieldFlags & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (fieldFlags >> 8) & 0xFF; + Stream_Write_UINT8(s, byte); + byte = (fieldFlags >> 16) & 0xFF; + Stream_Write_UINT8(s, byte); + } + else + { + return FALSE; + } + return TRUE; } @@ -1680,9 +2746,10 @@ BOOL update_read_bounds(wStream* s, rdpBounds* bounds) { BYTE flags; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, flags); /* field flags */ + + Stream_Read_UINT8(s, flags); /* field flags */ if (flags & BOUND_LEFT) { @@ -1727,6 +2794,60 @@ BOOL update_read_bounds(wStream* s, rdpBounds* bounds) if (!update_read_coord(s, &bounds->bottom, TRUE)) return FALSE; } + + return TRUE; +} + +BOOL update_write_bounds(wStream* s, ORDER_INFO* orderInfo) +{ + if (!(orderInfo->controlFlags & ORDER_BOUNDS)) + return TRUE; + + if (orderInfo->controlFlags & ORDER_ZERO_BOUNDS_DELTAS) + return TRUE; + + Stream_Write_UINT8(s, orderInfo->boundsFlags); /* field flags */ + + if (orderInfo->boundsFlags & BOUND_LEFT) + { + if (!update_write_coord(s, orderInfo->bounds.left)) + return FALSE; + } + else if (orderInfo->boundsFlags & BOUND_DELTA_LEFT) + { + + } + + if (orderInfo->boundsFlags & BOUND_TOP) + { + if (!update_write_coord(s, orderInfo->bounds.top)) + return FALSE; + } + else if (orderInfo->boundsFlags & BOUND_DELTA_TOP) + { + + } + + if (orderInfo->boundsFlags & BOUND_RIGHT) + { + if (!update_write_coord(s, orderInfo->bounds.right)) + return FALSE; + } + else if (orderInfo->boundsFlags & BOUND_DELTA_RIGHT) + { + + } + + if (orderInfo->boundsFlags & BOUND_BOTTOM) + { + if (!update_write_coord(s, orderInfo->bounds.bottom)) + return FALSE; + } + else if (orderInfo->boundsFlags & BOUND_DELTA_BOTTOM) + { + + } + return TRUE; } @@ -1739,7 +2860,7 @@ BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags) orderInfo = &(primary->order_info); if (flags & ORDER_TYPE_CHANGE) - stream_read_BYTE(s, orderInfo->orderType); /* orderType (1 byte) */ + Stream_Read_UINT8(s, orderInfo->orderType); /* orderType (1 byte) */ if (orderInfo->orderType >= PRIMARY_DRAWING_ORDER_COUNT) { @@ -1923,13 +3044,14 @@ BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) rdpContext* context = update->context; rdpSecondaryUpdate* secondary = update->secondary; - if (stream_get_left(s) < 5) + if (Stream_GetRemainingLength(s) < 5) return FALSE; - stream_read_UINT16(s, orderLength); /* orderLength (2 bytes) */ - stream_read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ - stream_read_BYTE(s, orderType); /* orderType (1 byte) */ - next = s->pointer + ((INT16) orderLength) + 7; + Stream_Read_UINT16(s, orderLength); /* orderLength (2 bytes) */ + Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ + Stream_Read_UINT8(s, orderType); /* orderType (1 byte) */ + + next = Stream_Pointer(s) + ((INT16) orderLength) + 7; #ifdef WITH_DEBUG_ORDERS if (orderType < SECONDARY_DRAWING_ORDER_COUNT) @@ -1965,7 +3087,7 @@ BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) break; case ORDER_TYPE_BITMAP_COMPRESSED_V3: - if (!update_read_cache_bitmap_v3_order(s, &(secondary->cache_bitmap_v3_order), TRUE, extraFlags)) + if (!update_read_cache_bitmap_v3_order(s, &(secondary->cache_bitmap_v3_order), extraFlags)) return FALSE; IFCALL(secondary->CacheBitmapV3, context, &(secondary->cache_bitmap_v3_order)); break; @@ -2001,7 +3123,8 @@ BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) break; } - s->pointer = next; + Stream_Pointer(s) = next; + return TRUE; } @@ -2111,10 +3234,10 @@ BOOL update_recv_order(rdpUpdate* update, wStream* s) { BYTE controlFlags; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, controlFlags); /* controlFlags (1 byte) */ + Stream_Read_UINT8(s, controlFlags); /* controlFlags (1 byte) */ if (!(controlFlags & ORDER_STANDARD)) return update_recv_altsec_order(update, s, controlFlags); diff --git a/libfreerdp/core/orders.h b/libfreerdp/core/orders.h index d8f807394..7860694fa 100644 --- a/libfreerdp/core/orders.h +++ b/libfreerdp/core/orders.h @@ -188,48 +188,95 @@ BOOL update_recv_order(rdpUpdate* update, wStream* s); +BOOL update_read_field_flags(wStream* s, UINT32* fieldFlags, BYTE flags, BYTE fieldBytes); +BOOL update_write_field_flags(wStream* s, UINT32 fieldFlags, BYTE flags, BYTE fieldBytes); + +BOOL update_read_bounds(wStream* s, rdpBounds* bounds); +BOOL update_write_bounds(wStream* s, ORDER_INFO* orderInfo); + BOOL update_read_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt); +BOOL update_write_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt); BOOL update_read_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt); +BOOL update_write_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt); BOOL update_read_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt); +BOOL update_write_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt); BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect); +BOOL update_write_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect); BOOL update_read_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid); +BOOL update_write_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid); BOOL update_read_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt); +BOOL update_write_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt); BOOL update_read_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt); +BOOL update_write_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt); BOOL update_read_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt); +BOOL update_write_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt); BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect); +BOOL update_write_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect); BOOL update_read_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid); +BOOL update_write_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid); BOOL update_read_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to); +BOOL update_write_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to); BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline); +BOOL update_write_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline); BOOL update_read_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt); +BOOL update_write_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt); BOOL update_read_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt); +BOOL update_write_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt); BOOL update_read_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap); +BOOL update_write_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap); BOOL update_read_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index); +BOOL update_write_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index); BOOL update_read_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index); +BOOL update_write_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index); BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph); +BOOL update_write_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph); BOOL update_read_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc); +BOOL update_write_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc); BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb); +BOOL update_write_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb); BOOL update_read_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc); +BOOL update_write_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc); BOOL update_read_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb); +BOOL update_write_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb); BOOL update_read_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap_order, BOOL compressed, UINT16 flags); +BOOL update_write_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap_order, BOOL compressed, UINT16* flags); BOOL update_read_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, BOOL compressed, UINT16 flags); -BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order, BOOL compressed, UINT16 flags); +BOOL update_write_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, BOOL compressed, UINT16* flags); +BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order, UINT16 flags); +BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order, UINT16* flags); BOOL update_read_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table_order, UINT16 flags); +BOOL update_write_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table_order, UINT16* flags); BOOL update_read_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_order, UINT16 flags); +BOOL update_write_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_order, UINT16* flags); BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order, UINT16 flags); +BOOL update_write_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags); BOOL update_read_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush_order, UINT16 flags); +BOOL update_write_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush_order, UINT16* flags); BOOL update_read_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap); +BOOL update_write_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap); BOOL update_read_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface); +BOOL update_write_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface); BOOL update_read_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap); +BOOL update_write_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap); BOOL update_read_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker); +BOOL update_write_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker); BOOL update_read_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first); +BOOL update_write_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first); BOOL update_read_stream_bitmap_next_order(wStream* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next); +BOOL update_write_stream_bitmap_next_order(wStream* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next); BOOL update_read_draw_gdiplus_first_order(wStream* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first); +BOOL update_write_draw_gdiplus_first_order(wStream* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first); BOOL update_read_draw_gdiplus_next_order(wStream* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next); +BOOL update_write_draw_gdiplus_next_order(wStream* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next); BOOL update_read_draw_gdiplus_end_order(wStream* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end); +BOOL update_write_draw_gdiplus_end_order(wStream* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end); BOOL update_read_draw_gdiplus_cache_first_order(wStream* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first); +BOOL update_write_draw_gdiplus_cache_first_order(wStream* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first); BOOL update_read_draw_gdiplus_cache_next_order(wStream* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next); +BOOL update_write_draw_gdiplus_cache_next_order(wStream* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next); BOOL update_read_draw_gdiplus_cache_end_order(wStream* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end); +BOOL update_write_draw_gdiplus_cache_end_order(wStream* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end); #endif /* __ORDERS_H */ diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index daeefdf1e..5e61a9f17 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -135,9 +135,9 @@ static BOOL peer_recv_data_pdu(freerdp_peer* client, wStream* s) return FALSE; case DATA_PDU_TYPE_FRAME_ACKNOWLEDGE: - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, client->ack_frame_id); + Stream_Read_UINT32(s, client->ack_frame_id); break; case DATA_PDU_TYPE_REFRESH_RECT: @@ -232,7 +232,7 @@ static int peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s) fastpath_read_header_rdp(fastpath, s, &length); - if ((length == 0) || (length > stream_get_left(s))) + if ((length == 0) || (length > Stream_GetRemainingLength(s))) { fprintf(stderr, "incorrect FastPath PDU header length %d\n", length); return -1; @@ -326,7 +326,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra) * During reactivation sequence the client might sent some input or channel data * before receiving the Deactivate All PDU. We need to process them as usual. */ - stream_set_pos(s, 0); + Stream_SetPosition(s, 0); return peer_recv_pdu(client, s); } break; @@ -380,6 +380,9 @@ void freerdp_peer_context_new(freerdp_peer* client) client->context->rdp = rdp; client->context->peer = client; + client->context->input = client->input; + client->context->update = client->update; + client->context->settings = client->settings; client->update->context = client->context; client->input->context = client->context; diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index d5ca4e2f9..2f23b895a 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -80,10 +80,10 @@ static const char* const DATA_PDU_TYPE_STRINGS[] = BOOL rdp_read_security_header(wStream* s, UINT16* flags) { /* Basic Security Header */ - if(stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT16(s, *flags); /* flags */ - stream_seek(s, 2); /* flagsHi (unused) */ + Stream_Read_UINT16(s, *flags); /* flags */ + Stream_Seek(s, 2); /* flagsHi (unused) */ return TRUE; } @@ -97,26 +97,26 @@ BOOL rdp_read_security_header(wStream* s, UINT16* flags) void rdp_write_security_header(wStream* s, UINT16 flags) { /* Basic Security Header */ - stream_write_UINT16(s, flags); /* flags */ - stream_write_UINT16(s, 0); /* flagsHi (unused) */ + Stream_Write_UINT16(s, flags); /* flags */ + Stream_Write_UINT16(s, 0); /* flagsHi (unused) */ } BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UINT16* channel_id) { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; /* Share Control Header */ - stream_read_UINT16(s, *length); /* totalLength */ + Stream_Read_UINT16(s, *length); /* totalLength */ - if (*length - 2 > stream_get_left(s)) + if (*length - 2 > Stream_GetRemainingLength(s)) return FALSE; - stream_read_UINT16(s, *type); /* pduType */ + Stream_Read_UINT16(s, *type); /* pduType */ *type &= 0x0F; /* type is in the 4 least significant bits */ if (*length > 4) - stream_read_UINT16(s, *channel_id); /* pduSource */ + Stream_Read_UINT16(s, *channel_id); /* pduSource */ else *channel_id = 0; /* Windows XP can send such short DEACTIVATE_ALL PDUs. */ @@ -128,25 +128,25 @@ void rdp_write_share_control_header(wStream* s, UINT16 length, UINT16 type, UINT length -= RDP_PACKET_HEADER_MAX_LENGTH; /* Share Control Header */ - stream_write_UINT16(s, length); /* totalLength */ - stream_write_UINT16(s, type | 0x10); /* pduType */ - stream_write_UINT16(s, channel_id); /* pduSource */ + Stream_Write_UINT16(s, length); /* totalLength */ + Stream_Write_UINT16(s, type | 0x10); /* pduType */ + Stream_Write_UINT16(s, channel_id); /* pduSource */ } BOOL rdp_read_share_data_header(wStream* s, UINT16* length, BYTE* type, UINT32* share_id, BYTE *compressed_type, UINT16 *compressed_len) { - if (stream_get_left(s) < 12) + if (Stream_GetRemainingLength(s) < 12) return FALSE; /* Share Data Header */ - stream_read_UINT32(s, *share_id); /* shareId (4 bytes) */ - stream_seek_BYTE(s); /* pad1 (1 byte) */ - stream_seek_BYTE(s); /* streamId (1 byte) */ - stream_read_UINT16(s, *length); /* uncompressedLength (2 bytes) */ - stream_read_BYTE(s, *type); /* pduType2, Data PDU Type (1 byte) */ - stream_read_BYTE(s, *compressed_type); /* compressedType (1 byte) */ - stream_read_UINT16(s, *compressed_len); /* compressedLength (2 bytes) */ + Stream_Read_UINT32(s, *share_id); /* shareId (4 bytes) */ + Stream_Seek_UINT8(s); /* pad1 (1 byte) */ + Stream_Seek_UINT8(s); /* streamId (1 byte) */ + Stream_Read_UINT16(s, *length); /* uncompressedLength (2 bytes) */ + Stream_Read_UINT8(s, *type); /* pduType2, Data PDU Type (1 byte) */ + Stream_Read_UINT8(s, *compressed_type); /* compressedType (1 byte) */ + Stream_Read_UINT16(s, *compressed_len); /* compressedLength (2 bytes) */ return TRUE; } @@ -157,23 +157,23 @@ void rdp_write_share_data_header(wStream* s, UINT16 length, BYTE type, UINT32 sh length -= RDP_SHARE_DATA_HEADER_LENGTH; /* Share Data Header */ - stream_write_UINT32(s, share_id); /* shareId (4 bytes) */ - stream_write_BYTE(s, 0); /* pad1 (1 byte) */ - stream_write_BYTE(s, STREAM_LOW); /* streamId (1 byte) */ - stream_write_UINT16(s, length); /* uncompressedLength (2 bytes) */ - stream_write_BYTE(s, type); /* pduType2, Data PDU Type (1 byte) */ - stream_write_BYTE(s, 0); /* compressedType (1 byte) */ - stream_write_UINT16(s, 0); /* compressedLength (2 bytes) */ + Stream_Write_UINT32(s, share_id); /* shareId (4 bytes) */ + Stream_Write_UINT8(s, 0); /* pad1 (1 byte) */ + Stream_Write_UINT8(s, STREAM_LOW); /* streamId (1 byte) */ + Stream_Write_UINT16(s, length); /* uncompressedLength (2 bytes) */ + Stream_Write_UINT8(s, type); /* pduType2, Data PDU Type (1 byte) */ + Stream_Write_UINT8(s, 0); /* compressedType (1 byte) */ + Stream_Write_UINT16(s, 0); /* compressedLength (2 bytes) */ } static int rdp_security_stream_init(rdpRdp* rdp, wStream* s) { if (rdp->do_crypt) { - stream_seek(s, 12); + Stream_Seek(s, 12); if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) - stream_seek(s, 4); + Stream_Seek(s, 4); rdp->sec_flags |= SEC_ENCRYPT; @@ -182,47 +182,49 @@ static int rdp_security_stream_init(rdpRdp* rdp, wStream* s) } else if (rdp->sec_flags != 0) { - stream_seek(s, 4); + Stream_Seek(s, 4); } return 0; } -/** - * Initialize an RDP packet stream.\n - * @param rdp rdp module - * @return - */ +int rdp_init_stream(rdpRdp* rdp, wStream* s) +{ + Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH); + rdp_security_stream_init(rdp, s); + return 0; +} wStream* rdp_send_stream_init(rdpRdp* rdp) { wStream* s; - s = transport_send_stream_init(rdp->transport, 2048); - stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); - rdp_security_stream_init(rdp, s); - + rdp_init_stream(rdp, s); return s; } -wStream* rdp_pdu_init(rdpRdp* rdp) +int rdp_init_stream_pdu(rdpRdp* rdp, wStream* s) { - wStream* s; - s = transport_send_stream_init(rdp->transport, 2048); - stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); + Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH); rdp_security_stream_init(rdp, s); - stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH); - return s; + Stream_Seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH); + return 0; +} + +int rdp_init_stream_data_pdu(rdpRdp* rdp, wStream* s) +{ + Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH); + rdp_security_stream_init(rdp, s); + Stream_Seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH); + Stream_Seek(s, RDP_SHARE_DATA_HEADER_LENGTH); + return 0; } wStream* rdp_data_pdu_init(rdpRdp* rdp) { wStream* s; s = transport_send_stream_init(rdp->transport, 2048); - stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); - rdp_security_stream_init(rdp, s); - stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH); - stream_seek(s, RDP_SHARE_DATA_HEADER_LENGTH); + rdp_init_stream_data_pdu(rdp, s); return s; } @@ -247,7 +249,7 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channel_id return FALSE; } - if (*length - 8 > stream_get_left(s)) + if (*length - 8 > Stream_GetRemainingLength(s)) return FALSE; if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum) @@ -262,15 +264,17 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channel_id return TRUE; } - if(stream_get_left(s) < 5) + if (Stream_GetRemainingLength(s) < 5) return FALSE; + per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ per_read_integer16(s, channel_id, 0); /* channelId */ - stream_seek(s, 1); /* dataPriority + Segmentation (0x70) */ + Stream_Seek(s, 1); /* dataPriority + Segmentation (0x70) */ - if(!per_read_length(s, length)) /* userData (OCTET_STRING) */ + if (!per_read_length(s, length)) /* userData (OCTET_STRING) */ return FALSE; - if (*length > stream_get_left(s)) + + if (*length > Stream_GetRemainingLength(s)) return FALSE; return TRUE; @@ -305,7 +309,7 @@ void rdp_write_header(rdpRdp* rdp, wStream* s, UINT16 length, UINT16 channel_id) mcs_write_domain_mcspdu_header(s, MCSPDU, length, 0); per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */ per_write_integer16(s, channel_id, 0); /* channelId */ - stream_write_BYTE(s, 0x70); /* dataPriority + segmentation */ + Stream_Write_UINT8(s, 0x70); /* dataPriority + segmentation */ /* * We always encode length in two bytes, eventhough we could use * only one byte if length <= 0x7F. It is just easier that way, @@ -313,7 +317,7 @@ void rdp_write_header(rdpRdp* rdp, wStream* s, UINT16 length, UINT16 channel_id) * the data first and then store the header. */ length = (length - RDP_PACKET_HEADER_MAX_LENGTH) | 0x8000; - stream_write_UINT16_be(s, length); /* userData (OCTET_STRING) */ + Stream_Write_UINT16_BE(s, length); /* userData (OCTET_STRING) */ } static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length) @@ -332,11 +336,11 @@ static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length) { if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { - data = s->pointer + 12; + data = Stream_Pointer(s) + 12; - length = length - (data - s->buffer); - stream_write_UINT16(s, 0x10); /* length */ - stream_write_BYTE(s, 0x1); /* TSFIPS_VERSION 1*/ + length = length - (data - Stream_Buffer(s)); + Stream_Write_UINT16(s, 0x10); /* length */ + Stream_Write_UINT8(s, 0x1); /* TSFIPS_VERSION 1*/ /* handle padding */ pad = 8 - (length % 8); @@ -346,22 +350,24 @@ static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length) if (pad) memset(data+length, 0, pad); - stream_write_BYTE(s, pad); + Stream_Write_UINT8(s, pad); - security_hmac_signature(data, length, s->pointer, rdp); - stream_seek(s, 8); + security_hmac_signature(data, length, Stream_Pointer(s), rdp); + Stream_Seek(s, 8); security_fips_encrypt(data, length + pad, rdp); } else { - data = s->pointer + 8; - length = length - (data - s->buffer); + data = Stream_Pointer(s) + 8; + length = length - (data - Stream_Buffer(s)); + if (sec_flags & SEC_SECURE_CHECKSUM) - security_salted_mac_signature(rdp, data, length, TRUE, s->pointer); + security_salted_mac_signature(rdp, data, length, TRUE, Stream_Pointer(s)); else - security_mac_signature(rdp, data, length, s->pointer); - stream_seek(s, 8); - security_encrypt(s->pointer, length, rdp); + security_mac_signature(rdp, data, length, Stream_Pointer(s)); + + Stream_Seek(s, 8); + security_encrypt(Stream_Pointer(s), length, rdp); } } @@ -403,23 +409,24 @@ static UINT32 rdp_get_sec_bytes(rdpRdp* rdp) BOOL rdp_send(rdpRdp* rdp, wStream* s, UINT16 channel_id) { + int secm; UINT16 length; UINT32 sec_bytes; - BYTE* sec_hold; - length = stream_get_length(s); - stream_set_pos(s, 0); + length = Stream_GetPosition(s); + Stream_SetPosition(s, 0); rdp_write_header(rdp, s, length, channel_id); sec_bytes = rdp_get_sec_bytes(rdp); - sec_hold = s->pointer; - stream_seek(s, sec_bytes); + secm = Stream_GetPosition(s); + Stream_Seek(s, sec_bytes); - s->pointer = sec_hold; + Stream_SetPosition(s, secm); length += rdp_security_stream_out(rdp, s, length); - stream_set_pos(s, length); + Stream_SetPosition(s, length); + Stream_SealLength(s); if (transport_write(rdp->transport, s) < 0) return FALSE; @@ -431,23 +438,25 @@ BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id) { UINT16 length; UINT32 sec_bytes; - BYTE* sec_hold; + int sec_hold; - length = stream_get_length(s); - stream_set_pos(s, 0); + length = Stream_GetPosition(s); + Stream_SetPosition(s, 0); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); sec_bytes = rdp_get_sec_bytes(rdp); - sec_hold = s->pointer; - stream_seek(s, sec_bytes); + sec_hold = Stream_GetPosition(s); + Stream_Seek(s, sec_bytes); rdp_write_share_control_header(s, length - sec_bytes, type, channel_id); - s->pointer = sec_hold; + Stream_SetPosition(s, sec_hold); length += rdp_security_stream_out(rdp, s, length); - stream_set_pos(s, length); + Stream_SetPosition(s, length); + Stream_SealLength(s); + if (transport_write(rdp->transport, s) < 0) return FALSE; @@ -458,24 +467,26 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id) { UINT16 length; UINT32 sec_bytes; - BYTE* sec_hold; + int sec_hold; - length = stream_get_length(s); - stream_set_pos(s, 0); + length = Stream_GetPosition(s); + Stream_SetPosition(s, 0); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); sec_bytes = rdp_get_sec_bytes(rdp); - sec_hold = s->pointer; - stream_seek(s, sec_bytes); + sec_hold = Stream_GetPosition(s); + Stream_Seek(s, sec_bytes); rdp_write_share_control_header(s, length - sec_bytes, PDU_TYPE_DATA, channel_id); rdp_write_share_data_header(s, length - sec_bytes, type, rdp->settings->ShareId); - s->pointer = sec_hold; + Stream_SetPosition(s, sec_hold); length += rdp_security_stream_out(rdp, s, length); - stream_set_pos(s, length); + Stream_SetPosition(s, length); + Stream_SealLength(s); + if (transport_write(rdp->transport, s) < 0) return FALSE; @@ -484,53 +495,65 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id) BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, rdp->errorInfo); /* errorInfo (4 bytes) */ + Stream_Read_UINT32(s, rdp->errorInfo); /* errorInfo (4 bytes) */ if (rdp->errorInfo != ERRINFO_SUCCESS) + { + rdpClient* client = rdp->instance->context->client; + rdp_print_errinfo(rdp->errorInfo); + IFCALL(client->OnErrorInfo, rdp->instance, rdp->errorInfo); + } + return TRUE; } int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) { BYTE type; + UINT32 roff; + UINT32 rlen; + wStream* cs; + BYTE* buffer; UINT16 length; UINT32 share_id; BYTE compressed_type; UINT16 compressed_len; - UINT32 roff; - UINT32 rlen; - wStream* comp_stream; if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len)) return -1; - comp_stream = s; + cs = s; if (compressed_type & PACKET_COMPRESSED) { - if (stream_get_left(s) < compressed_len - 18) + if (Stream_GetRemainingLength(s) < compressed_len - 18) { fprintf(stderr, "decompress_rdp: not enough bytes for compressed_len=%d\n", compressed_len); return -1; } - if (decompress_rdp(rdp->mppc_dec, s->pointer, compressed_len - 18, compressed_type, &roff, &rlen)) + + if (decompress_rdp(rdp->mppc_dec, Stream_Pointer(s), compressed_len - 18, compressed_type, &roff, &rlen)) { - comp_stream = stream_new(0); - comp_stream->buffer = rdp->mppc_dec->history_buf + roff; - comp_stream->pointer = comp_stream->buffer; - comp_stream->capacity = rlen; + buffer = rdp->mppc_dec->history_buf + roff; + cs = StreamPool_Take(rdp->transport->ReceivePool, rlen); + + Stream_SetPosition(cs, 0); + Stream_Write(cs, buffer, rlen); + Stream_SealLength(cs); + Stream_SetPosition(cs, 0); } else { fprintf(stderr, "decompress_rdp() failed\n"); return -1; } - stream_seek(s, compressed_len - 18); + + Stream_Seek(s, compressed_len - 18); } #ifdef WITH_DEBUG_RDP @@ -542,17 +565,17 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) switch (type) { case DATA_PDU_TYPE_UPDATE: - if (!update_recv(rdp->update, comp_stream)) + if (!update_recv(rdp->update, cs)) return -1; break; case DATA_PDU_TYPE_CONTROL: - if (!rdp_recv_server_control_pdu(rdp, comp_stream)) + if (!rdp_recv_server_control_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_POINTER: - if (!update_recv_pointer(rdp->update, comp_stream)) + if (!update_recv_pointer(rdp->update, cs)) return -1; break; @@ -560,7 +583,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) break; case DATA_PDU_TYPE_SYNCHRONIZE: - if (!rdp_recv_synchronize_pdu(rdp, comp_stream)) + if (!rdp_recv_synchronize_pdu(rdp, cs)) return -1; break; @@ -568,7 +591,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) break; case DATA_PDU_TYPE_PLAY_SOUND: - if (!update_recv_play_sound(rdp->update, comp_stream)) + if (!update_recv_play_sound(rdp->update, cs)) return -1; break; @@ -582,7 +605,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: - if(!rdp_recv_save_session_info(rdp, comp_stream)) + if (!rdp_recv_save_session_info(rdp, cs)) return -1; break; @@ -590,7 +613,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) break; case DATA_PDU_TYPE_FONT_MAP: - if(!rdp_recv_font_map_pdu(rdp, comp_stream)) + if (!rdp_recv_font_map_pdu(rdp, cs)) return -1; break; @@ -610,7 +633,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) break; case DATA_PDU_TYPE_SET_ERROR_INFO: - if (!rdp_recv_set_error_info_data_pdu(rdp, comp_stream)) + if (!rdp_recv_set_error_info_data_pdu(rdp, cs)) return -1; break; @@ -633,11 +656,8 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) break; } - if (comp_stream != s) - { - stream_detach(comp_stream); - stream_free(comp_stream); - } + if (cs != s) + Stream_Release(cs); return 0; } @@ -683,47 +703,48 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags) BYTE version, pad; BYTE* sig; - if (stream_get_left(s) < 12) + if (Stream_GetRemainingLength(s) < 12) return FALSE; - stream_read_UINT16(s, len); /* 0x10 */ - stream_read_BYTE(s, version); /* 0x1 */ - stream_read_BYTE(s, pad); + Stream_Read_UINT16(s, len); /* 0x10 */ + Stream_Read_UINT8(s, version); /* 0x1 */ + Stream_Read_UINT8(s, pad); - sig = s->pointer; - stream_seek(s, 8); /* signature */ + sig = Stream_Pointer(s); + Stream_Seek(s, 8); /* signature */ length -= 12; - if (!security_fips_decrypt(s->pointer, length, rdp)) + if (!security_fips_decrypt(Stream_Pointer(s), length, rdp)) { fprintf(stderr, "FATAL: cannot decrypt\n"); return FALSE; /* TODO */ } - if (!security_fips_check_signature(s->pointer, length - pad, sig, rdp)) + if (!security_fips_check_signature(Stream_Pointer(s), length - pad, sig, rdp)) { fprintf(stderr, "FATAL: invalid packet signature\n"); return FALSE; /* TODO */ } /* is this what needs adjusting? */ - s->capacity -= pad; + Stream_Capacity(s) -= pad; return TRUE; } - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read(s, wmac, sizeof(wmac)); + Stream_Read(s, wmac, sizeof(wmac)); length -= sizeof(wmac); - if (!security_decrypt(s->pointer, length, rdp)) + + if (!security_decrypt(Stream_Pointer(s), length, rdp)) return FALSE; if (securityFlags & SEC_SECURE_CHECKSUM) - security_salted_mac_signature(rdp, s->pointer, length, FALSE, cmac); + security_salted_mac_signature(rdp, Stream_Pointer(s), length, FALSE, cmac); else - security_mac_signature(rdp, s->pointer, length, cmac); + security_mac_signature(rdp, Stream_Pointer(s), length, cmac); if (memcmp(wmac, cmac, sizeof(wmac)) != 0) { @@ -755,7 +776,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) UINT16 pduSource; UINT16 channelId; UINT16 securityFlags; - BYTE* nextp; + int nextPosition; if (!rdp_read_header(rdp, s, &length, &channelId)) { @@ -783,7 +804,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) * [MS-RDPBCGR] 2.2.13.2.1 * - no share control header, nor the 2 byte pad */ - s->pointer -= 2; + Stream_Rewind(s, 2); rdp_recv_enhanced_security_redirection_packet(rdp, s); return -1; } @@ -796,14 +817,14 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) } else { - while (stream_get_left(s) > 3) + while (Stream_GetRemainingLength(s) > 3) { - stream_get_mark(s, nextp); + nextPosition = Stream_GetPosition(s); if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) return -1; - nextp += pduLength; + nextPosition += pduLength; rdp->settings->PduSource = pduSource; @@ -831,7 +852,8 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) fprintf(stderr, "incorrect PDU type: 0x%04X\n", pduType); break; } - stream_set_mark(s, nextp); + + Stream_SetPosition(s, nextPosition); } } @@ -848,7 +870,7 @@ static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s) if (!fastpath_read_header_rdp(fastpath, s, &length)) return -1; - if ((length == 0) || (length > stream_get_left(s))) + if ((length == 0) || (length > Stream_GetRemainingLength(s))) { fprintf(stderr, "incorrect FastPath PDU header length %d\n", length); return -1; @@ -873,21 +895,6 @@ static int rdp_recv_pdu(rdpRdp* rdp, wStream* s) return rdp_recv_fastpath_pdu(rdp, s); } -/** - * Receive an RDP packet.\n - * @param rdp RDP module - */ - -void rdp_recv(rdpRdp* rdp) -{ - wStream* s; - - s = transport_recv_stream_init(rdp->transport, 4096); - transport_read(rdp->transport, s); - - rdp_recv_pdu(rdp, s); -} - static int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) { int status = 0; diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h index a8128c2ee..a0f2c9530 100644 --- a/libfreerdp/core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -54,8 +54,8 @@ #define SEC_ENCRYPT 0x0008 #define SEC_RESET_SEQNO 0x0010 #define SEC_IGNORE_SEQNO 0x0020 -#define SEC_INFO_PKT 0x0040 -#define SEC_LICENSE_PKT 0x0080 +#define SEC_INFO_PKT 0x0040 +#define SEC_LICENSE_PKT 0x0080 #define SEC_LICENSE_ENCRYPT_CS 0x0200 #define SEC_LICENSE_ENCRYPT_SC 0x0200 #define SEC_REDIRECTION_PKT 0x0400 @@ -156,6 +156,7 @@ struct rdp_rdp UINT32 errorInfo; UINT32 finalize_sc_pdus; BOOL disconnect; + BOOL resendFocus; }; BOOL rdp_read_security_header(wStream* s, UINT16* flags); @@ -169,12 +170,13 @@ BOOL rdp_read_share_data_header(wStream* s, UINT16* length, BYTE* type, UINT32* void rdp_write_share_data_header(wStream* s, UINT16 length, BYTE type, UINT32 share_id); +int rdp_init_stream(rdpRdp* rdp, wStream* s); wStream* rdp_send_stream_init(rdpRdp* rdp); BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channel_id); void rdp_write_header(rdpRdp* rdp, wStream* s, UINT16 length, UINT16 channel_id); -wStream* rdp_pdu_init(rdpRdp* rdp); +int rdp_init_stream_pdu(rdpRdp* rdp, wStream* s); BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id); wStream* rdp_data_pdu_init(rdpRdp* rdp); @@ -182,7 +184,6 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id); int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s); BOOL rdp_send(rdpRdp* rdp, wStream* s, UINT16 channel_id); -void rdp_recv(rdpRdp* rdp); int rdp_send_channel_data(rdpRdp* rdp, int channel_id, BYTE* data, int size); diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c index 6ca3dac65..433731df4 100644 --- a/libfreerdp/core/redirection.c +++ b/libfreerdp/core/redirection.c @@ -63,16 +63,16 @@ void rdp_print_redirection_flags(UINT32 flags) BOOL rdp_string_read_length32(wStream* s, rdpString* string) { - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, string->length); + Stream_Read_UINT32(s, string->length); - if(stream_get_left(s) < string->length) + if(Stream_GetRemainingLength(s) < string->length) return FALSE; string->unicode = (char*) malloc(string->length); - stream_read(s, string->unicode, string->length); + Stream_Read(s, string->unicode, string->length); ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) string->unicode, string->length / 2, &string->ascii, 0, NULL, NULL); @@ -94,12 +94,12 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) UINT16 length; rdpRedirection* redirection = rdp->redirection; - if (stream_get_left(s) < 12) + if (Stream_GetRemainingLength(s) < 12) return FALSE; - stream_read_UINT16(s, flags); /* flags (2 bytes) */ - stream_read_UINT16(s, length); /* length (2 bytes) */ - stream_read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */ - stream_read_UINT32(s, redirection->flags); /* redirFlags (4 bytes) */ + Stream_Read_UINT16(s, flags); /* flags (2 bytes) */ + Stream_Read_UINT16(s, length); /* length (2 bytes) */ + Stream_Read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */ + Stream_Read_UINT32(s, redirection->flags); /* redirFlags (4 bytes) */ DEBUG_REDIR("flags: 0x%04X, length:%d, sessionID:0x%08X", flags, length, redirection->sessionID); @@ -116,14 +116,14 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) if (redirection->flags & LB_LOAD_BALANCE_INFO) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, redirection->LoadBalanceInfoLength); - if (stream_get_left(s) < redirection->LoadBalanceInfoLength) + Stream_Read_UINT32(s, redirection->LoadBalanceInfoLength); + if (Stream_GetRemainingLength(s) < redirection->LoadBalanceInfoLength) return FALSE; redirection->LoadBalanceInfo = (BYTE*) malloc(redirection->LoadBalanceInfoLength); - stream_read(s, redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength); + Stream_Read(s, redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength); #ifdef WITH_DEBUG_REDIR DEBUG_REDIR("loadBalanceInfo:"); winpr_HexDump(redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength); @@ -147,11 +147,11 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) if (redirection->flags & LB_PASSWORD) { /* Note: length (hopefully) includes double zero termination */ - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, redirection->PasswordCookieLength); + Stream_Read_UINT32(s, redirection->PasswordCookieLength); redirection->PasswordCookie = (BYTE*) malloc(redirection->PasswordCookieLength); - stream_read(s, redirection->PasswordCookie, redirection->PasswordCookieLength); + Stream_Read(s, redirection->PasswordCookie, redirection->PasswordCookieLength); #ifdef WITH_DEBUG_REDIR DEBUG_REDIR("password_cookie:"); @@ -186,11 +186,11 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) UINT32 count; UINT32 targetNetAddressesLength; - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, targetNetAddressesLength); + Stream_Read_UINT32(s, targetNetAddressesLength); - stream_read_UINT32(s, redirection->targetNetAddressesCount); + Stream_Read_UINT32(s, redirection->targetNetAddressesCount); count = redirection->targetNetAddressesCount; redirection->targetNetAddresses = (rdpString*) malloc(count * sizeof(rdpString)); @@ -204,7 +204,7 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) } } - if (!stream_skip(s, 8)) /* pad (8 bytes) */ + if (!Stream_SafeSeek(s, 8)) /* pad (8 bytes) */ return FALSE; if (redirection->flags & LB_NOREDIRECT) @@ -220,9 +220,9 @@ BOOL rdp_recv_redirection_packet(rdpRdp* rdp, wStream* s) BOOL rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, wStream* s) { - return stream_skip(s, 2) && /* pad2Octets (2 bytes) */ + return Stream_SafeSeek(s, 2) && /* pad2Octets (2 bytes) */ rdp_recv_server_redirection_pdu(rdp, s) && - stream_skip(s, 1); /* pad2Octets (1 byte) */ + Stream_SafeSeek(s, 1); /* pad2Octets (1 byte) */ } rdpRedirection* redirection_new() diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index b3091270f..a02c80c7b 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -240,6 +240,8 @@ rdpSettings* freerdp_settings_new(void* instance) settings->ServerPort = 3389; settings->DesktopResize = TRUE; settings->ToggleFullscreen = TRUE; + settings->DesktopPosX = 0; + settings->DesktopPosY = 0; settings->PerformanceFlags = PERF_DISABLE_FULLWINDOWDRAG | @@ -375,7 +377,7 @@ rdpSettings* freerdp_settings_new(void* instance) settings->VirtualChannelChunkSize = CHANNEL_CHUNK_LENGTH; - settings->MultifragMaxRequestSize = 0x200000; + settings->MultifragMaxRequestSize = 0xFFFF; settings->GatewayUseSameCredentials = TRUE; @@ -457,6 +459,7 @@ void freerdp_settings_free(rdpSettings* settings) free(settings->ConfigPath); free(settings->CurrentPath); free(settings->HomePath); + free(settings->LoadBalanceInfo); freerdp_device_collection_free(settings); freerdp_static_channel_collection_free(settings); freerdp_dynamic_channel_collection_free(settings); diff --git a/libfreerdp/core/surface.c b/libfreerdp/core/surface.c index 1c961f5d9..3de41339f 100644 --- a/libfreerdp/core/surface.c +++ b/libfreerdp/core/surface.c @@ -25,36 +25,36 @@ #include "surface.h" -static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT32 *length) +static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT32* length) { int pos; SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command; - if (stream_get_left(s) < 20) + if (Stream_GetRemainingLength(s) < 20) return -1; - stream_read_UINT16(s, cmd->destLeft); - stream_read_UINT16(s, cmd->destTop); - stream_read_UINT16(s, cmd->destRight); - stream_read_UINT16(s, cmd->destBottom); - stream_read_BYTE(s, cmd->bpp); - stream_seek(s, 2); /* reserved1, reserved2 */ - stream_read_BYTE(s, cmd->codecID); - stream_read_UINT16(s, cmd->width); - stream_read_UINT16(s, cmd->height); - stream_read_UINT32(s, cmd->bitmapDataLength); + Stream_Read_UINT16(s, cmd->destLeft); + Stream_Read_UINT16(s, cmd->destTop); + Stream_Read_UINT16(s, cmd->destRight); + Stream_Read_UINT16(s, cmd->destBottom); + Stream_Read_UINT8(s, cmd->bpp); + Stream_Seek(s, 2); /* reserved1, reserved2 */ + Stream_Read_UINT8(s, cmd->codecID); + Stream_Read_UINT16(s, cmd->width); + Stream_Read_UINT16(s, cmd->height); + Stream_Read_UINT32(s, cmd->bitmapDataLength); - if (stream_get_left(s) < cmd->bitmapDataLength) + if (Stream_GetRemainingLength(s) < cmd->bitmapDataLength) return -1; - pos = stream_get_pos(s) + cmd->bitmapDataLength; - cmd->bitmapData = stream_get_tail(s); + pos = Stream_GetPosition(s) + cmd->bitmapDataLength; + cmd->bitmapData = Stream_Pointer(s); + + Stream_SetPosition(s, pos); + *length = 20 + cmd->bitmapDataLength; IFCALL(update->SurfaceBits, update->context, cmd); - stream_set_pos(s, pos); - *length = 20 + cmd->bitmapDataLength; - return 0; } @@ -63,7 +63,7 @@ static void update_send_frame_acknowledge(rdpRdp* rdp, UINT32 frameId) wStream* s; s = rdp_data_pdu_init(rdp); - stream_write_UINT32(s, frameId); + Stream_Write_UINT32(s, frameId); rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id); } @@ -71,11 +71,11 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s, UINT3 { SURFACE_FRAME_MARKER* marker = &update->surface_frame_marker; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) return -1; - stream_read_UINT16(s, marker->frameAction); - stream_read_UINT32(s, marker->frameId); + Stream_Read_UINT16(s, marker->frameAction); + Stream_Read_UINT32(s, marker->frameId); IFCALL(update->SurfaceFrameMarker, update->context, marker); @@ -99,9 +99,9 @@ int update_recv_surfcmds(rdpUpdate* update, UINT32 size, wStream* s) while (size > 2) { - stream_get_mark(s, mark); + Stream_GetPointer(s, mark); - stream_read_UINT16(s, cmdType); + Stream_Read_UINT16(s, cmdType); size -= 2; switch (cmdType) @@ -136,28 +136,28 @@ int update_recv_surfcmds(rdpUpdate* update, UINT32 size, wStream* s) void update_write_surfcmd_surface_bits_header(wStream* s, SURFACE_BITS_COMMAND* cmd) { - stream_check_size(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH); + Stream_EnsureRemainingCapacity(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH); - stream_write_UINT16(s, CMDTYPE_STREAM_SURFACE_BITS); + Stream_Write_UINT16(s, CMDTYPE_STREAM_SURFACE_BITS); - stream_write_UINT16(s, cmd->destLeft); - stream_write_UINT16(s, cmd->destTop); - stream_write_UINT16(s, cmd->destRight); - stream_write_UINT16(s, cmd->destBottom); - stream_write_BYTE(s, cmd->bpp); - stream_write_UINT16(s, 0); /* reserved1, reserved2 */ - stream_write_BYTE(s, cmd->codecID); - stream_write_UINT16(s, cmd->width); - stream_write_UINT16(s, cmd->height); - stream_write_UINT32(s, cmd->bitmapDataLength); + Stream_Write_UINT16(s, cmd->destLeft); + Stream_Write_UINT16(s, cmd->destTop); + Stream_Write_UINT16(s, cmd->destRight); + Stream_Write_UINT16(s, cmd->destBottom); + Stream_Write_UINT8(s, cmd->bpp); + Stream_Write_UINT16(s, 0); /* reserved1, reserved2 */ + Stream_Write_UINT8(s, cmd->codecID); + Stream_Write_UINT16(s, cmd->width); + Stream_Write_UINT16(s, cmd->height); + Stream_Write_UINT32(s, cmd->bitmapDataLength); } void update_write_surfcmd_frame_marker(wStream* s, UINT16 frameAction, UINT32 frameId) { - stream_check_size(s, SURFCMD_FRAME_MARKER_LENGTH); + Stream_EnsureRemainingCapacity(s, SURFCMD_FRAME_MARKER_LENGTH); - stream_write_UINT16(s, CMDTYPE_FRAME_MARKER); + Stream_Write_UINT16(s, CMDTYPE_FRAME_MARKER); - stream_write_UINT16(s, frameAction); - stream_write_UINT32(s, frameId); + Stream_Write_UINT16(s, frameAction); + Stream_Write_UINT32(s, frameId); } diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index cb63b4241..a9331106a 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -134,6 +134,8 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, UINT16 port) if (tcp->sockfd < 0) return FALSE; + SetEventFileDescriptor(tcp->event, tcp->sockfd); + tcp_get_ip_address(tcp); tcp_get_mac_address(tcp); @@ -248,6 +250,15 @@ BOOL tcp_set_keep_alive_mode(rdpTcp* tcp) return TRUE; } +HANDLE tcp_get_event_handle(rdpTcp* tcp) +{ +#ifndef _WIN32 + return tcp->event; +#else + return (HANDLE) tcp->wsa_event; +#endif +} + rdpTcp* tcp_new(rdpSettings* settings) { rdpTcp* tcp; @@ -260,6 +271,7 @@ rdpTcp* tcp_new(rdpSettings* settings) tcp->sockfd = -1; tcp->settings = settings; + tcp->event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, tcp->sockfd); } return tcp; @@ -267,8 +279,9 @@ rdpTcp* tcp_new(rdpSettings* settings) void tcp_free(rdpTcp* tcp) { - if (tcp != NULL) + if (tcp) { + CloseHandle(tcp->event); free(tcp); } } diff --git a/libfreerdp/core/tcp.h b/libfreerdp/core/tcp.h index baede4524..539d77673 100644 --- a/libfreerdp/core/tcp.h +++ b/libfreerdp/core/tcp.h @@ -26,6 +26,8 @@ #include <freerdp/types.h> #include <freerdp/settings.h> +#include <winpr/crt.h> +#include <winpr/synch.h> #include <winpr/stream.h> #ifndef MSG_NOSIGNAL @@ -43,6 +45,7 @@ struct rdp_tcp #ifdef _WIN32 WSAEVENT wsa_event; #endif + HANDLE event; }; BOOL tcp_connect(rdpTcp* tcp, const char* hostname, UINT16 port); @@ -53,6 +56,7 @@ int tcp_wait_read(rdpTcp* tcp); int tcp_wait_write(rdpTcp* tcp); BOOL tcp_set_blocking_mode(rdpTcp* tcp, BOOL blocking); BOOL tcp_set_keep_alive_mode(rdpTcp* tcp); +HANDLE tcp_get_event_handle(rdpTcp* tcp); rdpTcp* tcp_new(rdpSettings* settings); void tcp_free(rdpTcp* tcp); diff --git a/libfreerdp/core/timezone.c b/libfreerdp/core/timezone.c index 30a291ffc..95f06a356 100644 --- a/libfreerdp/core/timezone.c +++ b/libfreerdp/core/timezone.c @@ -34,14 +34,14 @@ void rdp_read_system_time(wStream* s, SYSTEM_TIME* system_time) { - stream_read_UINT16(s, system_time->wYear); /* wYear, must be set to 0 */ - stream_read_UINT16(s, system_time->wMonth); /* wMonth */ - stream_read_UINT16(s, system_time->wDayOfWeek); /* wDayOfWeek */ - stream_read_UINT16(s, system_time->wDay); /* wDay */ - stream_read_UINT16(s, system_time->wHour); /* wHour */ - stream_read_UINT16(s, system_time->wMinute); /* wMinute */ - stream_read_UINT16(s, system_time->wSecond); /* wSecond */ - stream_read_UINT16(s, system_time->wMilliseconds); /* wMilliseconds */ + Stream_Read_UINT16(s, system_time->wYear); /* wYear, must be set to 0 */ + Stream_Read_UINT16(s, system_time->wMonth); /* wMonth */ + Stream_Read_UINT16(s, system_time->wDayOfWeek); /* wDayOfWeek */ + Stream_Read_UINT16(s, system_time->wDay); /* wDay */ + Stream_Read_UINT16(s, system_time->wHour); /* wHour */ + Stream_Read_UINT16(s, system_time->wMinute); /* wMinute */ + Stream_Read_UINT16(s, system_time->wSecond); /* wSecond */ + Stream_Read_UINT16(s, system_time->wMilliseconds); /* wMilliseconds */ } /** @@ -53,14 +53,14 @@ void rdp_read_system_time(wStream* s, SYSTEM_TIME* system_time) void rdp_write_system_time(wStream* s, SYSTEM_TIME* system_time) { - stream_write_UINT16(s, system_time->wYear); /* wYear, must be set to 0 */ - stream_write_UINT16(s, system_time->wMonth); /* wMonth */ - stream_write_UINT16(s, system_time->wDayOfWeek); /* wDayOfWeek */ - stream_write_UINT16(s, system_time->wDay); /* wDay */ - stream_write_UINT16(s, system_time->wHour); /* wHour */ - stream_write_UINT16(s, system_time->wMinute); /* wMinute */ - stream_write_UINT16(s, system_time->wSecond); /* wSecond */ - stream_write_UINT16(s, system_time->wMilliseconds); /* wMilliseconds */ + Stream_Write_UINT16(s, system_time->wYear); /* wYear, must be set to 0 */ + Stream_Write_UINT16(s, system_time->wMonth); /* wMonth */ + Stream_Write_UINT16(s, system_time->wDayOfWeek); /* wDayOfWeek */ + Stream_Write_UINT16(s, system_time->wDay); /* wDay */ + Stream_Write_UINT16(s, system_time->wHour); /* wHour */ + Stream_Write_UINT16(s, system_time->wMinute); /* wMinute */ + Stream_Write_UINT16(s, system_time->wSecond); /* wSecond */ + Stream_Write_UINT16(s, system_time->wMilliseconds); /* wMilliseconds */ DEBUG_TIMEZONE("Time: y=%d,m=%d,dow=%d,d=%d, %02d:%02d:%02d.%03d", system_time->wYear, system_time->wMonth, system_time->wDayOfWeek, system_time->wDay, system_time->wHour, system_time->wMinute, @@ -79,31 +79,31 @@ BOOL rdp_read_client_time_zone(wStream* s, rdpSettings* settings) char* str = NULL; TIME_ZONE_INFO* clientTimeZone; - if (stream_get_left(s) < 172) + if (Stream_GetRemainingLength(s) < 172) return FALSE; clientTimeZone = settings->ClientTimeZone; - stream_read_UINT32(s, clientTimeZone->bias); /* Bias */ + Stream_Read_UINT32(s, clientTimeZone->bias); /* Bias */ /* standardName (64 bytes) */ - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), 64 / 2, &str, 0, NULL, NULL); - stream_seek(s, 64); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), 64 / 2, &str, 0, NULL, NULL); + Stream_Seek(s, 64); strncpy(clientTimeZone->standardName, str, sizeof(clientTimeZone->standardName)); free(str); str = NULL; rdp_read_system_time(s, &clientTimeZone->standardDate); /* StandardDate */ - stream_read_UINT32(s, clientTimeZone->standardBias); /* StandardBias */ + Stream_Read_UINT32(s, clientTimeZone->standardBias); /* StandardBias */ /* daylightName (64 bytes) */ - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), 64 / 2, &str, 0, NULL, NULL); - stream_seek(s, 64); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), 64 / 2, &str, 0, NULL, NULL); + Stream_Seek(s, 64); strncpy(clientTimeZone->daylightName, str, sizeof(clientTimeZone->daylightName)); free(str); rdp_read_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */ - stream_read_UINT32(s, clientTimeZone->daylightBias); /* DaylightBias */ + Stream_Read_UINT32(s, clientTimeZone->daylightBias); /* DaylightBias */ return TRUE; } @@ -136,11 +136,11 @@ void rdp_write_client_time_zone(wStream* s, rdpSettings* settings) daylightNameLength = 62; /* Bias */ - stream_write_UINT32(s, clientTimeZone->bias); + Stream_Write_UINT32(s, clientTimeZone->bias); /* standardName (64 bytes) */ - stream_write(s, standardName, standardNameLength); - stream_write_zero(s, 64 - standardNameLength); + Stream_Write(s, standardName, standardNameLength); + Stream_Zero(s, 64 - standardNameLength); /* StandardDate */ rdp_write_system_time(s, &clientTimeZone->standardDate); @@ -149,19 +149,19 @@ void rdp_write_client_time_zone(wStream* s, rdpSettings* settings) /* Note that StandardBias is ignored if no valid standardDate is provided. */ /* StandardBias */ - stream_write_UINT32(s, clientTimeZone->standardBias); + Stream_Write_UINT32(s, clientTimeZone->standardBias); DEBUG_TIMEZONE("StandardBias=%d", clientTimeZone->standardBias); /* daylightName (64 bytes) */ - stream_write(s, daylightName, daylightNameLength); - stream_write_zero(s, 64 - daylightNameLength); + Stream_Write(s, daylightName, daylightNameLength); + Stream_Zero(s, 64 - daylightNameLength); /* DaylightDate */ rdp_write_system_time(s, &clientTimeZone->daylightDate); /* Note that DaylightBias is ignored if no valid daylightDate is provided. */ /* DaylightBias */ - stream_write_UINT32(s, clientTimeZone->daylightBias); + Stream_Write_UINT32(s, clientTimeZone->daylightBias); DEBUG_TIMEZONE("DaylightBias=%d", clientTimeZone->daylightBias); free(standardName); diff --git a/libfreerdp/core/tpdu.c b/libfreerdp/core/tpdu.c index 228d6e14a..a701c11d7 100644 --- a/libfreerdp/core/tpdu.c +++ b/libfreerdp/core/tpdu.c @@ -68,23 +68,23 @@ BOOL tpdu_read_header(wStream* s, BYTE* code, BYTE *li) { - if(stream_get_left(s) < 3) + if(Stream_GetRemainingLength(s) < 3) return FALSE; - stream_read_BYTE(s, *li); /* LI */ - stream_read_BYTE(s, *code); /* Code */ + Stream_Read_UINT8(s, *li); /* LI */ + Stream_Read_UINT8(s, *code); /* Code */ if (*code == X224_TPDU_DATA) { /* EOT (1 byte) */ - stream_seek(s, 1); + Stream_Seek(s, 1); } else { /* DST-REF (2 bytes) */ /* SRC-REF (2 bytes) */ /* Class 0 (1 byte) */ - return stream_skip(s, 5); + return Stream_SafeSeek(s, 5); } return TRUE; } @@ -98,18 +98,18 @@ BOOL tpdu_read_header(wStream* s, BYTE* code, BYTE *li) void tpdu_write_header(wStream* s, UINT16 length, BYTE code) { - stream_write_BYTE(s, length); /* LI */ - stream_write_BYTE(s, code); /* code */ + Stream_Write_UINT8(s, length); /* LI */ + Stream_Write_UINT8(s, code); /* code */ if (code == X224_TPDU_DATA) { - stream_write_BYTE(s, 0x80); /* EOT */ + Stream_Write_UINT8(s, 0x80); /* EOT */ } else { - stream_write_UINT16(s, 0); /* DST-REF */ - stream_write_UINT16(s, 0); /* SRC-REF */ - stream_write_BYTE(s, 0); /* Class 0 */ + Stream_Write_UINT16(s, 0); /* DST-REF */ + Stream_Write_UINT16(s, 0); /* SRC-REF */ + Stream_Write_UINT8(s, 0); /* Class 0 */ } } @@ -165,7 +165,7 @@ BOOL tpdu_read_connection_confirm(wStream* s, BYTE *li) return FALSE; } - return (stream_get_left(s) >= *li); + return (Stream_GetRemainingLength(s) >= *li); } /** diff --git a/libfreerdp/core/tpkt.c b/libfreerdp/core/tpkt.c index f5f55eb79..5689d62e4 100644 --- a/libfreerdp/core/tpkt.c +++ b/libfreerdp/core/tpkt.c @@ -67,7 +67,7 @@ BOOL tpkt_verify_header(wStream* s) { BYTE version; - stream_peek_BYTE(s, version); + Stream_Peek_UINT8(s, version); if (version == 3) return TRUE; @@ -86,12 +86,12 @@ UINT16 tpkt_read_header(wStream* s) BYTE version; UINT16 length; - stream_peek_BYTE(s, version); + Stream_Peek_UINT8(s, version); if (version == 3) { - stream_seek(s, 2); - stream_read_UINT16_be(s, length); + Stream_Seek(s, 2); + Stream_Read_UINT16_BE(s, length); } else { @@ -110,7 +110,7 @@ UINT16 tpkt_read_header(wStream* s) void tpkt_write_header(wStream* s, UINT16 length) { - stream_write_BYTE(s, 3); /* version */ - stream_write_BYTE(s, 0); /* reserved */ - stream_write_UINT16_be(s, length); /* length */ + Stream_Write_UINT8(s, 3); /* version */ + Stream_Write_UINT8(s, 0); /* reserved */ + Stream_Write_UINT16_BE(s, length); /* length */ } diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 29f8e6297..ba8f9c800 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -50,19 +50,15 @@ static void* transport_client_thread(void* arg); -wStream* transport_recv_stream_init(rdpTransport* transport, int size) -{ - wStream* s = transport->ReceiveStream; - stream_check_size(s, size); - stream_set_pos(s, 0); - return s; -} - wStream* transport_send_stream_init(rdpTransport* transport, int size) { - wStream* s = transport->SendStream; - stream_check_size(s, size); - stream_set_pos(s, 0); + wStream* s; + + s = StreamPool_Take(transport->ReceivePool, size); + + Stream_EnsureCapacity(s, size); + Stream_SetPosition(s, 0); + return s; } @@ -322,13 +318,13 @@ UINT32 nla_read_header(wStream* s) { length = s->pointer[2]; length += 3; - stream_seek(s, 3); + Stream_Seek(s, 3); } else if ((s->pointer[1] & ~(0x80)) == 2) { length = (s->pointer[2] << 8) | s->pointer[3]; length += 4; - stream_seek(s, 4); + Stream_Seek(s, 4); } else { @@ -339,7 +335,7 @@ UINT32 nla_read_header(wStream* s) { length = s->pointer[1]; length += 2; - stream_seek(s, 2); + Stream_Seek(s, 2); } return length; @@ -406,29 +402,29 @@ int transport_read_layer(rdpTransport* transport, UINT8* data, int bytes) int transport_read(rdpTransport* transport, wStream* s) { int status; - int pdu_bytes; - int stream_bytes; + int pduLength; + int streamPosition; int transport_status; - pdu_bytes = 0; + pduLength = 0; transport_status = 0; /* first check if we have header */ - stream_bytes = stream_get_length(s); + streamPosition = Stream_GetPosition(s); - if (stream_bytes < 4) + if (streamPosition < 4) { - status = transport_read_layer(transport, s->buffer + stream_bytes, 4 - stream_bytes); + status = transport_read_layer(transport, Stream_Buffer(s) + streamPosition, 4 - streamPosition); if (status < 0) return status; transport_status += status; - if ((status + stream_bytes) < 4) + if ((status + streamPosition) < 4) return transport_status; - stream_bytes += status; + streamPosition += status; } /* if header is present, read in exactly one PDU */ @@ -436,7 +432,7 @@ int transport_read(rdpTransport* transport, wStream* s) { /* TPKT header */ - pdu_bytes = (s->buffer[2] << 8) | s->buffer[3]; + pduLength = (s->buffer[2] << 8) | s->buffer[3]; } else if (s->buffer[0] == 0x30) { @@ -446,13 +442,13 @@ int transport_read(rdpTransport* transport, wStream* s) { if ((s->buffer[1] & ~(0x80)) == 1) { - pdu_bytes = s->buffer[2]; - pdu_bytes += 3; + pduLength = s->buffer[2]; + pduLength += 3; } else if ((s->buffer[1] & ~(0x80)) == 2) { - pdu_bytes = (s->buffer[2] << 8) | s->buffer[3]; - pdu_bytes += 4; + pduLength = (s->buffer[2] << 8) | s->buffer[3]; + pduLength += 4; } else { @@ -461,8 +457,8 @@ int transport_read(rdpTransport* transport, wStream* s) } else { - pdu_bytes = s->buffer[1]; - pdu_bytes += 2; + pduLength = s->buffer[1]; + pduLength += 2; } } else @@ -470,12 +466,12 @@ int transport_read(rdpTransport* transport, wStream* s) /* Fast-Path Header */ if (s->buffer[1] & 0x80) - pdu_bytes = ((s->buffer[1] & 0x7f) << 8) | s->buffer[2]; + pduLength = ((s->buffer[1] & 0x7F) << 8) | s->buffer[2]; else - pdu_bytes = s->buffer[1]; + pduLength = s->buffer[1]; } - status = transport_read_layer(transport, s->buffer + stream_bytes, pdu_bytes - stream_bytes); + status = transport_read_layer(transport, Stream_Buffer(s) + streamPosition, pduLength - streamPosition); if (status < 0) return status; @@ -484,10 +480,10 @@ int transport_read(rdpTransport* transport, wStream* s) #ifdef WITH_DEBUG_TRANSPORT /* dump when whole PDU is read */ - if (stream_bytes + status >= pdu_bytes) + if (streamPosition + status >= pduLength) { fprintf(stderr, "Local < Remote\n"); - winpr_HexDump(s->buffer, pdu_bytes); + winpr_HexDump(Stream_Buffer(s), pduLength); } #endif @@ -498,41 +494,42 @@ static int transport_read_nonblocking(rdpTransport* transport) { int status; - stream_check_size(transport->ReceiveBuffer, 32 * 1024); status = transport_read(transport, transport->ReceiveBuffer); if (status <= 0) return status; - stream_seek(transport->ReceiveBuffer, status); + Stream_Seek(transport->ReceiveBuffer, status); return status; } int transport_write(rdpTransport* transport, wStream* s) { - int status = -1; int length; + int status = -1; - length = stream_get_length(s); - stream_set_pos(s, 0); + WaitForSingleObject(transport->WriteMutex, INFINITE); + + length = Stream_GetPosition(s); + Stream_SetPosition(s, 0); #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { fprintf(stderr, "Local > Remote\n"); - winpr_HexDump(s->buffer, length); + winpr_HexDump(Stream_Buffer(s), length); } #endif while (length > 0) { if (transport->layer == TRANSPORT_LAYER_TLS) - status = tls_write(transport->TlsOut, stream_get_tail(s), length); + status = tls_write(transport->TlsOut, Stream_Pointer(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) - status = tcp_write(transport->TcpOut, stream_get_tail(s), length); + status = tcp_write(transport->TcpOut, Stream_Pointer(s), length); else if (transport->layer == TRANSPORT_LAYER_TSG) - status = tsg_write(transport->tsg, stream_get_tail(s), length); + status = tsg_write(transport->tsg, Stream_Pointer(s), length); if (status < 0) break; /* error occurred */ @@ -556,7 +553,7 @@ int transport_write(rdpTransport* transport, wStream* s) } length -= status; - stream_seek(s, status); + Stream_Seek(s, status); } if (status < 0) @@ -565,9 +562,15 @@ int transport_write(rdpTransport* transport, wStream* s) transport->layer = TRANSPORT_LAYER_CLOSED; } + if (s->pool) + Stream_Release(s); + + ReleaseMutex(transport->WriteMutex); + return status; } + void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount) { void* pfd; @@ -612,6 +615,30 @@ void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount) } } +void transport_get_read_handles(rdpTransport* transport, HANDLE* events, DWORD* count) +{ + events[*count] = tcp_get_event_handle(transport->TcpIn); + (*count)++; + + if (transport->SplitInputOutput) + { + events[*count] = tcp_get_event_handle(transport->TcpOut); + (*count)++; + } + + if (transport->ReceiveEvent) + { + events[*count] = transport->ReceiveEvent; + (*count)++; + } + + if (transport->GatewayEvent) + { + events[*count] = transport->GatewayEvent; + (*count)++; + } +} + int transport_check_fds(rdpTransport** ptransport) { int pos; @@ -631,16 +658,16 @@ int transport_check_fds(rdpTransport** ptransport) if (status < 0) return status; - while ((pos = stream_get_pos(transport->ReceiveBuffer)) > 0) + while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0) { - stream_set_pos(transport->ReceiveBuffer, 0); + Stream_SetPosition(transport->ReceiveBuffer, 0); if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */ { /* Ensure the TPKT header is available. */ if (pos <= 4) { - stream_set_pos(transport->ReceiveBuffer, pos); + Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } @@ -653,7 +680,7 @@ int transport_check_fds(rdpTransport** ptransport) /* Ensure the TSRequest header is available. */ if (pos <= 4) { - stream_set_pos(transport->ReceiveBuffer, pos); + Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } @@ -662,7 +689,7 @@ int transport_check_fds(rdpTransport** ptransport) if (pos < length) { - stream_set_pos(transport->ReceiveBuffer, pos); + Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } @@ -673,7 +700,7 @@ int transport_check_fds(rdpTransport** ptransport) /* Ensure the Fast Path header is available. */ if (pos <= 2) { - stream_set_pos(transport->ReceiveBuffer, pos); + Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } @@ -682,7 +709,7 @@ int transport_check_fds(rdpTransport** ptransport) if (pos < length) { - stream_set_pos(transport->ReceiveBuffer, pos); + Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } @@ -692,35 +719,26 @@ int transport_check_fds(rdpTransport** ptransport) if (length == 0) { fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); - winpr_HexDump(stream_get_head(transport->ReceiveBuffer), pos); + winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos); return -1; } if (pos < length) { - stream_set_pos(transport->ReceiveBuffer, pos); + Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; /* Packet is not yet completely received. */ } received = transport->ReceiveBuffer; - transport->ReceiveBuffer = ObjectPool_Take(transport->ReceivePool); - transport->ReceiveBuffer->pointer = transport->ReceiveBuffer->buffer; + transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0); - stream_set_pos(received, length); - stream_seal(received); - stream_set_pos(received, 0); - - /** - * ReceiveCallback return values: - * - * -1: synchronous failure - * 0: synchronous success - * 1: asynchronous return - */ + Stream_SetPosition(received, length); + Stream_SealLength(received); + Stream_SetPosition(received, 0); recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); - ObjectPool_Return(transport->ReceivePool, received); + Stream_Release(received); if (recv_status < 0) status = -1; @@ -764,22 +782,28 @@ static void* transport_client_thread(void* arg) { DWORD status; DWORD nCount; - HANDLE events[3]; - HANDLE ReadEvent; + HANDLE events[32]; freerdp* instance; rdpTransport* transport; transport = (rdpTransport*) arg; instance = (freerdp*) transport->settings->instance; - ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, transport->TcpIn->sockfd); - - nCount = 0; - events[nCount++] = transport->stopEvent; - events[nCount++] = ReadEvent; - while (1) { + nCount = 0; + events[nCount++] = transport->stopEvent; + events[nCount] = transport->connectedEvent; + + status = WaitForMultipleObjects(nCount + 1, events, FALSE, INFINITE); + + if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0) + { + break; + } + + transport_get_read_handles(transport, (HANDLE*) &events, &nCount); + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0) @@ -787,28 +811,13 @@ static void* transport_client_thread(void* arg) break; } - if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0) - { - if (!freerdp_check_fds(instance)) - break; - } + if (!freerdp_check_fds(instance)) + break; } - CloseHandle(ReadEvent); - return NULL; } -wStream* transport_receive_buffer_pool_new() -{ - wStream* pdu = NULL; - - pdu = stream_new(BUFFER_SIZE); - pdu->pointer = pdu->buffer; - - return pdu; -} - rdpTransport* transport_new(rdpSettings* settings) { rdpTransport* transport; @@ -826,20 +835,19 @@ rdpTransport* transport_new(rdpSettings* settings) /* a small 0.1ms delay when transport is blocking. */ transport->SleepInterval = 100; - transport->ReceivePool = ObjectPool_New(TRUE); - ObjectPool_Object(transport->ReceivePool)->fnObjectFree = (OBJECT_FREE_FN) stream_free; - ObjectPool_Object(transport->ReceivePool)->fnObjectNew = (OBJECT_NEW_FN) transport_receive_buffer_pool_new; + transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE); /* receive buffer for non-blocking read. */ - transport->ReceiveBuffer = ObjectPool_Take(transport->ReceivePool); + transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0); transport->ReceiveEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - /* buffers for blocking read/write */ - transport->ReceiveStream = stream_new(BUFFER_SIZE); - transport->SendStream = stream_new(BUFFER_SIZE); + transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL); transport->blocking = TRUE; + transport->ReadMutex = CreateMutex(NULL, FALSE, NULL); + transport->WriteMutex = CreateMutex(NULL, FALSE, NULL); + transport->layer = TRANSPORT_LAYER_TCP; } @@ -851,13 +859,12 @@ void transport_free(rdpTransport* transport) if (transport != NULL) { if (transport->ReceiveBuffer) - ObjectPool_Return(transport->ReceivePool, transport->ReceiveBuffer); + Stream_Release(transport->ReceiveBuffer); - ObjectPool_Free(transport->ReceivePool); + StreamPool_Free(transport->ReceivePool); - stream_free(transport->ReceiveStream); - stream_free(transport->SendStream); CloseHandle(transport->ReceiveEvent); + CloseHandle(transport->connectedEvent); if (transport->TlsIn) tls_free(transport->TlsIn); @@ -872,6 +879,9 @@ void transport_free(rdpTransport* transport) tsg_free(transport->tsg); + CloseHandle(transport->ReadMutex); + CloseHandle(transport->WriteMutex); + free(transport); } } diff --git a/libfreerdp/core/transport.h b/libfreerdp/core/transport.h index 0dc04122a..bb573b6eb 100644 --- a/libfreerdp/core/transport.h +++ b/libfreerdp/core/transport.h @@ -60,8 +60,6 @@ struct rdp_transport rdpCredssp* credssp; rdpSettings* settings; UINT32 SleepInterval; - wStream* SendStream; - wStream* ReceiveStream; void* ReceiveExtra; wStream* ReceiveBuffer; TransportRecv ReceiveCallback; @@ -69,13 +67,15 @@ struct rdp_transport HANDLE GatewayEvent; BOOL blocking; BOOL SplitInputOutput; - wObjectPool* ReceivePool; + wStreamPool* ReceivePool; + HANDLE connectedEvent; HANDLE stopEvent; HANDLE thread; BOOL async; + HANDLE ReadMutex; + HANDLE WriteMutex; }; -wStream* transport_recv_stream_init(rdpTransport* transport, int size); wStream* transport_send_stream_init(rdpTransport* transport, int size); BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port); void transport_attach(rdpTransport* transport, int sockfd); @@ -92,6 +92,7 @@ int transport_write(rdpTransport* transport, wStream* s); void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount); int transport_check_fds(rdpTransport** ptransport); BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking); +void transport_get_read_handles(rdpTransport* transport, HANDLE* events, DWORD* count); wStream* transport_receive_pool_take(rdpTransport* transport); int transport_receive_pool_return(rdpTransport* transport, wStream* pdu); diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 578c5ed4d..9984791d2 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -22,6 +22,7 @@ #endif #include <winpr/crt.h> +#include <winpr/print.h> #include <winpr/thread.h> #include <winpr/collections.h> @@ -42,21 +43,24 @@ static const char* const UPDATE_TYPE_STRINGS[] = }; */ +extern const BYTE PRIMARY_DRAWING_ORDER_FIELD_BYTES[]; + BOOL update_recv_orders(rdpUpdate* update, wStream* s) { UINT16 numberOrders; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) return FALSE; - stream_seek_UINT16(s); /* pad2OctetsA (2 bytes) */ - stream_read_UINT16(s, numberOrders); /* numberOrders (2 bytes) */ - stream_seek_UINT16(s); /* pad2OctetsB (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2OctetsA (2 bytes) */ + Stream_Read_UINT16(s, numberOrders); /* numberOrders (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2OctetsB (2 bytes) */ while (numberOrders > 0) { if (!update_recv_order(update, s)) return FALSE; + numberOrders--; } @@ -65,41 +69,41 @@ BOOL update_recv_orders(rdpUpdate* update, wStream* s) BOOL update_read_bitmap_data(wStream* s, BITMAP_DATA* bitmap_data) { - if (stream_get_left(s) < 18) + if (Stream_GetRemainingLength(s) < 18) return FALSE; - stream_read_UINT16(s, bitmap_data->destLeft); - stream_read_UINT16(s, bitmap_data->destTop); - stream_read_UINT16(s, bitmap_data->destRight); - stream_read_UINT16(s, bitmap_data->destBottom); - stream_read_UINT16(s, bitmap_data->width); - stream_read_UINT16(s, bitmap_data->height); - stream_read_UINT16(s, bitmap_data->bitsPerPixel); - stream_read_UINT16(s, bitmap_data->flags); - stream_read_UINT16(s, bitmap_data->bitmapLength); + Stream_Read_UINT16(s, bitmap_data->destLeft); + Stream_Read_UINT16(s, bitmap_data->destTop); + Stream_Read_UINT16(s, bitmap_data->destRight); + Stream_Read_UINT16(s, bitmap_data->destBottom); + Stream_Read_UINT16(s, bitmap_data->width); + Stream_Read_UINT16(s, bitmap_data->height); + Stream_Read_UINT16(s, bitmap_data->bitsPerPixel); + Stream_Read_UINT16(s, bitmap_data->flags); + Stream_Read_UINT16(s, bitmap_data->bitmapLength); if (bitmap_data->flags & BITMAP_COMPRESSION) { if (!(bitmap_data->flags & NO_BITMAP_COMPRESSION_HDR)) { - stream_read_UINT16(s, bitmap_data->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ - stream_read_UINT16(s, bitmap_data->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */ - stream_read_UINT16(s, bitmap_data->cbScanWidth); /* cbScanWidth (2 bytes) */ - stream_read_UINT16(s, bitmap_data->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */ + Stream_Read_UINT16(s, bitmap_data->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ + Stream_Read_UINT16(s, bitmap_data->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */ + Stream_Read_UINT16(s, bitmap_data->cbScanWidth); /* cbScanWidth (2 bytes) */ + Stream_Read_UINT16(s, bitmap_data->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */ bitmap_data->bitmapLength = bitmap_data->cbCompMainBodySize; } bitmap_data->compressed = TRUE; - stream_get_mark(s, bitmap_data->bitmapDataStream); - stream_seek(s, bitmap_data->bitmapLength); + Stream_GetPointer(s, bitmap_data->bitmapDataStream); + Stream_Seek(s, bitmap_data->bitmapLength); } else { - if (stream_get_left(s) < bitmap_data->bitmapLength) + if (Stream_GetRemainingLength(s) < bitmap_data->bitmapLength) return FALSE; bitmap_data->compressed = FALSE; - stream_get_mark(s, bitmap_data->bitmapDataStream); - stream_seek(s, bitmap_data->bitmapLength); + Stream_GetPointer(s, bitmap_data->bitmapDataStream); + Stream_Seek(s, bitmap_data->bitmapLength); } return TRUE; } @@ -108,10 +112,10 @@ BOOL update_read_bitmap(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmap_upd { int i; - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, bitmap_update->number); /* numberRectangles (2 bytes) */ + Stream_Read_UINT16(s, bitmap_update->number); /* numberRectangles (2 bytes) */ if (bitmap_update->number > bitmap_update->count) { @@ -142,16 +146,16 @@ BOOL update_read_palette(rdpUpdate* update, wStream* s, PALETTE_UPDATE* palette_ int i; PALETTE_ENTRY* entry; - if (stream_get_left(s) < 6) + if (Stream_GetRemainingLength(s) < 6) return FALSE; - stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ - stream_read_UINT32(s, palette_update->number); /* numberColors (4 bytes), must be set to 256 */ + Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ + Stream_Read_UINT32(s, palette_update->number); /* numberColors (4 bytes), must be set to 256 */ if (palette_update->number > 256) palette_update->number = 256; - if (stream_get_left(s) < palette_update->number * 3) + if (Stream_GetRemainingLength(s) < palette_update->number * 3) return FALSE; /* paletteEntries */ @@ -159,16 +163,16 @@ BOOL update_read_palette(rdpUpdate* update, wStream* s, PALETTE_UPDATE* palette_ { entry = &palette_update->entries[i]; - stream_read_BYTE(s, entry->blue); - stream_read_BYTE(s, entry->green); - stream_read_BYTE(s, entry->red); + Stream_Read_UINT8(s, entry->blue); + Stream_Read_UINT8(s, entry->green); + Stream_Read_UINT8(s, entry->red); } return TRUE; } void update_read_synchronize(rdpUpdate* update, wStream* s) { - stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ /** * The Synchronize Update is an artifact from the @@ -178,11 +182,11 @@ void update_read_synchronize(rdpUpdate* update, wStream* s) BOOL update_read_play_sound(wStream* s, PLAY_SOUND_UPDATE* play_sound) { - if (stream_get_left(s) < 8) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, play_sound->duration); /* duration (4 bytes) */ - stream_read_UINT32(s, play_sound->frequency); /* frequency (4 bytes) */ + Stream_Read_UINT32(s, play_sound->duration); /* duration (4 bytes) */ + Stream_Read_UINT32(s, play_sound->frequency); /* frequency (4 bytes) */ return TRUE; } @@ -198,35 +202,35 @@ BOOL update_recv_play_sound(rdpUpdate* update, wStream* s) BOOL update_read_pointer_position(wStream* s, POINTER_POSITION_UPDATE* pointer_position) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT16(s, pointer_position->xPos); /* xPos (2 bytes) */ - stream_read_UINT16(s, pointer_position->yPos); /* yPos (2 bytes) */ + Stream_Read_UINT16(s, pointer_position->xPos); /* xPos (2 bytes) */ + Stream_Read_UINT16(s, pointer_position->yPos); /* yPos (2 bytes) */ return TRUE; } BOOL update_read_pointer_system(wStream* s, POINTER_SYSTEM_UPDATE* pointer_system) { - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, pointer_system->type); /* systemPointerType (4 bytes) */ + Stream_Read_UINT32(s, pointer_system->type); /* systemPointerType (4 bytes) */ return TRUE; } BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color) { - if (stream_get_left(s) < 14) + if (Stream_GetRemainingLength(s) < 14) return FALSE; - stream_read_UINT16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */ - stream_read_UINT16(s, pointer_color->xPos); /* xPos (2 bytes) */ - stream_read_UINT16(s, pointer_color->yPos); /* yPos (2 bytes) */ - stream_read_UINT16(s, pointer_color->width); /* width (2 bytes) */ - stream_read_UINT16(s, pointer_color->height); /* height (2 bytes) */ - stream_read_UINT16(s, pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */ - stream_read_UINT16(s, pointer_color->lengthXorMask); /* lengthXorMask (2 bytes) */ + Stream_Read_UINT16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */ + Stream_Read_UINT16(s, pointer_color->xPos); /* xPos (2 bytes) */ + Stream_Read_UINT16(s, pointer_color->yPos); /* yPos (2 bytes) */ + Stream_Read_UINT16(s, pointer_color->width); /* width (2 bytes) */ + Stream_Read_UINT16(s, pointer_color->height); /* height (2 bytes) */ + Stream_Read_UINT16(s, pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */ + Stream_Read_UINT16(s, pointer_color->lengthXorMask); /* lengthXorMask (2 bytes) */ /** * There does not seem to be any documentation on why @@ -241,7 +245,7 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color) if (pointer_color->lengthXorMask > 0) { - if (stream_get_left(s) < pointer_color->lengthXorMask) + if (Stream_GetRemainingLength(s) < pointer_color->lengthXorMask) return FALSE; if (!pointer_color->xorMaskData) @@ -249,12 +253,12 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color) else pointer_color->xorMaskData = realloc(pointer_color->xorMaskData, pointer_color->lengthXorMask); - stream_read(s, pointer_color->xorMaskData, pointer_color->lengthXorMask); + Stream_Read(s, pointer_color->xorMaskData, pointer_color->lengthXorMask); } if (pointer_color->lengthAndMask > 0) { - if (stream_get_left(s) < pointer_color->lengthAndMask) + if (Stream_GetRemainingLength(s) < pointer_color->lengthAndMask) return FALSE; if (!pointer_color->andMaskData) @@ -262,30 +266,30 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color) else pointer_color->andMaskData = realloc(pointer_color->andMaskData, pointer_color->lengthAndMask); - stream_read(s, pointer_color->andMaskData, pointer_color->lengthAndMask); + Stream_Read(s, pointer_color->andMaskData, pointer_color->lengthAndMask); } - if (stream_get_left(s) > 0) - stream_seek_BYTE(s); /* pad (1 byte) */ + if (Stream_GetRemainingLength(s) > 0) + Stream_Seek_UINT8(s); /* pad (1 byte) */ return TRUE; } BOOL update_read_pointer_new(wStream* s, POINTER_NEW_UPDATE* pointer_new) { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ + Stream_Read_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ return update_read_pointer_color(s, &pointer_new->colorPtrAttr); /* colorPtrAttr */ } BOOL update_read_pointer_cached(wStream* s, POINTER_CACHED_UPDATE* pointer_cached) { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */ + Stream_Read_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */ return TRUE; } @@ -295,11 +299,11 @@ BOOL update_recv_pointer(rdpUpdate* update, wStream* s) rdpContext* context = update->context; rdpPointerUpdate* pointer = update->pointer; - if (stream_get_left(s) < 2 + 2) + if (Stream_GetRemainingLength(s) < 2 + 2) return FALSE; - stream_read_UINT16(s, messageType); /* messageType (2 bytes) */ - stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ + Stream_Read_UINT16(s, messageType); /* messageType (2 bytes) */ + Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ switch (messageType) { @@ -344,10 +348,10 @@ BOOL update_recv(rdpUpdate* update, wStream* s) UINT16 updateType; rdpContext* context = update->context; - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, updateType); /* updateType (2 bytes) */ + Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */ //fprintf(stderr, "%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]); @@ -439,27 +443,187 @@ void update_post_connect(rdpUpdate* update) static void update_begin_paint(rdpContext* context) { + wStream* s; + rdpUpdate* update = context->update; + if (update->us) + update->EndPaint(context); + + s = fastpath_update_pdu_init_new(context->rdp->fastpath); + Stream_SealLength(s); + Stream_Seek(s, 2); /* numberOrders (2 bytes) */ + + update->combineUpdates = TRUE; + update->numberOrders = 0; + update->us = s; } static void update_end_paint(rdpContext* context) { + wStream* s; + int headerLength; + rdpUpdate* update = context->update; + if (!update->us) + return; + + s = update->us; + headerLength = Stream_Length(s); + Stream_SealLength(s); + + Stream_SetPosition(s, headerLength); + Stream_Write_UINT16(s, update->numberOrders); /* numberOrders (2 bytes) */ + Stream_SetPosition(s, Stream_Length(s)); + + if (update->numberOrders > 0) + { + fastpath_send_update_pdu(context->rdp->fastpath, FASTPATH_UPDATETYPE_ORDERS, s); + } + + update->combineUpdates = FALSE; + update->numberOrders = 0; + update->us = NULL; + + Stream_Free(s, TRUE); +} + +static void update_set_bounds(rdpContext* context, rdpBounds* bounds) +{ + rdpUpdate* update = context->update; + + CopyMemory(&update->previousBounds, &update->currentBounds, sizeof(rdpBounds)); + + if (!bounds) + ZeroMemory(&update->currentBounds, sizeof(rdpBounds)); + else + CopyMemory(&update->currentBounds, bounds, sizeof(rdpBounds)); +} + +BOOL update_bounds_is_null(rdpBounds* bounds) +{ + if ((bounds->left == 0) && (bounds->top == 0) && + (bounds->right == 0) && (bounds->bottom == 0)) + return TRUE; + + return FALSE; +} + +BOOL update_bounds_equals(rdpBounds* bounds1, rdpBounds* bounds2) +{ + if ((bounds1->left == bounds2->left) && (bounds1->top == bounds2->top) && + (bounds1->right == bounds2->right) && (bounds1->bottom == bounds2->bottom)) + return TRUE; + + return FALSE; +} + +int update_prepare_bounds(rdpContext* context, ORDER_INFO* orderInfo) +{ + int length = 0; + rdpUpdate* update = context->update; + + orderInfo->boundsFlags = 0; + + if (update_bounds_is_null(&update->currentBounds)) + return 0; + + orderInfo->controlFlags |= ORDER_BOUNDS; + + if (update_bounds_equals(&update->previousBounds, &update->currentBounds)) + { + orderInfo->controlFlags |= ORDER_ZERO_BOUNDS_DELTAS; + return 0; + } + else + { + length += 1; + + if (update->previousBounds.left != update->currentBounds.left) + { + orderInfo->bounds.left = update->currentBounds.left; + orderInfo->boundsFlags |= BOUND_LEFT; + length += 2; + } + + if (update->previousBounds.top != update->currentBounds.top) + { + orderInfo->bounds.top = update->currentBounds.top; + orderInfo->boundsFlags |= BOUND_TOP; + length += 2; + } + + if (update->previousBounds.right != update->currentBounds.right) + { + orderInfo->bounds.right = update->currentBounds.right; + orderInfo->boundsFlags |= BOUND_RIGHT; + length += 2; + } + + if (update->previousBounds.bottom != update->currentBounds.bottom) + { + orderInfo->bounds.bottom = update->currentBounds.bottom; + orderInfo->boundsFlags |= BOUND_BOTTOM; + length += 2; + } + } + + return length; +} + +int update_prepare_order_info(rdpContext* context, ORDER_INFO* orderInfo, UINT32 orderType) +{ + int length = 1; + + orderInfo->fieldFlags = 0; + orderInfo->orderType = orderType; + + orderInfo->controlFlags = ORDER_STANDARD; + + orderInfo->controlFlags |= ORDER_TYPE_CHANGE; + length += 1; + + length += PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType]; + + length += update_prepare_bounds(context, orderInfo); + + return length; +} + +int update_write_order_info(rdpContext* context, wStream* s, ORDER_INFO* orderInfo, int offset) +{ + int position; + + position = Stream_GetPosition(s); + Stream_SetPosition(s, offset); + + Stream_Write_UINT8(s, orderInfo->controlFlags); /* controlFlags (1 byte) */ + + if (orderInfo->controlFlags & ORDER_TYPE_CHANGE) + Stream_Write_UINT8(s, orderInfo->orderType); /* orderType (1 byte) */ + + update_write_field_flags(s, orderInfo->fieldFlags, orderInfo->controlFlags, + PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType]); + + update_write_bounds(s, orderInfo); + + Stream_SetPosition(s, position); + + return 0; } static void update_write_refresh_rect(wStream* s, BYTE count, RECTANGLE_16* areas) { int i; - stream_write_BYTE(s, count); /* numberOfAreas (1 byte) */ - stream_seek(s, 3); /* pad3Octets (3 bytes) */ + Stream_Write_UINT8(s, count); /* numberOfAreas (1 byte) */ + Stream_Seek(s, 3); /* pad3Octets (3 bytes) */ for (i = 0; i < count; i++) { - stream_write_UINT16(s, areas[i].left); /* left (2 bytes) */ - stream_write_UINT16(s, areas[i].top); /* top (2 bytes) */ - stream_write_UINT16(s, areas[i].right); /* right (2 bytes) */ - stream_write_UINT16(s, areas[i].bottom); /* bottom (2 bytes) */ + Stream_Write_UINT16(s, areas[i].left); /* left (2 bytes) */ + Stream_Write_UINT16(s, areas[i].top); /* top (2 bytes) */ + Stream_Write_UINT16(s, areas[i].right); /* right (2 bytes) */ + Stream_Write_UINT16(s, areas[i].bottom); /* bottom (2 bytes) */ } } @@ -479,15 +643,15 @@ static void update_send_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_ static void update_write_suppress_output(wStream* s, BYTE allow, RECTANGLE_16* area) { - stream_write_BYTE(s, allow); /* allowDisplayUpdates (1 byte) */ - stream_seek(s, 3); /* pad3Octets (3 bytes) */ + Stream_Write_UINT8(s, allow); /* allowDisplayUpdates (1 byte) */ + Stream_Seek(s, 3); /* pad3Octets (3 bytes) */ if (allow > 0) { - stream_write_UINT16(s, area->left); /* left (2 bytes) */ - stream_write_UINT16(s, area->top); /* top (2 bytes) */ - stream_write_UINT16(s, area->right); /* right (2 bytes) */ - stream_write_UINT16(s, area->bottom); /* bottom (2 bytes) */ + Stream_Write_UINT16(s, area->left); /* left (2 bytes) */ + Stream_Write_UINT16(s, area->top); /* top (2 bytes) */ + Stream_Write_UINT16(s, area->right); /* right (2 bytes) */ + Stream_Write_UINT16(s, area->bottom); /* bottom (2 bytes) */ } } @@ -511,8 +675,8 @@ static void update_send_surface_command(rdpContext* context, wStream* s) rdpRdp* rdp = context->rdp; update = fastpath_update_pdu_init(rdp->fastpath); - stream_check_size(update, stream_get_length(s)); - stream_write(update, stream_get_head(s), stream_get_length(s)); + Stream_EnsureRemainingCapacity(update, Stream_GetPosition(s)); + Stream_Write(update, Stream_Buffer(s), Stream_GetPosition(s)); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, update); } @@ -522,9 +686,9 @@ static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); - stream_check_size(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH + (int) surface_bits_command->bitmapDataLength); + Stream_EnsureRemainingCapacity(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH + (int) surface_bits_command->bitmapDataLength); update_write_surfcmd_surface_bits_header(s, surface_bits_command); - stream_write(s, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); + Stream_Write(s, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s); } @@ -546,7 +710,7 @@ static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId) if (rdp->settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE]) { s = rdp_data_pdu_init(rdp); - stream_write_UINT32(s, frameId); + Stream_Write_UINT32(s, frameId); rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id); } } @@ -557,7 +721,7 @@ static void update_send_synchronize(rdpContext* context) rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); - stream_write_zero(s, 2); /* pad2Octets (2 bytes) */ + Stream_Zero(s, 2); /* pad2Octets (2 bytes) */ fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SYNCHRONIZE, s); } @@ -569,27 +733,478 @@ static void update_send_desktop_resize(rdpContext* context) rdp_server_reactivate(context->rdp); } +static void update_send_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) +{ + wStream* s; + int offset; + int headerLength; + ORDER_INFO orderInfo; + rdpUpdate* update = context->update; + + headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_DSTBLT); + + s = update->us; + offset = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_dstblt_order(s, &orderInfo, dstblt); + update_write_order_info(context, s, &orderInfo, offset); + + update->numberOrders++; +} + +static void update_send_patblt(rdpContext* context, PATBLT_ORDER* patblt) +{ + wStream* s; + int offset; + int headerLength; + ORDER_INFO orderInfo; + rdpUpdate* update = context->update; + + headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_PATBLT); + + s = update->us; + offset = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_patblt_order(s, &orderInfo, patblt); + update_write_order_info(context, s, &orderInfo, offset); + + update->numberOrders++; +} + static void update_send_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) { wStream* s; - rdpRdp* rdp = context->rdp; + int offset; + int headerLength; + ORDER_INFO orderInfo; + rdpUpdate* update = context->update; - s = fastpath_update_pdu_init(rdp->fastpath); + headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_SCRBLT); - stream_write_UINT16(s, 1); /* numberOrders (2 bytes) */ - stream_write_BYTE(s, ORDER_STANDARD | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */ - stream_write_BYTE(s, ORDER_TYPE_SCRBLT); /* orderType (1 byte) */ - stream_write_BYTE(s, 0x7F); /* fieldFlags (variable) */ + s = update->us; + offset = Stream_GetPosition(s); - stream_write_UINT16(s, scrblt->nLeftRect); - stream_write_UINT16(s, scrblt->nTopRect); - stream_write_UINT16(s, scrblt->nWidth); - stream_write_UINT16(s, scrblt->nHeight); - stream_write_BYTE(s, scrblt->bRop); - stream_write_UINT16(s, scrblt->nXSrc); - stream_write_UINT16(s, scrblt->nYSrc); + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); - fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_ORDERS, s); + update_write_scrblt_order(s, &orderInfo, scrblt); + update_write_order_info(context, s, &orderInfo, offset); + + update->numberOrders++; +} + +static void update_send_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) +{ + wStream* s; + int offset; + int headerLength; + ORDER_INFO orderInfo; + rdpUpdate* update = context->update; + + headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_OPAQUE_RECT); + + s = update->us; + offset = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_opaque_rect_order(s, &orderInfo, opaque_rect); + update_write_order_info(context, s, &orderInfo, offset); + + update->numberOrders++; +} + +static void update_send_line_to(rdpContext* context, LINE_TO_ORDER* line_to) +{ + wStream* s; + int offset; + int headerLength; + ORDER_INFO orderInfo; + rdpUpdate* update = context->update; + + headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_LINE_TO); + + s = update->us; + offset = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_line_to_order(s, &orderInfo, line_to); + update_write_order_info(context, s, &orderInfo, offset); + + update->numberOrders++; +} + +static void update_send_memblt(rdpContext* context, MEMBLT_ORDER* memblt) +{ + wStream* s; + int offset; + int headerLength; + ORDER_INFO orderInfo; + rdpUpdate* update = context->update; + + headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_MEMBLT); + + s = update->us; + offset = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_memblt_order(s, &orderInfo, memblt); + update_write_order_info(context, s, &orderInfo, offset); + + update->numberOrders++; +} + +static void update_send_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyph_index) +{ + wStream* s; + int offset; + int headerLength; + ORDER_INFO orderInfo; + rdpUpdate* update = context->update; + + headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_GLYPH_INDEX); + + s = update->us; + offset = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_glyph_index_order(s, &orderInfo, glyph_index); + update_write_order_info(context, s, &orderInfo, offset); + + update->numberOrders++; +} + +static void update_send_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitmap) +{ + wStream* s; + int bm, em; + BYTE orderType; + int headerLength; + UINT16 extraFlags; + INT16 orderLength; + rdpUpdate* update = context->update; + + extraFlags = 0; + headerLength = 6; + + orderType = cache_bitmap->compressed ? + ORDER_TYPE_CACHE_BITMAP_COMPRESSED : ORDER_TYPE_BITMAP_UNCOMPRESSED; + + s = update->us; + bm = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_cache_bitmap_order(s, cache_bitmap, cache_bitmap->compressed, &extraFlags); + em = Stream_GetPosition(s); + + orderLength = (em - bm) - 13; + + Stream_SetPosition(s, bm); + Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */ + Stream_Write_UINT16(s, orderLength); /* orderLength (2 bytes) */ + Stream_Write_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ + Stream_Write_UINT8(s, orderType); /* orderType (1 byte) */ + Stream_SetPosition(s, em); + + update->numberOrders++; + + /** + * temporary workaround to avoid PDUs exceeding maximum size + */ + + update->EndPaint(context); + update->BeginPaint(context); +} + +static void update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2) +{ + wStream* s; + int bm, em; + BYTE orderType; + int headerLength; + UINT16 extraFlags; + INT16 orderLength; + rdpUpdate* update = context->update; + + extraFlags = 0; + headerLength = 6; + + orderType = cache_bitmap_v2->compressed ? + ORDER_TYPE_BITMAP_COMPRESSED_V2 : ORDER_TYPE_BITMAP_UNCOMPRESSED_V2; + + s = update->us; + bm = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_cache_bitmap_v2_order(s, cache_bitmap_v2, cache_bitmap_v2->compressed, &extraFlags); + em = Stream_GetPosition(s); + + orderLength = (em - bm) - 13; + + Stream_SetPosition(s, bm); + Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */ + Stream_Write_UINT16(s, orderLength); /* orderLength (2 bytes) */ + Stream_Write_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ + Stream_Write_UINT8(s, orderType); /* orderType (1 byte) */ + Stream_SetPosition(s, em); + + update->numberOrders++; + + /** + * temporary workaround to avoid PDUs exceeding maximum size + */ + + update->EndPaint(context); + update->BeginPaint(context); +} + +static void update_send_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3) +{ + wStream* s; + int bm, em; + BYTE orderType; + int headerLength; + UINT16 extraFlags; + INT16 orderLength; + rdpUpdate* update = context->update; + + extraFlags = 0; + headerLength = 6; + orderType = ORDER_TYPE_BITMAP_COMPRESSED_V3; + + s = update->us; + bm = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_cache_bitmap_v3_order(s, cache_bitmap_v3, &extraFlags); + em = Stream_GetPosition(s); + + orderLength = (em - bm) - 13; + + Stream_SetPosition(s, bm); + Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */ + Stream_Write_UINT16(s, orderLength); /* orderLength (2 bytes) */ + Stream_Write_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ + Stream_Write_UINT8(s, orderType); /* orderType (1 byte) */ + Stream_SetPosition(s, em); + + update->numberOrders++; + + /** + * temporary workaround to avoid PDUs exceeding maximum size + */ + + update->EndPaint(context); + update->BeginPaint(context); +} + +static void update_send_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE_ORDER* cache_color_table) +{ + wStream* s; + UINT16 flags; + int bm, em; + int headerLength; + INT16 orderLength; + rdpUpdate* update = context->update; + + flags = 0; + headerLength = 6; + + s = update->us; + bm = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_cache_color_table_order(s, cache_color_table, &flags); + em = Stream_GetPosition(s); + + orderLength = (em - bm) - 13; + + Stream_SetPosition(s, bm); + Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */ + Stream_Write_UINT16(s, orderLength); /* orderLength (2 bytes) */ + Stream_Write_UINT16(s, flags); /* extraFlags (2 bytes) */ + Stream_Write_UINT8(s, ORDER_TYPE_CACHE_COLOR_TABLE); /* orderType (1 byte) */ + Stream_SetPosition(s, em); + + update->numberOrders++; +} + +static void update_send_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph) +{ + wStream* s; + UINT16 flags; + int bm, em; + int headerLength; + INT16 orderLength; + rdpUpdate* update = context->update; + + flags = 0; + headerLength = 6; + + s = update->us; + bm = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_cache_glyph_order(s, cache_glyph, &flags); + em = Stream_GetPosition(s); + + orderLength = (em - bm) - 13; + + Stream_SetPosition(s, bm); + Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */ + Stream_Write_UINT16(s, orderLength); /* orderLength (2 bytes) */ + Stream_Write_UINT16(s, flags); /* extraFlags (2 bytes) */ + Stream_Write_UINT8(s, ORDER_TYPE_CACHE_GLYPH); /* orderType (1 byte) */ + Stream_SetPosition(s, em); + + update->numberOrders++; +} + +static void update_send_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER* cache_glyph_v2) +{ + wStream* s; + UINT16 flags; + int bm, em; + int headerLength; + INT16 orderLength; + rdpUpdate* update = context->update; + + flags = 0; + headerLength = 6; + + s = update->us; + bm = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_cache_glyph_v2_order(s, cache_glyph_v2, &flags); + em = Stream_GetPosition(s); + + orderLength = (em - bm) - 13; + + Stream_SetPosition(s, bm); + Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */ + Stream_Write_UINT16(s, orderLength); /* orderLength (2 bytes) */ + Stream_Write_UINT16(s, flags); /* extraFlags (2 bytes) */ + Stream_Write_UINT8(s, ORDER_TYPE_CACHE_GLYPH); /* orderType (1 byte) */ + Stream_SetPosition(s, em); + + update->numberOrders++; +} + +static void update_send_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush) +{ + wStream* s; + UINT16 flags; + int bm, em; + int headerLength; + INT16 orderLength; + rdpUpdate* update = context->update; + + flags = 0; + headerLength = 6; + + s = update->us; + bm = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_cache_brush_order(s, cache_brush, &flags); + em = Stream_GetPosition(s); + + orderLength = (em - bm) - 13; + + Stream_SetPosition(s, bm); + Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */ + Stream_Write_UINT16(s, orderLength); /* orderLength (2 bytes) */ + Stream_Write_UINT16(s, flags); /* extraFlags (2 bytes) */ + Stream_Write_UINT8(s, ORDER_TYPE_CACHE_BRUSH); /* orderType (1 byte) */ + Stream_SetPosition(s, em); + + update->numberOrders++; +} + +static void update_send_create_offscreen_bitmap_order(rdpContext* context, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap) +{ + wStream* s; + int bm, em; + BYTE orderType; + BYTE controlFlags; + int headerLength; + rdpUpdate* update = context->update; + + headerLength = 1; + orderType = ORDER_TYPE_CREATE_OFFSCREEN_BITMAP; + controlFlags = ORDER_SECONDARY | (orderType << 2); + + s = update->us; + bm = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_create_offscreen_bitmap_order(s, create_offscreen_bitmap); + em = Stream_GetPosition(s); + + Stream_SetPosition(s, bm); + Stream_Write_UINT8(s, controlFlags); /* controlFlags (1 byte) */ + Stream_SetPosition(s, em); + + update->numberOrders++; +} + +static void update_send_switch_surface_order(rdpContext* context, SWITCH_SURFACE_ORDER* switch_surface) +{ + wStream* s; + int bm, em; + BYTE orderType; + BYTE controlFlags; + int headerLength; + rdpUpdate* update = context->update; + + headerLength = 1; + orderType = ORDER_TYPE_SWITCH_SURFACE; + controlFlags = ORDER_SECONDARY | (orderType << 2); + + s = update->us; + bm = Stream_GetPosition(s); + + Stream_EnsureRemainingCapacity(s, headerLength); + Stream_Seek(s, headerLength); + + update_write_switch_surface_order(s, switch_surface); + em = Stream_GetPosition(s); + + Stream_SetPosition(s, bm); + Stream_Write_UINT8(s, controlFlags); /* controlFlags (1 byte) */ + Stream_SetPosition(s, em); + + update->numberOrders++; } static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system) @@ -610,23 +1225,23 @@ static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDAT static void update_write_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color) { - stream_check_size(s, 15 + (int) pointer_color->lengthAndMask + (int) pointer_color->lengthXorMask); + Stream_EnsureRemainingCapacity(s, 15 + (int) pointer_color->lengthAndMask + (int) pointer_color->lengthXorMask); - stream_write_UINT16(s, pointer_color->cacheIndex); - stream_write_UINT16(s, pointer_color->xPos); - stream_write_UINT16(s, pointer_color->yPos); - stream_write_UINT16(s, pointer_color->width); - stream_write_UINT16(s, pointer_color->height); - stream_write_UINT16(s, pointer_color->lengthAndMask); - stream_write_UINT16(s, pointer_color->lengthXorMask); + Stream_Write_UINT16(s, pointer_color->cacheIndex); + Stream_Write_UINT16(s, pointer_color->xPos); + Stream_Write_UINT16(s, pointer_color->yPos); + Stream_Write_UINT16(s, pointer_color->width); + Stream_Write_UINT16(s, pointer_color->height); + Stream_Write_UINT16(s, pointer_color->lengthAndMask); + Stream_Write_UINT16(s, pointer_color->lengthXorMask); if (pointer_color->lengthXorMask > 0) - stream_write(s, pointer_color->xorMaskData, pointer_color->lengthXorMask); + Stream_Write(s, pointer_color->xorMaskData, pointer_color->lengthXorMask); if (pointer_color->lengthAndMask > 0) - stream_write(s, pointer_color->andMaskData, pointer_color->lengthAndMask); + Stream_Write(s, pointer_color->andMaskData, pointer_color->lengthAndMask); - stream_write_BYTE(s, 0); /* pad (1 byte) */ + Stream_Write_UINT8(s, 0); /* pad (1 byte) */ } static void update_send_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* pointer_color) @@ -645,7 +1260,7 @@ static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* poi rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); - stream_write_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ + Stream_Write_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ update_write_pointer_color(s, &pointer_new->colorPtrAttr); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_POINTER, s); } @@ -656,7 +1271,7 @@ static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDAT rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); - stream_write_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */ + Stream_Write_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */ fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_CACHED, s); } @@ -666,22 +1281,23 @@ BOOL update_read_refresh_rect(rdpUpdate* update, wStream* s) BYTE numberOfAreas; RECTANGLE_16* areas; - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_BYTE(s, numberOfAreas); - stream_seek(s, 3); /* pad3Octects */ + Stream_Read_UINT8(s, numberOfAreas); + Stream_Seek(s, 3); /* pad3Octects */ - if (stream_get_left(s) < numberOfAreas * 4 * 2) + if (Stream_GetRemainingLength(s) < numberOfAreas * 4 * 2) return FALSE; + areas = (RECTANGLE_16*) malloc(sizeof(RECTANGLE_16) * numberOfAreas); for (index = 0; index < numberOfAreas; index++) { - stream_read_UINT16(s, areas[index].left); - stream_read_UINT16(s, areas[index].top); - stream_read_UINT16(s, areas[index].right); - stream_read_UINT16(s, areas[index].bottom); + Stream_Read_UINT16(s, areas[index].left); + Stream_Read_UINT16(s, areas[index].top); + Stream_Read_UINT16(s, areas[index].right); + Stream_Read_UINT16(s, areas[index].bottom); } IFCALL(update->RefreshRect, update->context, numberOfAreas, areas); @@ -695,17 +1311,17 @@ BOOL update_read_suppress_output(rdpUpdate* update, wStream* s) { BYTE allowDisplayUpdates; - if (stream_get_left(s) < 4) + if (Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_BYTE(s, allowDisplayUpdates); - stream_seek(s, 3); /* pad3Octects */ + Stream_Read_UINT8(s, allowDisplayUpdates); + Stream_Seek(s, 3); /* pad3Octects */ - if (allowDisplayUpdates > 0 && stream_get_left(s) < 8) + if (allowDisplayUpdates > 0 && Stream_GetRemainingLength(s) < 8) return FALSE; IFCALL(update->SuppressOutput, update->context, allowDisplayUpdates, - allowDisplayUpdates > 0 ? (RECTANGLE_16*) stream_get_tail(s) : NULL); + allowDisplayUpdates > 0 ? (RECTANGLE_16*) Stream_Pointer(s) : NULL); return TRUE; } @@ -714,12 +1330,28 @@ void update_register_server_callbacks(rdpUpdate* update) { update->BeginPaint = update_begin_paint; update->EndPaint = update_end_paint; + update->SetBounds = update_set_bounds; update->Synchronize = update_send_synchronize; update->DesktopResize = update_send_desktop_resize; update->SurfaceBits = update_send_surface_bits; update->SurfaceFrameMarker = update_send_surface_frame_marker; update->SurfaceCommand = update_send_surface_command; + update->primary->DstBlt = update_send_dstblt; + update->primary->PatBlt = update_send_patblt; update->primary->ScrBlt = update_send_scrblt; + update->primary->OpaqueRect = update_send_opaque_rect; + update->primary->LineTo = update_send_line_to; + update->primary->MemBlt = update_send_memblt; + update->primary->GlyphIndex = update_send_glyph_index; + update->secondary->CacheBitmap = update_send_cache_bitmap; + update->secondary->CacheBitmapV2 = update_send_cache_bitmap_v2; + update->secondary->CacheBitmapV3 = update_send_cache_bitmap_v3; + update->secondary->CacheColorTable = update_send_cache_color_table; + update->secondary->CacheGlyph = update_send_cache_glyph; + update->secondary->CacheGlyphV2 = update_send_cache_glyph_v2; + update->secondary->CacheBrush = update_send_cache_brush; + update->altsec->CreateOffscreenBitmap = update_send_create_offscreen_bitmap_order; + update->altsec->SwitchSurface = update_send_switch_surface_order; update->pointer->PointerSystem = update_send_pointer_system; update->pointer->PointerColor = update_send_pointer_color; update->pointer->PointerNew = update_send_pointer_new; @@ -744,7 +1376,7 @@ rdpUpdate* update_new(rdpRdp* rdp) update = (rdpUpdate*) malloc(sizeof(rdpUpdate)); - if (update != NULL) + if (update) { OFFSCREEN_DELETE_LIST* deleteList; diff --git a/libfreerdp/core/window.c b/libfreerdp/core/window.c index 418e4b696..7422f5b1f 100644 --- a/libfreerdp/core/window.c +++ b/libfreerdp/core/window.c @@ -30,29 +30,29 @@ BOOL update_read_icon_info(wStream* s, ICON_INFO* icon_info) { - if(stream_get_left(s) < 8) + if(Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT16(s, icon_info->cacheEntry); /* cacheEntry (2 bytes) */ - stream_read_BYTE(s, icon_info->cacheId); /* cacheId (1 byte) */ - stream_read_BYTE(s, icon_info->bpp); /* bpp (1 byte) */ - stream_read_UINT16(s, icon_info->width); /* width (2 bytes) */ - stream_read_UINT16(s, icon_info->height); /* height (2 bytes) */ + Stream_Read_UINT16(s, icon_info->cacheEntry); /* cacheEntry (2 bytes) */ + Stream_Read_UINT8(s, icon_info->cacheId); /* cacheId (1 byte) */ + Stream_Read_UINT8(s, icon_info->bpp); /* bpp (1 byte) */ + Stream_Read_UINT16(s, icon_info->width); /* width (2 bytes) */ + Stream_Read_UINT16(s, icon_info->height); /* height (2 bytes) */ /* cbColorTable is only present when bpp is 1, 2 or 4 */ if (icon_info->bpp == 1 || icon_info->bpp == 2 || icon_info->bpp == 4) { - if(stream_get_left(s) < 2) + if(Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, icon_info->cbColorTable); /* cbColorTable (2 bytes) */ + Stream_Read_UINT16(s, icon_info->cbColorTable); /* cbColorTable (2 bytes) */ } else { icon_info->cbColorTable = 0; } - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT16(s, icon_info->cbBitsMask); /* cbBitsMask (2 bytes) */ - stream_read_UINT16(s, icon_info->cbBitsColor); /* cbBitsColor (2 bytes) */ + Stream_Read_UINT16(s, icon_info->cbBitsMask); /* cbBitsMask (2 bytes) */ + Stream_Read_UINT16(s, icon_info->cbBitsColor); /* cbBitsColor (2 bytes) */ - if(stream_get_left(s) < icon_info->cbBitsMask + icon_info->cbBitsColor) + if(Stream_GetRemainingLength(s) < icon_info->cbBitsMask + icon_info->cbBitsColor) return FALSE; /* bitsMask */ @@ -60,39 +60,39 @@ BOOL update_read_icon_info(wStream* s, ICON_INFO* icon_info) icon_info->bitsMask = (BYTE*) malloc(icon_info->cbBitsMask); else icon_info->bitsMask = (BYTE*) realloc(icon_info->bitsMask, icon_info->cbBitsMask); - stream_read(s, icon_info->bitsMask, icon_info->cbBitsMask); + Stream_Read(s, icon_info->bitsMask, icon_info->cbBitsMask); /* colorTable */ if (icon_info->colorTable == NULL) icon_info->colorTable = (BYTE*) malloc(icon_info->cbColorTable); else icon_info->colorTable = (BYTE*) realloc(icon_info->colorTable, icon_info->cbColorTable); - stream_read(s, icon_info->colorTable, icon_info->cbColorTable); + Stream_Read(s, icon_info->colorTable, icon_info->cbColorTable); /* bitsColor */ if (icon_info->bitsColor == NULL) icon_info->bitsColor = (BYTE*) malloc(icon_info->cbBitsColor); else icon_info->bitsColor = (BYTE*) realloc(icon_info->bitsColor, icon_info->cbBitsColor); - stream_read(s, icon_info->bitsColor, icon_info->cbBitsColor); + Stream_Read(s, icon_info->bitsColor, icon_info->cbBitsColor); return TRUE; } BOOL update_read_cached_icon_info(wStream* s, CACHED_ICON_INFO* cached_icon_info) { - if(stream_get_left(s) < 3) + if(Stream_GetRemainingLength(s) < 3) return FALSE; - stream_read_UINT16(s, cached_icon_info->cacheEntry); /* cacheEntry (2 bytes) */ - stream_read_BYTE(s, cached_icon_info->cacheId); /* cacheId (1 byte) */ + Stream_Read_UINT16(s, cached_icon_info->cacheEntry); /* cacheEntry (2 bytes) */ + Stream_Read_UINT8(s, cached_icon_info->cacheId); /* cacheId (1 byte) */ return TRUE; } BOOL update_read_notify_icon_infotip(wStream* s, NOTIFY_ICON_INFOTIP* notify_icon_infotip) { - if(stream_get_left(s) < 8) + if(Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, notify_icon_infotip->timeout); /* timeout (4 bytes) */ - stream_read_UINT32(s, notify_icon_infotip->flags); /* infoFlags (4 bytes) */ + Stream_Read_UINT32(s, notify_icon_infotip->timeout); /* timeout (4 bytes) */ + Stream_Read_UINT32(s, notify_icon_infotip->flags); /* infoFlags (4 bytes) */ return rail_read_unicode_string(s, ¬ify_icon_infotip->text) && /* infoTipText */ rail_read_unicode_string(s, ¬ify_icon_infotip->title); /* title */ } @@ -103,23 +103,23 @@ BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderInfo, WI int size; if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) { - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, window_state->ownerWindowId); /* ownerWindowId (4 bytes) */ + Stream_Read_UINT32(s, window_state->ownerWindowId); /* ownerWindowId (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE) { - if(stream_get_left(s) < 8) + if(Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, window_state->style); /* style (4 bytes) */ - stream_read_UINT32(s, window_state->extendedStyle); /* extendedStyle (4 bytes) */ + Stream_Read_UINT32(s, window_state->style); /* style (4 bytes) */ + Stream_Read_UINT32(s, window_state->extendedStyle); /* extendedStyle (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW) { - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, window_state->showState); /* showState (1 byte) */ + Stream_Read_UINT8(s, window_state->showState); /* showState (1 byte) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) { @@ -129,105 +129,105 @@ BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderInfo, WI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) { - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, window_state->clientOffsetX); /* clientOffsetX (4 bytes) */ - stream_read_UINT32(s, window_state->clientOffsetY); /* clientOffsetY (4 bytes) */ + Stream_Read_UINT32(s, window_state->clientOffsetX); /* clientOffsetX (4 bytes) */ + Stream_Read_UINT32(s, window_state->clientOffsetY); /* clientOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) { - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, window_state->clientAreaWidth); /* clientAreaWidth (4 bytes) */ - stream_read_UINT32(s, window_state->clientAreaHeight); /* clientAreaHeight (4 bytes) */ + Stream_Read_UINT32(s, window_state->clientAreaWidth); /* clientAreaWidth (4 bytes) */ + Stream_Read_UINT32(s, window_state->clientAreaHeight); /* clientAreaHeight (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) { - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, window_state->RPContent); /* RPContent (1 byte) */ + Stream_Read_UINT8(s, window_state->RPContent); /* RPContent (1 byte) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) { - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, window_state->rootParentHandle);/* rootParentHandle (4 bytes) */ + Stream_Read_UINT32(s, window_state->rootParentHandle);/* rootParentHandle (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) { - if(stream_get_left(s) < 8) + if(Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, window_state->windowOffsetX); /* windowOffsetX (4 bytes) */ - stream_read_UINT32(s, window_state->windowOffsetY); /* windowOffsetY (4 bytes) */ + Stream_Read_UINT32(s, window_state->windowOffsetX); /* windowOffsetX (4 bytes) */ + Stream_Read_UINT32(s, window_state->windowOffsetY); /* windowOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) { - if(stream_get_left(s) < 8) + if(Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, window_state->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */ - stream_read_UINT32(s, window_state->windowClientDeltaY); /* windowClientDeltaY (4 bytes) */ + Stream_Read_UINT32(s, window_state->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */ + Stream_Read_UINT32(s, window_state->windowClientDeltaY); /* windowClientDeltaY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) { - if(stream_get_left(s) < 8) + if(Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, window_state->windowWidth); /* windowWidth (4 bytes) */ - stream_read_UINT32(s, window_state->windowHeight); /* windowHeight (4 bytes) */ + Stream_Read_UINT32(s, window_state->windowWidth); /* windowWidth (4 bytes) */ + Stream_Read_UINT32(s, window_state->windowHeight); /* windowHeight (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) { - if(stream_get_left(s) < 2) + if(Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, window_state->numWindowRects); /* numWindowRects (2 bytes) */ + Stream_Read_UINT16(s, window_state->numWindowRects); /* numWindowRects (2 bytes) */ size = sizeof(RECTANGLE_16) * window_state->numWindowRects; window_state->windowRects = (RECTANGLE_16*) malloc(size); - if(stream_get_left(s) < 8 * window_state->numWindowRects) + if(Stream_GetRemainingLength(s) < 8 * window_state->numWindowRects) return FALSE; /* windowRects */ for (i = 0; i < (int) window_state->numWindowRects; i++) { - stream_read_UINT16(s, window_state->windowRects[i].left); /* left (2 bytes) */ - stream_read_UINT16(s, window_state->windowRects[i].top); /* top (2 bytes) */ - stream_read_UINT16(s, window_state->windowRects[i].right); /* right (2 bytes) */ - stream_read_UINT16(s, window_state->windowRects[i].bottom); /* bottom (2 bytes) */ + Stream_Read_UINT16(s, window_state->windowRects[i].left); /* left (2 bytes) */ + Stream_Read_UINT16(s, window_state->windowRects[i].top); /* top (2 bytes) */ + Stream_Read_UINT16(s, window_state->windowRects[i].right); /* right (2 bytes) */ + Stream_Read_UINT16(s, window_state->windowRects[i].bottom); /* bottom (2 bytes) */ } } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) { - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, window_state->visibleOffsetX); /* visibleOffsetX (4 bytes) */ - stream_read_UINT32(s, window_state->visibleOffsetY); /* visibleOffsetY (4 bytes) */ + Stream_Read_UINT32(s, window_state->visibleOffsetX); /* visibleOffsetX (4 bytes) */ + Stream_Read_UINT32(s, window_state->visibleOffsetY); /* visibleOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) { - if(stream_get_left(s) < 2) + if(Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, window_state->numVisibilityRects); /* numVisibilityRects (2 bytes) */ + Stream_Read_UINT16(s, window_state->numVisibilityRects); /* numVisibilityRects (2 bytes) */ size = sizeof(RECTANGLE_16) * window_state->numVisibilityRects; window_state->visibilityRects = (RECTANGLE_16*) malloc(size); - if(stream_get_left(s) < window_state->numVisibilityRects * 8) + if(Stream_GetRemainingLength(s) < window_state->numVisibilityRects * 8) return FALSE; /* visibilityRects */ for (i = 0; i < (int) window_state->numVisibilityRects; i++) { - stream_read_UINT16(s, window_state->visibilityRects[i].left); /* left (2 bytes) */ - stream_read_UINT16(s, window_state->visibilityRects[i].top); /* top (2 bytes) */ - stream_read_UINT16(s, window_state->visibilityRects[i].right); /* right (2 bytes) */ - stream_read_UINT16(s, window_state->visibilityRects[i].bottom); /* bottom (2 bytes) */ + Stream_Read_UINT16(s, window_state->visibilityRects[i].left); /* left (2 bytes) */ + Stream_Read_UINT16(s, window_state->visibilityRects[i].top); /* top (2 bytes) */ + Stream_Read_UINT16(s, window_state->visibilityRects[i].right); /* right (2 bytes) */ + Stream_Read_UINT16(s, window_state->visibilityRects[i].bottom); /* bottom (2 bytes) */ } } return TRUE; @@ -256,9 +256,9 @@ BOOL update_recv_window_info_order(rdpUpdate* update, wStream* s, WINDOW_ORDER_I rdpContext* context = update->context; rdpWindowUpdate* window = update->window; - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */ + Stream_Read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */ if (orderInfo->fieldFlags & WINDOW_ORDER_ICON) { @@ -297,9 +297,9 @@ BOOL update_recv_window_info_order(rdpUpdate* update, wStream* s, WINDOW_ORDER_I BOOL update_read_notification_icon_state_order(wStream* s, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state) { if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) { - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, notify_icon_state->version); /* version (4 bytes) */ + Stream_Read_UINT32(s, notify_icon_state->version); /* version (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) { @@ -313,9 +313,9 @@ BOOL update_read_notification_icon_state_order(wStream* s, WINDOW_ORDER_INFO* or } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE) { - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, notify_icon_state->state); /* state (4 bytes) */ + Stream_Read_UINT32(s, notify_icon_state->state); /* state (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_ICON) { @@ -340,10 +340,10 @@ BOOL update_recv_notification_icon_info_order(rdpUpdate* update, wStream* s, WIN rdpContext* context = update->context; rdpWindowUpdate* window = update->window; - if(stream_get_left(s) < 8) + if(Stream_GetRemainingLength(s) < 8) return FALSE; - stream_read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */ - stream_read_UINT32(s, orderInfo->notifyIconId); /* notifyIconId (4 bytes) */ + Stream_Read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */ + Stream_Read_UINT32(s, orderInfo->notifyIconId); /* notifyIconId (4 bytes) */ if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED) { @@ -371,18 +371,18 @@ BOOL update_read_desktop_actively_monitored_order(wStream* s, WINDOW_ORDER_INFO* int size; if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) { - if(stream_get_left(s) < 4) + if(Stream_GetRemainingLength(s) < 4) return FALSE; - stream_read_UINT32(s, monitored_desktop->activeWindowId); /* activeWindowId (4 bytes) */ + Stream_Read_UINT32(s, monitored_desktop->activeWindowId); /* activeWindowId (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) { - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, monitored_desktop->numWindowIds); /* numWindowIds (1 byte) */ + Stream_Read_UINT8(s, monitored_desktop->numWindowIds); /* numWindowIds (1 byte) */ - if(stream_get_left(s) < 4 * monitored_desktop->numWindowIds) + if(Stream_GetRemainingLength(s) < 4 * monitored_desktop->numWindowIds) return FALSE; size = sizeof(UINT32) * monitored_desktop->numWindowIds; @@ -395,7 +395,7 @@ BOOL update_read_desktop_actively_monitored_order(wStream* s, WINDOW_ORDER_INFO* /* windowIds */ for (i = 0; i < (int) monitored_desktop->numWindowIds; i++) { - stream_read_UINT32(s, monitored_desktop->windowIds[i]); + Stream_Read_UINT32(s, monitored_desktop->windowIds[i]); } } return TRUE; @@ -432,10 +432,10 @@ BOOL update_recv_altsec_window_order(rdpUpdate* update, wStream* s) UINT16 orderSize; rdpWindowUpdate* window = update->window; - if(stream_get_left(s) < 6) + if(Stream_GetRemainingLength(s) < 6) return FALSE; - stream_read_UINT16(s, orderSize); /* orderSize (2 bytes) */ - stream_read_UINT32(s, window->orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */ + Stream_Read_UINT16(s, orderSize); /* orderSize (2 bytes) */ + Stream_Read_UINT32(s, window->orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */ if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW) return update_recv_window_info_order(update, s, &window->orderInfo); diff --git a/libfreerdp/crypto/ber.c b/libfreerdp/crypto/ber.c index 3272ff687..3809f6dfc 100644 --- a/libfreerdp/crypto/ber.c +++ b/libfreerdp/crypto/ber.c @@ -30,21 +30,21 @@ BOOL ber_read_length(wStream* s, int* length) { BYTE byte; - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte & 0x80) { byte &= ~(0x80); - if(stream_get_left(s) < byte) + if(Stream_GetRemainingLength(s) < byte) return FALSE; if (byte == 1) - stream_read_BYTE(s, *length); + Stream_Read_UINT8(s, *length); else if (byte == 2) - stream_read_UINT16_be(s, *length); + Stream_Read_UINT16_BE(s, *length); else return FALSE; } @@ -65,13 +65,13 @@ int ber_write_length(wStream* s, int length) { if (length > 0x7F) { - stream_write_BYTE(s, 0x82); - stream_write_UINT16_be(s, length); + Stream_Write_UINT8(s, 0x82); + Stream_Write_UINT16_BE(s, length); return 3; } else { - stream_write_BYTE(s, length); + Stream_Write_UINT8(s, length); return 1; } } @@ -103,9 +103,9 @@ BOOL ber_read_universal_tag(wStream* s, BYTE tag, BOOL pc) { BYTE byte; - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != (BER_CLASS_UNIV | BER_PC(pc) | (BER_TAG_MASK & tag))) return FALSE; @@ -122,7 +122,7 @@ BOOL ber_read_universal_tag(wStream* s, BYTE tag, BOOL pc) void ber_write_universal_tag(wStream* s, BYTE tag, BOOL pc) { - stream_write_BYTE(s, (BER_CLASS_UNIV | BER_PC(pc)) | (BER_TAG_MASK & tag)); + Stream_Write_UINT8(s, (BER_CLASS_UNIV | BER_PC(pc)) | (BER_TAG_MASK & tag)); } /** @@ -138,16 +138,16 @@ BOOL ber_read_application_tag(wStream* s, BYTE tag, int* length) if (tag > 30) { - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK)) return FALSE; - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != tag) return FALSE; @@ -156,9 +156,9 @@ BOOL ber_read_application_tag(wStream* s, BYTE tag, int* length) } else { - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | (BER_TAG_MASK & tag))) return FALSE; @@ -180,13 +180,13 @@ void ber_write_application_tag(wStream* s, BYTE tag, int length) { if (tag > 30) { - stream_write_BYTE(s, (BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK); - stream_write_BYTE(s, tag); + Stream_Write_UINT8(s, (BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK); + Stream_Write_UINT8(s, tag); ber_write_length(s, length); } else { - stream_write_BYTE(s, (BER_CLASS_APPL | BER_CONSTRUCT) | (BER_TAG_MASK & tag)); + Stream_Write_UINT8(s, (BER_CLASS_APPL | BER_CONSTRUCT) | (BER_TAG_MASK & tag)); ber_write_length(s, length); } } @@ -195,13 +195,13 @@ BOOL ber_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc) { BYTE byte; - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != ((BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag))) { - stream_rewind(s, 1); + Stream_Rewind(s, 1); return FALSE; } @@ -210,7 +210,7 @@ BOOL ber_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc) int ber_write_contextual_tag(wStream* s, BYTE tag, int length, BOOL pc) { - stream_write_BYTE(s, (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag)); + Stream_Write_UINT8(s, (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag)); return ber_write_length(s, length) + 1; } @@ -223,9 +223,9 @@ BOOL ber_read_sequence_tag(wStream* s, int* length) { BYTE byte; - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != ((BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_SEQUENCE_OF))) return FALSE; @@ -241,7 +241,7 @@ BOOL ber_read_sequence_tag(wStream* s, int* length) int ber_write_sequence_tag(wStream* s, int length) { - stream_write_BYTE(s, (BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_MASK & BER_TAG_SEQUENCE)); + Stream_Write_UINT8(s, (BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_MASK & BER_TAG_SEQUENCE)); return ber_write_length(s, length) + 1; } @@ -263,10 +263,10 @@ BOOL ber_read_enumerated(wStream* s, BYTE* enumerated, BYTE count) !ber_read_length(s, &length)) return FALSE; - if (length != 1 || stream_get_left(s) < 1) + if (length != 1 || Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, *enumerated); + Stream_Read_UINT8(s, *enumerated); /* check that enumerated value falls within expected range */ if (*enumerated + 1 > count) @@ -279,7 +279,7 @@ void ber_write_enumerated(wStream* s, BYTE enumerated, BYTE count) { ber_write_universal_tag(s, BER_TAG_ENUMERATED, FALSE); ber_write_length(s, 1); - stream_write_BYTE(s, enumerated); + Stream_Write_UINT8(s, enumerated); } BOOL ber_read_bit_string(wStream* s, int* length, BYTE* padding) @@ -288,9 +288,9 @@ BOOL ber_read_bit_string(wStream* s, int* length, BYTE* padding) !ber_read_length(s, length)) return FALSE; - if(stream_get_left(s) < 1) + if(Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, *padding); + Stream_Read_UINT8(s, *padding); return TRUE; } @@ -305,7 +305,7 @@ void ber_write_octet_string(wStream* s, const BYTE* oct_str, int length) { ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); ber_write_length(s, length); - stream_write(s, oct_str, length); + Stream_Write(s, oct_str, length); } BOOL ber_read_octet_string_tag(wStream* s, int* length) @@ -342,10 +342,10 @@ BOOL ber_read_BOOL(wStream* s, BOOL* value) !ber_read_length(s, &length)) return FALSE; - if (length != 1 || stream_get_left(s) < 1) + if (length != 1 || Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, v); + Stream_Read_UINT8(s, v); *value = (v ? TRUE : FALSE); return TRUE; } @@ -360,7 +360,7 @@ void ber_write_BOOL(wStream* s, BOOL value) { ber_write_universal_tag(s, BER_TAG_BOOLEAN, FALSE); ber_write_length(s, 1); - stream_write_BYTE(s, (value == TRUE) ? 0xFF : 0); + Stream_Write_UINT8(s, (value == TRUE) ? 0xFF : 0); } BOOL ber_read_integer(wStream* s, UINT32* value) @@ -369,33 +369,33 @@ BOOL ber_read_integer(wStream* s, UINT32* value) if (!ber_read_universal_tag(s, BER_TAG_INTEGER, FALSE) || !ber_read_length(s, &length) || - stream_get_left(s) < length) + Stream_GetRemainingLength(s) < length) return FALSE; if (value == NULL) { // even if we don't care the integer value, check the announced size - return stream_skip(s, length); + return Stream_SafeSeek(s, length); } if (length == 1) { - stream_read_BYTE(s, *value); + Stream_Read_UINT8(s, *value); } else if (length == 2) { - stream_read_UINT16_be(s, *value); + Stream_Read_UINT16_BE(s, *value); } else if (length == 3) { BYTE byte; - stream_read_BYTE(s, byte); - stream_read_UINT16_be(s, *value); + Stream_Read_UINT8(s, byte); + Stream_Read_UINT16_BE(s, *value); *value += (byte << 16); } else if (length == 4) { - stream_read_UINT32_be(s, *value); + Stream_Read_UINT32_BE(s, *value); } else if (length == 8) { @@ -424,26 +424,26 @@ int ber_write_integer(wStream* s, UINT32 value) if (value <= 0xFF) { ber_write_length(s, 1); - stream_write_BYTE(s, value); + Stream_Write_UINT8(s, value); return 2; } else if (value < 0xFF80) { ber_write_length(s, 2); - stream_write_UINT16_be(s, value); + Stream_Write_UINT16_BE(s, value); return 3; } else if (value < 0xFF8000) { ber_write_length(s, 3); - stream_write_BYTE(s, (value >> 16)); - stream_write_UINT16_be(s, (value & 0xFFFF)); + Stream_Write_UINT8(s, (value >> 16)); + Stream_Write_UINT16_BE(s, (value & 0xFFFF)); return 4; } else if (value <= 0xFFFFFFFF) { ber_write_length(s, 4); - stream_write_UINT32_be(s, value); + Stream_Write_UINT32_BE(s, value); return 5; } diff --git a/libfreerdp/crypto/der.c b/libfreerdp/crypto/der.c index 7c4694f17..2f69fa6a0 100644 --- a/libfreerdp/crypto/der.c +++ b/libfreerdp/crypto/der.c @@ -27,9 +27,9 @@ int _der_skip_length(int length) { - if (length > 0x81 && length <= 0x102) + if (length > 0x7F && length <= 0xFF) return 2; - else if (length > 0x102) + else if (length > 0xFF) return 3; else return 1; @@ -39,19 +39,19 @@ int der_write_length(wStream* s, int length) { if (length > 0x7F && length <= 0xFF) { - stream_write_BYTE(s, 0x81); - stream_write_BYTE(s, length); + Stream_Write_UINT8(s, 0x81); + Stream_Write_UINT8(s, length); return 2; } else if (length > 0xFF) { - stream_write_BYTE(s, 0x82); - stream_write_UINT16_be(s, length); + Stream_Write_UINT8(s, 0x82); + Stream_Write_UINT16_BE(s, length); return 3; } else { - stream_write_BYTE(s, length); + Stream_Write_UINT8(s, length); return 1; } } @@ -73,13 +73,13 @@ int der_skip_contextual_tag(int length) int der_write_contextual_tag(wStream* s, BYTE tag, int length, BOOL pc) { - stream_write_BYTE(s, (ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag)); + Stream_Write_UINT8(s, (ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag)); return der_write_length(s, length) + 1; } void der_write_universal_tag(wStream* s, BYTE tag, BOOL pc) { - stream_write_BYTE(s, (ER_CLASS_UNIV | ER_PC(pc)) | (ER_TAG_MASK & tag)); + Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_PC(pc)) | (ER_TAG_MASK & tag)); } int der_skip_octet_string(int length) @@ -91,7 +91,7 @@ void der_write_octet_string(wStream* s, BYTE* oct_str, int length) { der_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE); der_write_length(s, length); - stream_write(s, oct_str, length); + Stream_Write(s, oct_str, length); } int der_skip_sequence_tag(int length) @@ -101,7 +101,7 @@ int der_skip_sequence_tag(int length) int der_write_sequence_tag(wStream* s, int length) { - stream_write_BYTE(s, (ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_MASK & ER_TAG_SEQUENCE)); + Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_MASK & ER_TAG_SEQUENCE)); return der_write_length(s, length) + 1; } diff --git a/libfreerdp/crypto/er.c b/libfreerdp/crypto/er.c index 612752221..04d0c1ca6 100644 --- a/libfreerdp/crypto/er.c +++ b/libfreerdp/crypto/er.c @@ -32,16 +32,16 @@ void er_read_length(wStream* s, int* length) { BYTE byte; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte & 0x80) { byte &= ~(0x80); if (byte == 1) - stream_read_BYTE(s, *length); + Stream_Read_UINT8(s, *length); if (byte == 2) - stream_read_UINT16_be(s, *length); + Stream_Read_UINT16_BE(s, *length); } else { @@ -90,7 +90,7 @@ BOOL er_read_universal_tag(wStream* s, BYTE tag, BOOL pc) { BYTE byte; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != (ER_CLASS_UNIV | ER_PC(pc) | (ER_TAG_MASK & tag))) return FALSE; @@ -107,7 +107,7 @@ BOOL er_read_universal_tag(wStream* s, BYTE tag, BOOL pc) void er_write_universal_tag(wStream* s, BYTE tag, BOOL pc) { - stream_write_BYTE(s, (ER_CLASS_UNIV | ER_PC(pc)) | (ER_TAG_MASK & tag)); + Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_PC(pc)) | (ER_TAG_MASK & tag)); } /** @@ -123,12 +123,12 @@ BOOL er_read_application_tag(wStream* s, BYTE tag, int* length) if (tag > 30) { - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK)) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != tag) return FALSE; @@ -137,7 +137,7 @@ BOOL er_read_application_tag(wStream* s, BYTE tag, int* length) } else { - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag))) return FALSE; @@ -159,13 +159,13 @@ void er_write_application_tag(wStream* s, BYTE tag, int length, BOOL flag) { if (tag > 30) { - stream_write_BYTE(s, (ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK); - stream_write_BYTE(s, tag); + Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK); + Stream_Write_UINT8(s, tag); er_write_length(s, length, flag); } else { - stream_write_BYTE(s, (ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag)); + Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag)); er_write_length(s, length, flag); } } @@ -174,11 +174,11 @@ BOOL er_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc) { BYTE byte; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != ((ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag))) { - stream_rewind(s, 1); + Stream_Rewind(s, 1); return FALSE; } @@ -189,7 +189,7 @@ BOOL er_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc) int er_write_contextual_tag(wStream* s, BYTE tag, int length, BOOL pc, BOOL flag) { - stream_write_BYTE(s, (ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag)); + Stream_Write_UINT8(s, (ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag)); return er_write_length(s, length, flag) + 1; } @@ -202,7 +202,7 @@ BOOL er_read_sequence_tag(wStream* s, int* length) { BYTE byte; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte != ((ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_SEQUENCE_OF))) return FALSE; @@ -220,7 +220,7 @@ BOOL er_read_sequence_tag(wStream* s, int* length) int er_write_sequence_tag(wStream* s, int length, BOOL flag) { - stream_write_BYTE(s, (ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_MASK & ER_TAG_SEQUENCE)); + Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_MASK & ER_TAG_SEQUENCE)); return er_write_length(s, length, flag) + 1; } @@ -242,7 +242,7 @@ BOOL er_read_enumerated(wStream* s, BYTE* enumerated, BYTE count) er_read_length(s, &length); if (length == 1) - stream_read_BYTE(s, *enumerated); + Stream_Read_UINT8(s, *enumerated); else return FALSE; @@ -257,14 +257,14 @@ void er_write_enumerated(wStream* s, BYTE enumerated, BYTE count, BOOL flag) { er_write_universal_tag(s, ER_TAG_ENUMERATED, FALSE); er_write_length(s, 1, flag); - stream_write_BYTE(s, enumerated); + Stream_Write_UINT8(s, enumerated); } BOOL er_read_bit_string(wStream* s, int* length, BYTE* padding) { er_read_universal_tag(s, ER_TAG_BIT_STRING, FALSE); er_read_length(s, length); - stream_read_BYTE(s, *padding); + Stream_Read_UINT8(s, *padding); return TRUE; } @@ -273,7 +273,7 @@ BOOL er_write_bit_string_tag(wStream* s, UINT32 length, BYTE padding, BOOL flag) { er_write_universal_tag(s, ER_TAG_BIT_STRING, FALSE); er_write_length(s, length, flag); - stream_write_BYTE(s, padding); + Stream_Write_UINT8(s, padding); return TRUE; } @@ -297,7 +297,7 @@ void er_write_octet_string(wStream* s, BYTE* oct_str, int length, BOOL flag) { er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE); er_write_length(s, length, flag); - stream_write(s, oct_str, length); + Stream_Write(s, oct_str, length); } int er_write_octet_string_tag(wStream* s, int length, BOOL flag) @@ -328,7 +328,7 @@ BOOL er_read_BOOL(wStream* s, BOOL* value) er_read_length(s, &length); if (length != 1) return FALSE; - stream_read_BYTE(s, v); + Stream_Read_UINT8(s, v); *value = (v ? TRUE : FALSE); return TRUE; } @@ -343,7 +343,7 @@ void er_write_BOOL(wStream* s, BOOL value) { er_write_universal_tag(s, ER_TAG_BOOLEAN, FALSE); er_write_length(s, 1, FALSE); - stream_write_BYTE(s, (value == TRUE) ? 0xFF : 0); + Stream_Write_UINT8(s, (value == TRUE) ? 0xFF : 0); } BOOL er_read_integer(wStream* s, UINT32* value) @@ -355,25 +355,33 @@ BOOL er_read_integer(wStream* s, UINT32* value) if (value == NULL) { - stream_seek(s, length); + Stream_Seek(s, length); return TRUE; } if (length == 1) - stream_read_BYTE(s, *value); + { + Stream_Read_UINT8(s, *value); + } else if (length == 2) - stream_read_UINT16_be(s, *value); + { + Stream_Read_UINT16_BE(s, *value); + } else if (length == 3) { BYTE byte; - stream_read_BYTE(s, byte); - stream_read_UINT16_be(s, *value); + Stream_Read_UINT8(s, byte); + Stream_Read_UINT16_BE(s, *value); *value += (byte << 16); } else if (length == 4) - stream_read_UINT32_be(s, *value); + { + Stream_Read_UINT32_BE(s, *value); + } else + { return FALSE; + } return TRUE; } @@ -391,19 +399,19 @@ int er_write_integer(wStream* s, INT32 value) if (value <= 127 && value >= -128) { er_write_length(s, 1, FALSE); - stream_write_BYTE(s, value); + Stream_Write_UINT8(s, value); return 2; } else if (value <= 32767 && value >= -32768) { er_write_length(s, 2, FALSE); - stream_write_UINT16_be(s, value); + Stream_Write_UINT16_BE(s, value); return 3; } else { er_write_length(s, 4, FALSE); - stream_write_UINT32_be(s, value); + Stream_Write_UINT32_BE(s, value); return 5; } diff --git a/libfreerdp/crypto/per.c b/libfreerdp/crypto/per.c index 2a3631c01..ab6a409ad 100644 --- a/libfreerdp/crypto/per.c +++ b/libfreerdp/crypto/per.c @@ -34,19 +34,19 @@ BOOL per_read_length(wStream* s, UINT16* length) { BYTE byte; - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); if (byte & 0x80) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; byte &= ~(0x80); *length = (byte << 8); - stream_read_BYTE(s, byte); + Stream_Read_UINT8(s, byte); *length += byte; } else @@ -66,9 +66,9 @@ BOOL per_read_length(wStream* s, UINT16* length) void per_write_length(wStream* s, int length) { if (length > 0x7F) - stream_write_UINT16_be(s, (length | 0x8000)); + Stream_Write_UINT16_BE(s, (length | 0x8000)); else - stream_write_BYTE(s, length); + Stream_Write_UINT8(s, length); } /** @@ -80,10 +80,10 @@ void per_write_length(wStream* s, int length) BOOL per_read_choice(wStream* s, BYTE* choice) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, *choice); + Stream_Read_UINT8(s, *choice); return TRUE; } @@ -95,7 +95,7 @@ BOOL per_read_choice(wStream* s, BYTE* choice) void per_write_choice(wStream* s, BYTE choice) { - stream_write_BYTE(s, choice); + Stream_Write_UINT8(s, choice); } /** @@ -107,10 +107,10 @@ void per_write_choice(wStream* s, BYTE choice) BOOL per_read_selection(wStream* s, BYTE* selection) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, *selection); + Stream_Read_UINT8(s, *selection); return TRUE; } @@ -122,7 +122,7 @@ BOOL per_read_selection(wStream* s, BYTE* selection) void per_write_selection(wStream* s, BYTE selection) { - stream_write_BYTE(s, selection); + Stream_Write_UINT8(s, selection); } /** @@ -134,10 +134,10 @@ void per_write_selection(wStream* s, BYTE selection) BOOL per_read_number_of_sets(wStream* s, BYTE* number) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, *number); + Stream_Read_UINT8(s, *number); return TRUE; } @@ -149,7 +149,7 @@ BOOL per_read_number_of_sets(wStream* s, BYTE* number) void per_write_number_of_sets(wStream* s, BYTE number) { - stream_write_BYTE(s, number); + Stream_Write_UINT8(s, number); } /** @@ -160,10 +160,10 @@ void per_write_number_of_sets(wStream* s, BYTE number) BOOL per_read_padding(wStream* s, int length) { - if (stream_get_left(s) < length) + if (Stream_GetRemainingLength(s) < length) return FALSE; - stream_seek(s, length); + Stream_Seek(s, length); return TRUE; } @@ -178,7 +178,7 @@ void per_write_padding(wStream* s, int length) int i; for (i = 0; i < length; i++) - stream_write_BYTE(s, 0); + Stream_Write_UINT8(s, 0); } /** @@ -195,13 +195,13 @@ BOOL per_read_integer(wStream* s, UINT32* integer) if (!per_read_length(s, &length)) return FALSE; - if (stream_get_left(s) < length) + if (Stream_GetRemainingLength(s) < length) return FALSE; if (length == 1) - stream_read_BYTE(s, *integer); + Stream_Read_UINT8(s, *integer); else if (length == 2) - stream_read_UINT16_be(s, *integer); + Stream_Read_UINT16_BE(s, *integer); else return FALSE; @@ -219,17 +219,17 @@ void per_write_integer(wStream* s, UINT32 integer) if (integer <= 0xFF) { per_write_length(s, 1); - stream_write_BYTE(s, integer); + Stream_Write_UINT8(s, integer); } else if (integer <= 0xFFFF) { per_write_length(s, 2); - stream_write_UINT16_be(s, integer); + Stream_Write_UINT16_BE(s, integer); } else if (integer <= 0xFFFFFFFF) { per_write_length(s, 4); - stream_write_UINT32_be(s, integer); + Stream_Write_UINT32_BE(s, integer); } } @@ -243,10 +243,10 @@ void per_write_integer(wStream* s, UINT32 integer) BOOL per_read_integer16(wStream* s, UINT16* integer, UINT16 min) { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16_be(s, *integer); + Stream_Read_UINT16_BE(s, *integer); if (*integer + min > 0xFFFF) return FALSE; @@ -265,7 +265,7 @@ BOOL per_read_integer16(wStream* s, UINT16* integer, UINT16 min) void per_write_integer16(wStream* s, UINT16 integer, UINT16 min) { - stream_write_UINT16_be(s, integer - min); + Stream_Write_UINT16_BE(s, integer - min); } /** @@ -278,10 +278,10 @@ void per_write_integer16(wStream* s, UINT16 integer, UINT16 min) BOOL per_read_enumerated(wStream* s, BYTE* enumerated, BYTE count) { - if (stream_get_left(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; - stream_read_BYTE(s, *enumerated); + Stream_Read_UINT8(s, *enumerated); /* check that enumerated value falls within expected range */ if (*enumerated + 1 > count) @@ -300,7 +300,7 @@ BOOL per_read_enumerated(wStream* s, BYTE* enumerated, BYTE count) void per_write_enumerated(wStream* s, BYTE enumerated, BYTE count) { - stream_write_BYTE(s, enumerated); + Stream_Write_UINT8(s, enumerated); } /** @@ -322,17 +322,17 @@ BOOL per_read_object_identifier(wStream* s, BYTE oid[6]) if (length != 5) return FALSE; - if (stream_get_left(s) < length) + if (Stream_GetRemainingLength(s) < length) return FALSE; - stream_read_BYTE(s, t12); /* first two tuples */ + Stream_Read_UINT8(s, t12); /* first two tuples */ a_oid[0] = (t12 >> 4); a_oid[1] = (t12 & 0x0F); - stream_read_BYTE(s, a_oid[2]); /* tuple 3 */ - stream_read_BYTE(s, a_oid[3]); /* tuple 4 */ - stream_read_BYTE(s, a_oid[4]); /* tuple 5 */ - stream_read_BYTE(s, a_oid[5]); /* tuple 6 */ + Stream_Read_UINT8(s, a_oid[2]); /* tuple 3 */ + Stream_Read_UINT8(s, a_oid[3]); /* tuple 4 */ + Stream_Read_UINT8(s, a_oid[4]); /* tuple 5 */ + Stream_Read_UINT8(s, a_oid[5]); /* tuple 6 */ if ((a_oid[0] == oid[0]) && (a_oid[1] == oid[1]) && (a_oid[2] == oid[2]) && (a_oid[3] == oid[3]) && @@ -355,12 +355,12 @@ BOOL per_read_object_identifier(wStream* s, BYTE oid[6]) void per_write_object_identifier(wStream* s, BYTE oid[6]) { BYTE t12 = (oid[0] << 4) & (oid[1] & 0x0F); - stream_write_BYTE(s, 5); /* length */ - stream_write_BYTE(s, t12); /* first two tuples */ - stream_write_BYTE(s, oid[2]); /* tuple 3 */ - stream_write_BYTE(s, oid[3]); /* tuple 4 */ - stream_write_BYTE(s, oid[4]); /* tuple 5 */ - stream_write_BYTE(s, oid[5]); /* tuple 6 */ + Stream_Write_UINT8(s, 5); /* length */ + Stream_Write_UINT8(s, t12); /* first two tuples */ + Stream_Write_UINT8(s, oid[2]); /* tuple 3 */ + Stream_Write_UINT8(s, oid[3]); /* tuple 4 */ + Stream_Write_UINT8(s, oid[4]); /* tuple 5 */ + Stream_Write_UINT8(s, oid[5]); /* tuple 6 */ } /** @@ -375,7 +375,7 @@ void per_write_string(wStream* s, BYTE* str, int length) int i; for (i = 0; i < length; i++) - stream_write_BYTE(s, str[i]); + Stream_Write_UINT8(s, str[i]); } /** @@ -399,11 +399,11 @@ BOOL per_read_octet_string(wStream* s, BYTE* oct_str, int length, int min) if (mlength + min != length) return FALSE; - if (stream_get_left(s) < length) + if (Stream_GetRemainingLength(s) < length) return FALSE; - a_oct_str = s->pointer; - stream_seek(s, length); + a_oct_str = Stream_Pointer(s); + Stream_Seek(s, length); for (i = 0; i < length; i++) { @@ -432,7 +432,7 @@ void per_write_octet_string(wStream* s, BYTE* oct_str, int length, int min) per_write_length(s, mlength); for (i = 0; i < length; i++) - stream_write_BYTE(s, oct_str[i]); + Stream_Write_UINT8(s, oct_str[i]); } /** @@ -453,10 +453,10 @@ BOOL per_read_numeric_string(wStream* s, int min) length = (mlength + min + 1) / 2; - if (stream_get_left(s) < length) + if (Stream_GetRemainingLength(s) < length) return FALSE; - stream_seek(s, length); + Stream_Seek(s, length); return TRUE; } @@ -487,6 +487,6 @@ void per_write_numeric_string(wStream* s, BYTE* num_str, int length, int min) c2 = (c2 - 0x30) % 10; num = (c1 << 4) | c2; - stream_write_BYTE(s, num); /* string */ + Stream_Write_UINT8(s, num); /* string */ } } diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 878502f7f..920f20488 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -249,17 +249,16 @@ BOOL tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file) SSL_CTX_set_options(tls->ctx, options); - fprintf(stderr, "private key file: %s\n", privatekey_file); - if (SSL_CTX_use_RSAPrivateKey_file(tls->ctx, privatekey_file, SSL_FILETYPE_PEM) <= 0) { fprintf(stderr, "SSL_CTX_use_RSAPrivateKey_file failed\n"); + fprintf(stderr, "PrivateKeyFile: %s\n", privatekey_file); return FALSE; } tls->ssl = SSL_new(tls->ctx); - if (tls->ssl == NULL) + if (!tls->ssl) { fprintf(stderr, "SSL_new failed\n"); return FALSE; @@ -271,23 +270,6 @@ BOOL tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file) return FALSE; } - cert = tls_get_certificate(tls, FALSE); - - if (cert == NULL) - { - fprintf(stderr, "tls_connect: tls_get_certificate failed to return the server certificate.\n"); - return FALSE; - } - - if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength)) - { - fprintf(stderr, "tls_connect: crypto_cert_get_public_key failed to return the server public key.\n"); - tls_free_certificate(cert); - return FALSE; - } - - free(cert); - if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) { fprintf(stderr, "SSL_set_fd failed\n"); @@ -319,6 +301,23 @@ BOOL tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file) } } + cert = tls_get_certificate(tls, FALSE); + + if (!cert) + { + fprintf(stderr, "tls_connect: tls_get_certificate failed to return the server certificate.\n"); + return FALSE; + } + + if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength)) + { + fprintf(stderr, "tls_connect: crypto_cert_get_public_key failed to return the server public key.\n"); + tls_free_certificate(cert); + return FALSE; + } + + free(cert); + fprintf(stderr, "TLS connection accepted\n"); return TRUE; @@ -356,6 +355,18 @@ int tls_read(rdpTls* tls, BYTE* data, int length) status = 0; break; + case SSL_ERROR_SYSCALL: + if (errno == EAGAIN) + { + status = 0; + } + else + { + tls_print_error("SSL_read", tls->ssl, status); + status = -1; + } + break; + default: tls_print_error("SSL_read", tls->ssl, status); status = -1; @@ -404,6 +415,18 @@ int tls_write(rdpTls* tls, BYTE* data, int length) status = 0; break; + case SSL_ERROR_SYSCALL: + if (errno == EAGAIN) + { + status = 0; + } + else + { + tls_print_error("SSL_write", tls->ssl, status); + status = -1; + } + break; + default: tls_print_error("SSL_write", tls->ssl, status); status = -1; @@ -474,7 +497,7 @@ BOOL tls_print_error(char* func, SSL* connection, int value) return FALSE; case SSL_ERROR_SYSCALL: - fprintf(stderr, "%s: I/O error\n", func); + fprintf(stderr, "%s: I/O error: %s (%d)\n", func, strerror(errno), errno); tls_errors(func); return TRUE; diff --git a/libfreerdp/dummy.c b/libfreerdp/dummy.c new file mode 100644 index 000000000..b959f9be3 --- /dev/null +++ b/libfreerdp/dummy.c @@ -0,0 +1,5 @@ + +int dummy() +{ + return 0; +} diff --git a/libfreerdp/locale/keyboard_layout.c b/libfreerdp/locale/keyboard_layout.c index bbc5bbdbf..78e98cf5b 100644 --- a/libfreerdp/locale/keyboard_layout.c +++ b/libfreerdp/locale/keyboard_layout.c @@ -285,3 +285,28 @@ const char* freerdp_keyboard_get_layout_name_from_id(DWORD keyboardLayoutID) return "unknown"; } + +DWORD freerdp_keyboard_get_layout_id_from_name(const char* name) +{ + int i; + + for (i = 0; i < ARRAYSIZE(RDP_KEYBOARD_LAYOUT_TABLE); i++) + { + if (strcmp(RDP_KEYBOARD_LAYOUT_TABLE[i].name, name) == 0) + return RDP_KEYBOARD_LAYOUT_TABLE[i].code; + } + + for (i = 0; i < ARRAYSIZE(RDP_KEYBOARD_LAYOUT_VARIANT_TABLE); i++) + { + if (strcmp(RDP_KEYBOARD_LAYOUT_VARIANT_TABLE[i].name, name) == 0) + return RDP_KEYBOARD_LAYOUT_VARIANT_TABLE[i].code; + } + + for (i = 0; i < ARRAYSIZE(RDP_KEYBOARD_IME_TABLE); i++) + { + if (strcmp(RDP_KEYBOARD_IME_TABLE[i].name, name) == 0) + return RDP_KEYBOARD_IME_TABLE[i].code; + } + + return 0; +} diff --git a/libfreerdp/primitives/CMakeLists.txt b/libfreerdp/primitives/CMakeLists.txt index d9db4da17..8aa327c80 100644 --- a/libfreerdp/primitives/CMakeLists.txt +++ b/libfreerdp/primitives/CMakeLists.txt @@ -76,8 +76,6 @@ set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVER if(IPP_FOUND) include_directories(${IPP_INCLUDE_DIRS}) foreach(ipp_lib ${IPP_LIBRARIES}) - add_library("${ipp_lib}_imported" STATIC IMPORTED) - set_property(TARGET "${ipp_lib}_imported" PROPERTY IMPORTED_LOCATION "${IPP_LIBRARY_DIRS}/${ipp_lib}") set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} "${ipp_lib}_imported") endforeach() endif() diff --git a/libfreerdp/utils/rail.c b/libfreerdp/utils/rail.c index 521710091..00c0460f8 100644 --- a/libfreerdp/utils/rail.c +++ b/libfreerdp/utils/rail.c @@ -48,12 +48,12 @@ void rail_unicode_string_free(RAIL_UNICODE_STRING* unicode_string) BOOL rail_read_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string) { - if (stream_get_left(s) < 2) + if (Stream_GetRemainingLength(s) < 2) return FALSE; - stream_read_UINT16(s, unicode_string->length); /* cbString (2 bytes) */ + Stream_Read_UINT16(s, unicode_string->length); /* cbString (2 bytes) */ - if (stream_get_left(s) < unicode_string->length) + if (Stream_GetRemainingLength(s) < unicode_string->length) return FALSE; if (unicode_string->string == NULL) @@ -61,41 +61,41 @@ BOOL rail_read_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string) else unicode_string->string = (BYTE*) realloc(unicode_string->string, unicode_string->length); - stream_read(s, unicode_string->string, unicode_string->length); + Stream_Read(s, unicode_string->string, unicode_string->length); return TRUE; } void rail_write_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string) { - stream_check_size(s, 2 + unicode_string->length); - stream_write_UINT16(s, unicode_string->length); /* cbString (2 bytes) */ - stream_write(s, unicode_string->string, unicode_string->length); /* string */ + Stream_EnsureRemainingCapacity(s, 2 + unicode_string->length); + Stream_Write_UINT16(s, unicode_string->length); /* cbString (2 bytes) */ + Stream_Write(s, unicode_string->string, unicode_string->length); /* string */ } void rail_write_unicode_string_value(wStream* s, RAIL_UNICODE_STRING* unicode_string) { if (unicode_string->length > 0) { - stream_check_size(s, unicode_string->length); - stream_write(s, unicode_string->string, unicode_string->length); /* string */ + Stream_EnsureRemainingCapacity(s, unicode_string->length); + Stream_Write(s, unicode_string->string, unicode_string->length); /* string */ } } void rail_read_rectangle_16(wStream* s, RECTANGLE_16* rectangle_16) { - stream_read_UINT16(s, rectangle_16->left); /* left (2 bytes) */ - stream_read_UINT16(s, rectangle_16->top); /* top (2 bytes) */ - stream_read_UINT16(s, rectangle_16->right); /* right (2 bytes) */ - stream_read_UINT16(s, rectangle_16->bottom); /* bottom (2 bytes) */ + Stream_Read_UINT16(s, rectangle_16->left); /* left (2 bytes) */ + Stream_Read_UINT16(s, rectangle_16->top); /* top (2 bytes) */ + Stream_Read_UINT16(s, rectangle_16->right); /* right (2 bytes) */ + Stream_Read_UINT16(s, rectangle_16->bottom); /* bottom (2 bytes) */ } void rail_write_rectangle_16(wStream* s, RECTANGLE_16* rectangle_16) { - stream_write_UINT16(s, rectangle_16->left); /* left (2 bytes) */ - stream_write_UINT16(s, rectangle_16->top); /* top (2 bytes) */ - stream_write_UINT16(s, rectangle_16->right); /* right (2 bytes) */ - stream_write_UINT16(s, rectangle_16->bottom); /* bottom (2 bytes) */ + Stream_Write_UINT16(s, rectangle_16->left); /* left (2 bytes) */ + Stream_Write_UINT16(s, rectangle_16->top); /* top (2 bytes) */ + Stream_Write_UINT16(s, rectangle_16->right); /* right (2 bytes) */ + Stream_Write_UINT16(s, rectangle_16->bottom); /* bottom (2 bytes) */ } void* rail_clone_order(UINT32 event_type, void* order) diff --git a/libfreerdp/utils/svc_plugin.c b/libfreerdp/utils/svc_plugin.c index a47898fd7..f0869a6c6 100644 --- a/libfreerdp/utils/svc_plugin.c +++ b/libfreerdp/utils/svc_plugin.c @@ -116,24 +116,24 @@ static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT3 if (dataFlags & CHANNEL_FLAG_FIRST) { if (plugin->data_in != NULL) - stream_free(plugin->data_in); + Stream_Free(plugin->data_in, TRUE); - plugin->data_in = stream_new(totalLength); + plugin->data_in = Stream_New(NULL, totalLength); } data_in = plugin->data_in; - stream_check_size(data_in, (int) dataLength); - stream_write(data_in, pData, dataLength); + Stream_EnsureRemainingCapacity(data_in, (int) dataLength); + Stream_Write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) { - if (stream_get_size(data_in) != stream_get_length(data_in)) + if (Stream_Capacity(data_in) != Stream_GetPosition(data_in)) { fprintf(stderr, "svc_plugin_process_received: read error\n"); } plugin->data_in = NULL; - stream_set_pos(data_in, 0); + Stream_SetPosition(data_in, 0); MessageQueue_Post(plugin->MsgPipe->In, NULL, 0, (void*) data_in, NULL); } @@ -167,7 +167,7 @@ static void svc_plugin_open_event(UINT32 openHandle, UINT32 event, void* pData, break; case CHANNEL_EVENT_WRITE_COMPLETE: - stream_free((wStream*) pData); + Stream_Free((wStream*) pData, TRUE); break; case CHANNEL_EVENT_USER: @@ -247,7 +247,7 @@ static void svc_plugin_process_terminated(rdpSvcPlugin* plugin) if (plugin->data_in) { - stream_free(plugin->data_in); + Stream_Free(plugin->data_in, TRUE); plugin->data_in = NULL; } @@ -305,17 +305,17 @@ int svc_plugin_send(rdpSvcPlugin* plugin, wStream* data_out) { UINT32 status = 0; - DEBUG_SVC("length %d", (int) stream_get_length(data_out)); + DEBUG_SVC("length %d", (int) Stream_GetPosition(data_out)); if (!plugin) status = CHANNEL_RC_BAD_INIT_HANDLE; else status = plugin->channel_entry_points.pVirtualChannelWrite(plugin->open_handle, - stream_get_data(data_out), stream_get_length(data_out), data_out); + Stream_Buffer(data_out), Stream_GetPosition(data_out), data_out); if (status != CHANNEL_RC_OK) { - stream_free(data_out); + Stream_Free(data_out, TRUE); fprintf(stderr, "svc_plugin_send: VirtualChannelWrite failed %d\n", status); } @@ -326,7 +326,8 @@ int svc_plugin_send_event(rdpSvcPlugin* plugin, wMessage* event) { UINT32 status = 0; - DEBUG_SVC("event_type %d", event->event_type); + DEBUG_SVC("event class: %d type: %d", + GetMessageClass(event->id), GetMessageType(event->id)); status = plugin->channel_entry_points.pVirtualChannelEventPush(plugin->open_handle, event); diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 000000000..e8786806f --- /dev/null +++ b/server/.gitignore @@ -0,0 +1,3 @@ +WaykServer +xrdp-ng + diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 97bef04f5..265706ba5 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -35,3 +35,13 @@ else() add_subdirectory(Windows) endif() +if(WITH_WAYK) + if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/WaykServer") + add_subdirectory(WaykServer) + endif() +endif() + +if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/xrdp-ng") + add_subdirectory("xrdp-ng") +endif() + diff --git a/server/Mac/mf_peer.c b/server/Mac/mf_peer.c index 2d0c8ee61..019efb0eb 100644 --- a/server/Mac/mf_peer.c +++ b/server/Mac/mf_peer.c @@ -133,8 +133,8 @@ void mf_peer_rfx_update(freerdp_peer* client) s = mfp->s; - stream_clear(s); - stream_set_pos(s, 0); + Stream_Clear(s); + Stream_SetPosition(s, 0); UINT32 x = mfi->invalid.x / mfi->scale; UINT32 y = mfi->invalid.y / mfi->scale; @@ -160,8 +160,8 @@ void mf_peer_rfx_update(freerdp_peer* client) cmd->codecID = 3; cmd->width = rect.width; cmd->height = rect.height; - cmd->bitmapDataLength = stream_get_length(s); - cmd->bitmapData = stream_get_head(s); + cmd->bitmapDataLength = Stream_GetPosition(s); + cmd->bitmapData = Stream_Buffer(s); //send @@ -184,7 +184,7 @@ void mf_peer_context_new(freerdp_peer* client, mfPeerContext* context) //context->nsc_context = nsc_context_new(); //nsc_context_set_pixel_format(context->nsc_context, RDP_PIXEL_FORMAT_B8G8R8A8); - context->s = stream_new(0xFFFF); + context->s = Stream_New(NULL, 0xFFFF); //#ifdef WITH_SERVER_CHANNELS context->vcm = WTSCreateVirtualChannelManager(client); @@ -203,7 +203,7 @@ void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context) dispatch_suspend(info_timer); - stream_free(context->s); + Stream_Free(context->s, TRUE); rfx_context_free(context->rfx_context); //nsc_context_free(context->nsc_context); diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index 323edc532..637e634ba 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -55,7 +55,7 @@ void test_peer_context_new(freerdp_peer* client, testPeerContext* context) context->nsc_context = nsc_context_new(); nsc_context_set_pixel_format(context->nsc_context, RDP_PIXEL_FORMAT_R8G8B8); - context->s = stream_new(65536); + context->s = Stream_New(NULL, 65536); context->icon_x = -1; context->icon_y = -1; @@ -74,7 +74,7 @@ void test_peer_context_free(freerdp_peer* client, testPeerContext* context) CloseHandle(context->debug_channel_thread); } - stream_free(context->s); + Stream_Free(context->s, TRUE); free(context->icon_data); free(context->bg_data); @@ -104,8 +104,8 @@ static void test_peer_init(freerdp_peer* client) static wStream* test_peer_stream_init(testPeerContext* context) { - stream_clear(context->s); - stream_set_pos(context->s, 0); + Stream_Clear(context->s); + Stream_SetPosition(context->s, 0); return context->s; } @@ -179,8 +179,8 @@ static void test_peer_draw_background(freerdp_peer* client) cmd->bpp = 32; cmd->width = rect.width; cmd->height = rect.height; - cmd->bitmapDataLength = stream_get_length(s); - cmd->bitmapData = stream_get_head(s); + cmd->bitmapDataLength = Stream_GetPosition(s); + cmd->bitmapData = Stream_Buffer(s); update->SurfaceBits(update->context, cmd); free(rgb_data); @@ -278,8 +278,8 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y) cmd->bpp = 32; cmd->width = context->icon_width; cmd->height = context->icon_height; - cmd->bitmapDataLength = stream_get_length(s); - cmd->bitmapData = stream_get_head(s); + cmd->bitmapDataLength = Stream_GetPosition(s); + cmd->bitmapData = Stream_Buffer(s); update->SurfaceBits(update->context, cmd); } @@ -305,8 +305,8 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y) cmd->bpp = 32; cmd->width = context->icon_width; cmd->height = context->icon_height; - cmd->bitmapDataLength = stream_get_length(s); - cmd->bitmapData = stream_get_head(s); + cmd->bitmapDataLength = Stream_GetPosition(s); + cmd->bitmapData = Stream_Buffer(s); update->SurfaceBits(update->context, cmd); context->icon_x = x; @@ -362,7 +362,7 @@ void tf_peer_dump_rfx(freerdp_peer* client) rdpPcap* pcap_rfx; pcap_record record; - s = stream_new(512); + s = Stream_New(NULL, 512); update = client->update; client->update->pcap_rfx = pcap_open(test_pcap_file, FALSE); pcap_rfx = client->update->pcap_rfx; @@ -376,12 +376,12 @@ void tf_peer_dump_rfx(freerdp_peer* client) { pcap_get_next_record_header(pcap_rfx, &record); - s->buffer = realloc(s->buffer, record.length); - record.data = s->buffer; - s->capacity = record.length; + Stream_Buffer(s) = realloc(Stream_Buffer(s), record.length); + record.data = Stream_Buffer(s); + Stream_Capacity(s) = record.length; pcap_get_next_record_content(pcap_rfx, &record); - s->pointer = s->buffer + s->capacity; + Stream_Pointer(s) = Stream_Buffer(s) + Stream_Capacity(s); if (test_dump_rfx_realtime && test_sleep_tsdiff(&prev_seconds, &prev_useconds, record.header.ts_sec, record.header.ts_usec) == FALSE) break; @@ -406,7 +406,7 @@ static void* tf_debug_channel_thread_func(void* arg) context->event = CreateWaitObjectEvent(NULL, TRUE, FALSE, fd); } - s = stream_new(4096); + s = Stream_New(NULL, 4096); WTSVirtualChannelWrite(context->debug_channel, (BYTE*) "test1", 5, NULL); @@ -417,30 +417,30 @@ static void* tf_debug_channel_thread_func(void* arg) if (WaitForSingleObject(context->stopEvent, 0) == WAIT_OBJECT_0) break; - stream_set_pos(s, 0); + Stream_SetPosition(s, 0); - if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), - stream_get_size(s), &bytes_returned) == FALSE) + if (WTSVirtualChannelRead(context->debug_channel, 0, Stream_Buffer(s), + Stream_Capacity(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; - stream_check_size(s, bytes_returned); + Stream_EnsureRemainingCapacity(s, bytes_returned); - if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), - stream_get_size(s), &bytes_returned) == FALSE) + if (WTSVirtualChannelRead(context->debug_channel, 0, Stream_Buffer(s), + Stream_Capacity(s), &bytes_returned) == FALSE) { /* should not happen */ break; } } - stream_set_pos(s, bytes_returned); + Stream_SetPosition(s, bytes_returned); printf("got %d bytes\n", bytes_returned); } - stream_free(s); + Stream_Free(s, TRUE); return 0; } diff --git a/server/Windows/wf_update.c b/server/Windows/wf_update.c index 7b68f4f9c..c8e8dc796 100644 --- a/server/Windows/wf_update.c +++ b/server/Windows/wf_update.c @@ -123,7 +123,7 @@ void wf_update_encode(wfInfo* wfi) cmd = &wfi->cmd; - stream_set_pos(wfi->s, 0); + Stream_SetPosition(wfi->s, 0); wf_info_getScreenData(wfi, &width, &height, &pDataBits, &stride); @@ -134,7 +134,7 @@ void wf_update_encode(wfInfo* wfi) //printf("x:%d y:%d w:%d h:%d\n", wfi->invalid.left, wfi->invalid.top, width, height); - stream_clear(wfi->s); + Stream_Clear(wfi->s); rfx_compose_message(wfi->rfx_context, wfi->s, &rect, 1, pDataBits, width, height, stride); @@ -149,8 +149,8 @@ void wf_update_encode(wfInfo* wfi) cmd->codecID = 3; cmd->width = width; cmd->height = height; - cmd->bitmapDataLength = stream_get_length(wfi->s); - cmd->bitmapData = stream_get_head(wfi->s); + cmd->bitmapDataLength = Stream_GetPosition(wfi->s); + cmd->bitmapData = Stream_Buffer(wfi->s); } void wf_update_peer_send(wfInfo* wfi, wfPeerContext* context) @@ -203,7 +203,7 @@ void wf_update_encoder_reset(wfInfo* wfi) wfi->rfx_context->width = wfi->servscreen_width; wfi->rfx_context->height = wfi->servscreen_height; rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); - wfi->s = stream_new(0xFFFF); + wfi->s = Stream_New(NULL, 0xFFFF); } wf_info_invalidate_full_screen(wfi); diff --git a/server/X11/CMakeLists.txt b/server/X11/CMakeLists.txt index d4e708df8..2af6f8f2e 100644 --- a/server/X11/CMakeLists.txt +++ b/server/X11/CMakeLists.txt @@ -16,17 +16,40 @@ # limitations under the License. set(MODULE_NAME "xfreerdp-server") -set(MODULE_PREFIX "FREERDP_SERVER_X11") +set(MODULE_PREFIX "FREERDP_SERVER_X11_CONTROL") include_directories(${X11_INCLUDE_DIRS}) +include_directories("../../winpr/tools/makecert") set(${MODULE_PREFIX}_SRCS xf_peer.c + xf_peer.h xf_input.c + xf_input.h xf_encode.c - xfreerdp.c) + xf_encode.h + xf_update.c + xf_update.h + xf_cursor.c + xf_cursor.h + xf_monitors.c + xf_monitors.h + xf_interface.c + xf_interface.h + xfreerdp.h) -add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +if(WITH_SERVER_INTERFACE) + if(SERVER_INTERFACE_SHARED) + add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS}) + else() + add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + endif() + set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION} PREFIX "lib") +else() + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/xfreerdp.c) + add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp-server") +endif() set(XEXT_FEATURE_TYPE "RECOMMENDED") set(XEXT_FEATURE_PURPOSE "X11 extension") @@ -36,14 +59,26 @@ set(XSHM_FEATURE_TYPE "RECOMMENDED") set(XSHM_FEATURE_PURPOSE "X11 shared memory") set(XSHM_FEATURE_DESCRIPTION "X11 shared memory extension") +set(XINERAMA_FEATURE_TYPE "RECOMMENDED") +set(XINERAMA_FEATURE_PURPOSE "multi-monitor") +set(XINERAMA_FEATURE_DESCRIPTION "X11 multi-monitor extension") + set(XTEST_FEATURE_TYPE "RECOMMENDED") set(XTEST_FEATURE_PURPOSE "X11 input event injection") set(XTEST_FEATURE_DESCRIPTION "X11 input event injection extension") +set(XCURSOR_FEATURE_TYPE "RECOMMENDED") +set(XCURSOR_FEATURE_PURPOSE "cursor") +set(XCURSOR_FEATURE_DESCRIPTION "X11 cursor extension") + set(XFIXES_FEATURE_TYPE "RECOMMENDED") set(XFIXES_FEATURE_PURPOSE "X11 region") set(XFIXES_FEATURE_DESCRIPTION "X11 region fix extension") +set(XRANDR_FEATURE_TYPE "RECOMMENDED") +set(XRANDR_FEATURE_PURPOSE "X11 resize, rotate and reflect") +set(XRANDR_FEATURE_DESCRIPTION "X11 resize, rotate and reflect extension") + set(XDAMAGE_FEATURE_TYPE "RECOMMENDED") set(XDAMAGE_FEATURE_PURPOSE "X11 region damage") set(XDAMAGE_FEATURE_DESCRIPTION "X11 region damage extension") @@ -52,7 +87,10 @@ find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DE find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION}) find_feature(XTest ${XTEST_FEATURE_TYPE} ${XTEST_FEATURE_PURPOSE} ${XTEST_FEATURE_DESCRIPTION}) find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION}) +find_feature(XRandR ${XRANDR_FEATURE_TYPE} ${XRANDR_FEATURE_PURPOSE} ${XRANDR_FEATURE_DESCRIPTION}) find_feature(Xdamage ${XDAMAGE_FEATURE_TYPE} ${XDAMAGE_FEATURE_PURPOSE} ${XDAMAGE_FEATURE_DESCRIPTION}) +find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSOR_FEATURE_DESCRIPTION}) +find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION}) if(WITH_XSHM) add_definitions(-DWITH_XSHM) @@ -65,6 +103,18 @@ if(WITH_XEXT) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XEXT_LIBRARIES}) endif() +if(WITH_XINERAMA) + add_definitions(-DWITH_XINERAMA) + include_directories(${XINERAMA_INCLUDE_DIRS}) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XINERAMA_LIBRARIES}) +endif() + +if(WITH_XCURSOR) + add_definitions(-DWITH_XCURSOR) + include_directories(${XCURSOR_INCLUDE_DIRS}) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XCURSOR_LIBRARIES}) +endif() + if(WITH_XDAMAGE) add_definitions(-DWITH_XDAMAGE) include_directories(${XDAMAGE_INCLUDE_DIRS}) @@ -84,6 +134,12 @@ if(WITH_XTEST) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XTEST_LIBRARIES}) endif() +if(WITH_XRANDR) + add_definitions(-DWITH_XRANDR) + include_directories(${XRANDR_INCLUDE_DIRS}) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRANDR_LIBRARIES}) +endif() + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${X11_LIBRARIES}) set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS @@ -94,10 +150,18 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE winpr - MODULES winpr-sspi) + MODULES winpr-sspi winpr-crt winpr-utils winpr-input winpr-sysinfo) + +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr-makecert-tool) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) + +if(WITH_SERVER_INTERFACE) + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries) + add_subdirectory(cli) +else() + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server) +endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/X11") diff --git a/server/X11/cli/CMakeLists.txt b/server/X11/cli/CMakeLists.txt new file mode 100644 index 000000000..6d0d45ff3 --- /dev/null +++ b/server/X11/cli/CMakeLists.txt @@ -0,0 +1,36 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# FreeRDP X11 cmake build script +# +# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(MODULE_NAME "xfreerdp-server-cli") +set(MODULE_PREFIX "FREERDP_SERVER_X11") + +include_directories(..) + +set(${MODULE_PREFIX}_SRCS + xfreerdp.c) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp-server" RUNTIME_OUTPUT_DIRECTORY "..") + +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} xfreerdp-server) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +install(TARGETS ${MODULE_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server) + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/X11") + diff --git a/server/X11/cli/xfreerdp-server b/server/X11/cli/xfreerdp-server new file mode 100755 index 000000000..9e837526b Binary files /dev/null and b/server/X11/cli/xfreerdp-server differ diff --git a/server/X11/cli/xfreerdp.c b/server/X11/cli/xfreerdp.c new file mode 100644 index 000000000..bd3b27729 --- /dev/null +++ b/server/X11/cli/xfreerdp.c @@ -0,0 +1,52 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP X11 Server + * + * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf_interface.h" + +int main(int argc, char* argv[]) +{ + HANDLE thread; + xfServer* server; + DWORD dwExitCode; + + freerdp_server_global_init(); + + server = freerdp_server_new(argc, argv); + + if (!server) + return 0; + + freerdp_server_start(server); + + thread = freerdp_server_get_thread(server); + + WaitForSingleObject(thread, INFINITE); + + GetExitCodeThread(thread, &dwExitCode); + + freerdp_server_free(server); + + freerdp_server_global_uninit(); + + return 0; +} diff --git a/server/X11/xf_cursor.c b/server/X11/xf_cursor.c new file mode 100644 index 000000000..ebd523f29 --- /dev/null +++ b/server/X11/xf_cursor.c @@ -0,0 +1,55 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * X11 Server Cursor + * + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#ifdef WITH_XCURSOR +#include <X11/Xcursor/Xcursor.h> +#endif + +#ifdef WITH_XFIXES +#include <X11/extensions/Xfixes.h> +#endif + +#include <winpr/crt.h> + +#include "xf_cursor.h" + +int xf_cursor_init(xfInfo* xfi) +{ + int event; + int error; + + if (!XFixesQueryExtension(xfi->display, &event, &error)) + { + fprintf(stderr, "XFixesQueryExtension failed\n"); + return -1; + } + + xfi->xfixes_notify_event = event + XFixesCursorNotify; + + XFixesSelectCursorInput(xfi->display, DefaultRootWindow(xfi->display), XFixesDisplayCursorNotifyMask); + + return 0; +} diff --git a/client/Mac/MRDPWindow.m b/server/X11/xf_cursor.h similarity index 71% rename from client/Mac/MRDPWindow.m rename to server/X11/xf_cursor.h index e5e5e402f..64c95c312 100644 --- a/client/Mac/MRDPWindow.m +++ b/server/X11/xf_cursor.h @@ -1,8 +1,8 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * MacFreeRDP + * X11 Server Cursor * - * Copyright 2012 Thomas Goddard + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,11 @@ * limitations under the License. */ -#include "MRDPWindow.h" +#ifndef XFREERDP_SERVER_CURSOR_H +#define XFREERDP_SERVER_CURSOR_H -@implementation MRDPWindow +#include "xfreerdp.h" -@synthesize windowID; -@synthesize window; -@synthesize view; +int xf_cursor_init(xfInfo* xfi); -@end +#endif /* XFREERDP_SERVER_CURSOR_H */ diff --git a/server/X11/xf_encode.c b/server/X11/xf_encode.c index ca10744c4..54830f5cf 100644 --- a/server/X11/xf_encode.c +++ b/server/X11/xf_encode.c @@ -22,12 +22,12 @@ #endif #include <X11/Xlib.h> +#include <X11/Xutil.h> #include <sys/select.h> #include <sys/signal.h> #include <winpr/crt.h> -#include <winpr/synch.h> #include "xf_encode.h" @@ -65,116 +65,85 @@ void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int #endif } -void* xf_frame_rate_thread(void* param) +int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height) { + wStream* s; + BYTE* data; xfInfo* xfi; - HGDI_RGN region; + RFX_RECT rect; + XImage* image; + rdpUpdate* update; xfPeerContext* xfp; - freerdp_peer* client; - UINT32 wait_interval; + SURFACE_BITS_COMMAND* cmd; - client = (freerdp_peer*) param; + update = client->update; xfp = (xfPeerContext*) client->context; + cmd = &update->surface_bits_command; xfi = xfp->info; - region = xfp->hdc->hwnd->invalid; - wait_interval = 1000000 / xfp->fps; - - while (1) + if (width * height <= 0) { - /* check if we should terminate */ - pthread_testcancel(); - - if (!region->null) - { - UINT32 xy, wh; - - pthread_mutex_lock(&(xfp->mutex)); - - xy = (region->x << 16) | region->y; - wh = (region->w << 16) | region->h; - region->null = 1; - - pthread_mutex_unlock(&(xfp->mutex)); - - MessageQueue_Post(xfp->queue, (void*) xfp, - MakeMessageId(PeerEvent, EncodeRegion), - (void*) (size_t) xy, (void*) (size_t) wh); - } - - USleep(wait_interval); + cmd->bitmapDataLength = 0; + return -1; } - return NULL; -} + s = xfp->s; + Stream_Clear(s); + Stream_SetPosition(s, 0); -void* xf_monitor_updates(void* param) -{ - int fds; - xfInfo* xfi; - XEvent xevent; - fd_set rfds_set; - int select_status; - xfPeerContext* xfp; - freerdp_peer* client; - UINT32 wait_interval; - struct timeval timeout; - int x, y, width, height; - XDamageNotifyEvent* notify; - - client = (freerdp_peer*) param; - xfp = (xfPeerContext*) client->context; - xfi = xfp->info; - - fds = xfi->xfds; - wait_interval = 1000000 / xfp->fps; - ZeroMemory(&timeout, sizeof(struct timeval)); - - pthread_create(&(xfp->frame_rate_thread), 0, xf_frame_rate_thread, (void*) client); - - while (1) + if (xfi->use_xshm) { - /* check if we should terminate */ - pthread_testcancel(); + /** + * Passing an offset source rectangle to rfx_compose_message() + * leads to protocol errors, so offset the data pointer instead. + */ - FD_ZERO(&rfds_set); - FD_SET(fds, &rfds_set); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; - timeout.tv_sec = 0; - timeout.tv_usec = wait_interval; - select_status = select(fds + 1, &rfds_set, NULL, NULL, &timeout); + image = xf_snapshot(xfp, x, y, width, height); - if (select_status == -1) - { - fprintf(stderr, "select failed\n"); - } - else if (select_status == 0) - { + data = (BYTE*) image->data; + data = &data[(y * image->bytes_per_line) + (x * image->bits_per_pixel / 8)]; - } + rfx_compose_message(xfp->rfx_context, s, &rect, 1, data, + width, height, image->bytes_per_line); - while (XPending(xfi->display) > 0) - { - ZeroMemory(&xevent, sizeof(xevent)); - XNextEvent(xfi->display, &xevent); + cmd->destLeft = x; + cmd->destTop = y; + cmd->destRight = x + width; + cmd->destBottom = y + height; + } + else + { + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; - if (xevent.type == xfi->xdamage_notify_event) - { - notify = (XDamageNotifyEvent*) &xevent; + image = xf_snapshot(xfp, x, y, width, height); - x = notify->area.x; - y = notify->area.y; - width = notify->area.width; - height = notify->area.height; + data = (BYTE*) image->data; - pthread_mutex_lock(&(xfp->mutex)); - gdi_InvalidateRegion(xfp->hdc, x, y, width, height); - pthread_mutex_unlock(&(xfp->mutex)); + rfx_compose_message(xfp->rfx_context, s, &rect, 1, data, + width, height, image->bytes_per_line); - xf_xdamage_subtract_region(xfp, x, y, width, height); - } - } + cmd->destLeft = x; + cmd->destTop = y; + cmd->destRight = x + width; + cmd->destBottom = y + height; + + XDestroyImage(image); } - return NULL; + cmd->bpp = 32; + cmd->codecID = client->settings->RemoteFxCodecId; + cmd->width = width; + cmd->height = height; + cmd->bitmapDataLength = Stream_GetPosition(s); + cmd->bitmapData = Stream_Buffer(s); + + return 0; } diff --git a/server/X11/xf_encode.h b/server/X11/xf_encode.h index f84b3f48e..fb7d98562 100644 --- a/server/X11/xf_encode.h +++ b/server/X11/xf_encode.h @@ -20,13 +20,12 @@ #ifndef __XF_ENCODE_H #define __XF_ENCODE_H -#include <pthread.h> #include "xfreerdp.h" #include "xf_peer.h" XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height); void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height); -void* xf_monitor_updates(void* param); +int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height); #endif /* __XF_ENCODE_H */ diff --git a/server/X11/xf_input.c b/server/X11/xf_input.c index feac6ebf5..14d55fca7 100644 --- a/server/X11/xf_input.c +++ b/server/X11/xf_input.c @@ -25,6 +25,9 @@ #include <freerdp/locale/keyboard.h> +#include <winpr/crt.h> +#include <winpr/input.h> + #include "xf_peer.h" #include "xf_input.h" @@ -37,7 +40,8 @@ void xf_input_synchronize_event(rdpInput* input, UINT32 flags) void xf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { #ifdef WITH_XTEST - unsigned int keycode; + DWORD vkcode; + DWORD keycode; BOOL extended = FALSE; xfPeerContext* xfp = (xfPeerContext*) input->context; xfInfo* xfi = xfp->info; @@ -45,7 +49,11 @@ void xf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) if (flags & KBD_FLAGS_EXTENDED) extended = TRUE; - keycode = freerdp_keyboard_get_x11_keycode_from_rdp_scancode(code, extended); + if (extended) + code |= KBDEXT; + + vkcode = GetVirtualKeyCodeFromVirtualScanCode(code, 4); + keycode = GetKeycodeFromVirtualKeyCode(vkcode, KEYCODE_TYPE_EVDEV); if (keycode != 0) { diff --git a/server/X11/xfreerdp.c b/server/X11/xf_interface.c similarity index 56% rename from server/X11/xfreerdp.c rename to server/X11/xf_interface.c index 62bd98901..1c93b5e4e 100644 --- a/server/X11/xfreerdp.c +++ b/server/X11/xf_interface.c @@ -1,8 +1,8 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP X11 Server + * FreeRDP X11 Server Interface * - * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,6 @@ * limitations under the License. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -33,10 +29,9 @@ #include "xf_peer.h" #include "xfreerdp.h" -char* xf_pcap_file = NULL; -BOOL xf_pcap_dump_realtime = TRUE; +#include "xf_interface.h" -void xf_server_main_loop(freerdp_listener* instance) +void* xf_server_thread(void* param) { int i; int fds; @@ -44,14 +39,19 @@ void xf_server_main_loop(freerdp_listener* instance) int rcount; void* rfds[32]; fd_set rfds_set; + xfServer* server; + freerdp_listener* listener; ZeroMemory(rfds, sizeof(rfds)); + server = (xfServer*) param; + listener = server->listener; + while (1) { rcount = 0; - if (instance->GetFileDescriptor(instance, rfds, &rcount) != TRUE) + if (listener->GetFileDescriptor(listener, rfds, &rcount) != TRUE) { fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); break; @@ -86,41 +86,73 @@ void xf_server_main_loop(freerdp_listener* instance) } } - if (instance->CheckFileDescriptor(instance) != TRUE) + if (listener->CheckFileDescriptor(listener) != TRUE) { fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); break; } } - instance->Close(instance); + listener->Close(listener); + + return NULL; } -int main(int argc, char* argv[]) +int freerdp_server_global_init() { - freerdp_listener* instance; - - /* ignore SIGPIPE, otherwise an SSL_write failure could crash the server */ + /* + * ignore SIGPIPE, otherwise an SSL_write failure could crash the server + */ signal(SIGPIPE, SIG_IGN); - instance = freerdp_listener_new(); - instance->PeerAccepted = xf_peer_accepted; - - if (argc > 1) - xf_pcap_file = argv[1]; - - if (argc > 2 && !strcmp(argv[2], "--fast")) - xf_pcap_dump_realtime = FALSE; - - /* Open the server socket and start listening. */ - if (instance->Open(instance, NULL, 3389)) - { - /* Entering the server main loop. In a real server the listener can be run in its own thread. */ - xf_server_main_loop(instance); - } - - freerdp_listener_free(instance); - return 0; } +int freerdp_server_global_uninit() +{ + return 0; +} + +int freerdp_server_start(xfServer* server) +{ + if (server->listener->Open(server->listener, NULL, 3389)) + { + server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_server_thread, (void*) server, 0, NULL); + } + + return 0; +} + +int freerdp_server_stop(xfServer* server) +{ + return 0; +} + +HANDLE freerdp_server_get_thread(xfServer* server) +{ + return server->thread; +} + +xfServer* freerdp_server_new(int argc, char** argv) +{ + xfServer* server; + + server = (xfServer*) malloc(sizeof(xfServer)); + + if (server) + { + server->listener = freerdp_listener_new(); + server->listener->PeerAccepted = xf_peer_accepted; + } + + return server; +} + +void freerdp_server_free(xfServer* server) +{ + if (server) + { + freerdp_listener_free(server->listener); + free(server); + } +} diff --git a/server/X11/xf_interface.h b/server/X11/xf_interface.h new file mode 100644 index 000000000..f62d36450 --- /dev/null +++ b/server/X11/xf_interface.h @@ -0,0 +1,54 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP X11 Server Interface + * + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef XFREERDP_SERVER_INTERFACE_H +#define XFREERDP_SERVER_INTERFACE_H + +#include <winpr/crt.h> + +#include <freerdp/api.h> +#include <freerdp/freerdp.h> + +typedef struct xf_info xfInfo; +typedef struct xf_server xfServer; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Server Interface + */ + +FREERDP_API int freerdp_server_global_init(); +FREERDP_API int freerdp_server_global_uninit(); + +FREERDP_API int freerdp_server_start(xfServer* server); +FREERDP_API int freerdp_server_stop(xfServer* server); + +FREERDP_API HANDLE freerdp_server_get_thread(xfServer* server); + +FREERDP_API xfServer* freerdp_server_new(int argc, char** argv); +FREERDP_API void freerdp_server_free(xfServer* server); + +#ifdef __cplusplus +} +#endif + +#endif /* XFREERDP_SERVER_INTERFACE_H */ diff --git a/server/X11/xf_monitors.c b/server/X11/xf_monitors.c new file mode 100644 index 000000000..2bf5d51f1 --- /dev/null +++ b/server/X11/xf_monitors.c @@ -0,0 +1,68 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * X11 Server Monitors + * + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <winpr/crt.h> + +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#ifdef WITH_XINERAMA +#include <X11/extensions/Xinerama.h> +#endif + +#include "xf_monitors.h" + +int xf_list_monitors(xfInfo* xfi) +{ +#ifdef WITH_XINERAMAZ + int i, nmonitors = 0; + int ignored, ignored2; + XineramaScreenInfo* screen = NULL; + + if (XineramaQueryExtension(xfi->display, &ignored, &ignored2)) + { + if (XineramaIsActive(xfi->display)) + { + screen = XineramaQueryScreens(xfi->display, &nmonitors); + + for (i = 0; i < nmonitors; i++) + { + printf(" %s [%d] %dx%d\t+%d+%d\n", + (i == 0) ? "*" : " ", i, + screen[i].width, screen[i].height, + screen[i].x_org, screen[i].y_org); + } + + XFree(screen); + } + } +#else + Screen* screen; + + screen = ScreenOfDisplay(xfi->display, DefaultScreen(xfi->display)); + printf(" * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen), HeightOfScreen(screen), 0, 0); +#endif + + return 0; +} + diff --git a/client/Mac/MRDPRailWindow.m b/server/X11/xf_monitors.h similarity index 70% rename from client/Mac/MRDPRailWindow.m rename to server/X11/xf_monitors.h index f714d610e..8487c3327 100644 --- a/client/Mac/MRDPRailWindow.m +++ b/server/X11/xf_monitors.h @@ -1,8 +1,8 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * MacFreeRDP + * X11 Server Monitors * - * Copyright 2012 Thomas Goddard + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,12 @@ * limitations under the License. */ -#import "MRDPRailWindow.h" +#ifndef XFREERDP_SERVER_MONITORS_H +#define XFREERDP_SERVER_MONITORS_H -@implementation MRDPRailWindow +#include "xfreerdp.h" -- (BOOL) canBecomeKeyWindow -{ - return YES; -} +int xf_list_monitors(xfInfo* xfi); + +#endif /* XFREERDP_SERVER_MONITORS_H */ -@end diff --git a/server/X11/xf_peer.c b/server/X11/xf_peer.c index 7a4baddd3..28316c87e 100644 --- a/server/X11/xf_peer.c +++ b/server/X11/xf_peer.c @@ -36,13 +36,19 @@ #include <winpr/file.h> #include <winpr/path.h> #include <winpr/synch.h> +#include <winpr/thread.h> #include <freerdp/freerdp.h> #include <freerdp/codec/color.h> #include <freerdp/locale/keyboard.h> #include "xf_input.h" +#include "xf_cursor.h" #include "xf_encode.h" +#include "xf_update.h" +#include "xf_monitors.h" + +#include "makecert.h" #include "xf_peer.h" @@ -50,31 +56,11 @@ void xf_xdamage_init(xfInfo* xfi) { - Bool pixmaps; int damage_event; int damage_error; int major, minor; XGCValues values; - if (xfi->use_xshm) - { - if (XShmQueryExtension(xfi->display) != False) - { - XShmQueryVersion(xfi->display, &major, &minor, &pixmaps); - - if (pixmaps != True) - { - fprintf(stderr, "XShmQueryVersion failed\n"); - return; - } - } - else - { - fprintf(stderr, "XShmQueryExtension failed\n"); - return; - } - } - if (XDamageQueryExtension(xfi->display, &damage_event, &damage_error) == 0) { fprintf(stderr, "XDamageQueryExtension failed\n"); @@ -122,8 +108,27 @@ void xf_xdamage_init(xfInfo* xfi) #endif -void xf_xshm_init(xfInfo* xfi) +int xf_xshm_init(xfInfo* xfi) { + Bool pixmaps; + int major, minor; + + if (XShmQueryExtension(xfi->display) != False) + { + XShmQueryVersion(xfi->display, &major, &minor, &pixmaps); + + if (pixmaps != True) + { + fprintf(stderr, "XShmQueryVersion failed\n"); + return -1; + } + } + else + { + fprintf(stderr, "XShmQueryExtension failed\n"); + return -1; + } + xfi->fb_shm_info.shmid = -1; xfi->fb_shm_info.shmaddr = (char*) -1; @@ -133,7 +138,7 @@ void xf_xshm_init(xfInfo* xfi) if (!xfi->fb_image) { fprintf(stderr, "XShmCreateImage failed\n"); - return; + return -1; } xfi->fb_shm_info.shmid = shmget(IPC_PRIVATE, @@ -142,7 +147,7 @@ void xf_xshm_init(xfInfo* xfi) if (xfi->fb_shm_info.shmid == -1) { fprintf(stderr, "shmget failed\n"); - return; + return -1; } xfi->fb_shm_info.readOnly = False; @@ -152,7 +157,7 @@ void xf_xshm_init(xfInfo* xfi) if (xfi->fb_shm_info.shmaddr == ((char*) -1)) { fprintf(stderr, "shmat failed\n"); - return; + return -1; } XShmAttach(xfi->display, &(xfi->fb_shm_info)); @@ -166,6 +171,8 @@ void xf_xshm_init(xfInfo* xfi) xfi->fb_pixmap = XShmCreatePixmap(xfi->display, xfi->root_window, xfi->fb_image->data, &(xfi->fb_shm_info), xfi->fb_image->width, xfi->fb_image->height, xfi->fb_image->depth); + + return 0; } xfInfo* xf_info_init() @@ -188,7 +195,9 @@ xfInfo* xf_info_init() * To see if your X11 server supports shared pixmaps, use: * xdpyinfo -ext MIT-SHM | grep "shared pixmaps" */ - xfi->use_xshm = FALSE; + xfi->use_xshm = TRUE; + + setenv("DISPLAY", ":0", 1); /* Set DISPLAY variable if not already set */ if (!XInitThreads()) fprintf(stderr, "warning: XInitThreads() failure\n"); @@ -201,6 +210,8 @@ xfInfo* xf_info_init() exit(1); } + xf_list_monitors(xfi); + xfi->xfds = ConnectionNumber(xfi->display); xfi->number = DefaultScreen(xfi->display); xfi->screen = ScreenOfDisplay(xfi->display, xfi->number); @@ -236,7 +247,7 @@ xfInfo* xf_info_init() vis = XGetVisualInfo(xfi->display, VisualClassMask | VisualScreenMask, &template, &vi_count); - if (vis == NULL) + if (!vis) { fprintf(stderr, "XGetVisualInfo failed\n"); exit(1); @@ -258,14 +269,23 @@ xfInfo* xf_info_init() XSelectInput(xfi->display, xfi->root_window, SubstructureNotifyMask); + if (xfi->use_xshm) + { + if (xf_xshm_init(xfi) < 0) + xfi->use_xshm = FALSE; + } + + if (xfi->use_xshm) + printf("Using X Shared Memory Extension (XShm)\n"); + #ifdef WITH_XDAMAGE xf_xdamage_init(xfi); #endif - if (xfi->use_xshm) - xf_xshm_init(xfi); + xf_cursor_init(xfi); xfi->bytesPerPixel = 4; + xfi->activePeerCount = 0; freerdp_keyboard_init(0); @@ -282,14 +302,18 @@ void xf_peer_context_new(freerdp_peer* client, xfPeerContext* context) rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); - context->s = stream_new(65536); + context->s = Stream_New(NULL, 65536); + Stream_Clear(context->s); + + context->updateReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + context->updateSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL); } void xf_peer_context_free(freerdp_peer* client, xfPeerContext* context) { if (context) { - stream_free(context->s); + Stream_Free(context->s, TRUE); rfx_context_free(context->rfx_context); } } @@ -307,106 +331,21 @@ void xf_peer_init(freerdp_peer* client) xfp = (xfPeerContext*) client->context; xfp->fps = 16; - xfp->thread = 0; - xfp->activations = 0; - - xfp->queue = MessageQueue_New(); - xfi = xfp->info; - xfp->hdc = gdi_CreateDC(xfi->clrconv, xfi->bpp); - pthread_mutex_init(&(xfp->mutex), NULL); + xfp->mutex = CreateMutex(NULL, FALSE, NULL); } -wStream* xf_peer_stream_init(xfPeerContext* context) +void xf_peer_send_update(freerdp_peer* client) { - stream_clear(context->s); - stream_set_pos(context->s, 0); - return context->s; -} - -void xf_peer_live_rfx(freerdp_peer* client) -{ - xfPeerContext* xfp = (xfPeerContext*) client->context; - pthread_create(&(xfp->thread), 0, xf_monitor_updates, (void*) client); -} - -void xf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int height) -{ - wStream* s; - BYTE* data; - xfInfo* xfi; - RFX_RECT rect; - XImage* image; rdpUpdate* update; - xfPeerContext* xfp; SURFACE_BITS_COMMAND* cmd; update = client->update; - xfp = (xfPeerContext*) client->context; cmd = &update->surface_bits_command; - xfi = xfp->info; - if (width * height <= 0) - return; - - s = xf_peer_stream_init(xfp); - - if (xfi->use_xshm) - { - /** - * Passing an offset source rectangle to rfx_compose_message() - * leads to protocol errors, so offset the data pointer instead. - */ - - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - - image = xf_snapshot(xfp, x, y, width, height); - - data = (BYTE*) image->data; - data = &data[(y * image->bytes_per_line) + (x * image->bits_per_pixel / 8)]; - - rfx_compose_message(xfp->rfx_context, s, &rect, 1, data, - width, height, image->bytes_per_line); - - cmd->destLeft = x; - cmd->destTop = y; - cmd->destRight = x + width; - cmd->destBottom = y + height; - } - else - { - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - - image = xf_snapshot(xfp, x, y, width, height); - - data = (BYTE*) image->data; - - rfx_compose_message(xfp->rfx_context, s, &rect, 1, data, - width, height, image->bytes_per_line); - - cmd->destLeft = x; - cmd->destTop = y; - cmd->destRight = x + width; - cmd->destBottom = y + height; - - XDestroyImage(image); - } - - cmd->bpp = 32; - cmd->codecID = client->settings->RemoteFxCodecId; - cmd->width = width; - cmd->height = height; - cmd->bitmapDataLength = stream_get_length(s); - cmd->bitmapData = stream_get_head(s); - - update->SurfaceBits(update->context, cmd); + if (cmd->bitmapDataLength) + update->SurfaceBits(update->context, cmd); } BOOL xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount) @@ -415,7 +354,7 @@ BOOL xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount) HANDLE event; xfPeerContext* xfp = (xfPeerContext*) client->context; - event = MessageQueue_Event(xfp->queue); + event = xfp->updateReadyEvent; fds = GetEventFileDescriptor(event); rfds[*rcount] = (void*) (long) fds; (*rcount)++; @@ -426,34 +365,20 @@ BOOL xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount) BOOL xf_peer_check_fds(freerdp_peer* client) { xfInfo* xfi; - wMessage message; xfPeerContext* xfp; xfp = (xfPeerContext*) client->context; xfi = xfp->info; - if (xfp->activated == FALSE) - return TRUE; - - if (MessageQueue_Peek(xfp->queue, &message, TRUE)) + if (WaitForSingleObject(xfp->updateReadyEvent, 0) == WAIT_OBJECT_0) { - if (message.id == MakeMessageId(PeerEvent, EncodeRegion)) - { - UINT32 xy, wh; - UINT16 x, y, w, h; + if (!xfp->activated) + return TRUE; - xy = (UINT32) (size_t) message.wParam; - wh = (UINT32) (size_t) message.lParam; + xf_peer_send_update(client); - x = ((xy & 0xFFFF0000) >> 16); - y = (xy & 0x0000FFFF); - - w = ((wh & 0xFFFF0000) >> 16); - h = (wh & 0x0000FFFF); - - if (w * h > 0) - xf_peer_rfx_update(client, x, y, w, h); - } + ResetEvent(xfp->updateReadyEvent); + SetEvent(xfp->updateSentEvent); } return TRUE; @@ -516,34 +441,28 @@ BOOL xf_peer_activate(freerdp_peer* client) rfx_context_reset(xfp->rfx_context); xfp->activated = TRUE; - xf_peer_live_rfx(client); + xfp->info->activePeerCount++; + + xfp->monitorThread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) xf_update_thread, (void*) client, 0, NULL); return TRUE; } -void* xf_peer_main_loop(void* arg) +const char* makecert_argv[4] = +{ + "makecert", + "-rdp", + "-live", + "-silent" +}; + +int makecert_argc = (sizeof(makecert_argv) / sizeof(char*)); + +int xf_generate_certificate(rdpSettings* settings) { - int i; - int fds; - int max_fds; - int rcount; - void* rfds[32]; - fd_set rfds_set; - rdpSettings* settings; char* server_file_path; - freerdp_peer* client = (freerdp_peer*) arg; - xfPeerContext* xfp; - - ZeroMemory(rfds, sizeof(rfds)); - - fprintf(stderr, "We've got a client %s\n", client->hostname); - - xf_peer_init(client); - xfp = (xfPeerContext*) client->context; - - settings = client->settings; - - /* Initialize the real server settings here */ + MAKECERT_CONTEXT* context; server_file_path = GetCombinedPath(settings->ConfigPath, "server"); @@ -553,6 +472,53 @@ void* xf_peer_main_loop(void* arg) settings->CertificateFile = GetCombinedPath(server_file_path, "server.crt"); settings->PrivateKeyFile = GetCombinedPath(server_file_path, "server.key"); + if ((!PathFileExistsA(settings->CertificateFile)) || + (!PathFileExistsA(settings->PrivateKeyFile))) + { + context = makecert_context_new(); + + makecert_context_process(context, makecert_argc, (char**) makecert_argv); + + makecert_context_set_output_file_name(context, "server"); + + if (!PathFileExistsA(settings->CertificateFile)) + makecert_context_output_certificate_file(context, server_file_path); + + if (!PathFileExistsA(settings->PrivateKeyFile)) + makecert_context_output_private_key_file(context, server_file_path); + + makecert_context_free(context); + } + + free(server_file_path); + + return 0; +} + +static void* xf_peer_main_loop(void* arg) +{ + int i; + int fds; + int max_fds; + int rcount; + void* rfds[32]; + fd_set rfds_set; + rdpSettings* settings; + xfPeerContext* xfp; + struct timeval timeout; + freerdp_peer* client = (freerdp_peer*) arg; + + ZeroMemory(rfds, sizeof(rfds)); + ZeroMemory(&timeout, sizeof(struct timeval)); + + fprintf(stderr, "We've got a client %s\n", client->hostname); + + xf_peer_init(client); + xfp = (xfPeerContext*) client->context; + settings = client->settings; + + xf_generate_certificate(settings); + settings->RemoteFxCodec = TRUE; settings->ColorDepth = 32; @@ -573,6 +539,7 @@ void* xf_peer_main_loop(void* arg) fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); break; } + if (xf_peer_get_fds(client, rfds, &rcount) != TRUE) { fprintf(stderr, "Failed to get xfreerdp file descriptor\n"); @@ -595,7 +562,10 @@ void* xf_peer_main_loop(void* arg) if (max_fds == 0) break; - if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) + timeout.tv_sec = 0; + timeout.tv_usec = 100; + + if (select(max_fds + 1, &rfds_set, NULL, NULL, &timeout) == -1) { /* these are not really errors */ if (!((errno == EAGAIN) || @@ -613,6 +583,7 @@ void* xf_peer_main_loop(void* arg) fprintf(stderr, "Failed to check freerdp file descriptor\n"); break; } + if ((xf_peer_check_fds(client)) != TRUE) { fprintf(stderr, "Failed to check xfreerdp file descriptor\n"); @@ -624,12 +595,6 @@ void* xf_peer_main_loop(void* arg) client->Disconnect(client); - pthread_cancel(xfp->thread); - pthread_cancel(xfp->frame_rate_thread); - - pthread_join(xfp->thread, NULL); - pthread_join(xfp->frame_rate_thread, NULL); - freerdp_peer_context_free(client); freerdp_peer_free(client); @@ -638,8 +603,7 @@ void* xf_peer_main_loop(void* arg) void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client) { - pthread_t th; + HANDLE thread; - pthread_create(&th, 0, xf_peer_main_loop, client); - pthread_detach(th); + thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_peer_main_loop, client, 0, NULL); } diff --git a/server/X11/xf_peer.h b/server/X11/xf_peer.h index 53135baa2..e6febd68d 100644 --- a/server/X11/xf_peer.h +++ b/server/X11/xf_peer.h @@ -21,6 +21,8 @@ #define __XF_PEER_H #include <winpr/crt.h> +#include <winpr/synch.h> +#include <winpr/thread.h> #include <winpr/stream.h> #include <winpr/collections.h> @@ -47,16 +49,13 @@ struct xf_peer_context int fps; wStream* s; - HGDI_DC hdc; xfInfo* info; - int activations; - pthread_t thread; + HANDLE mutex; BOOL activated; - pthread_mutex_t mutex; + HANDLE monitorThread; + HANDLE updateReadyEvent; + HANDLE updateSentEvent; RFX_CONTEXT* rfx_context; - pthread_t frame_rate_thread; - - wMessageQueue* queue; }; void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); diff --git a/server/X11/xf_update.c b/server/X11/xf_update.c new file mode 100644 index 000000000..33dd426b3 --- /dev/null +++ b/server/X11/xf_update.c @@ -0,0 +1,99 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * X11 Server Graphical Updates + * + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <X11/Xlib.h> + +#include <winpr/crt.h> +#include <winpr/synch.h> +#include <winpr/sysinfo.h> + +#include "xf_peer.h" +#include "xf_encode.h" + +#include "xf_update.h" + +void* xf_update_thread(void* param) +{ + xfInfo* xfi; + HANDLE event; + XEvent xevent; + DWORD beg, end; + DWORD diff, rate; + xfPeerContext* xfp; + freerdp_peer* client; + int x, y, width, height; + XDamageNotifyEvent* notify; + + client = (freerdp_peer*) param; + xfp = (xfPeerContext*) client->context; + xfi = xfp->info; + + rate = 1000 / xfp->fps; + + event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfi->xfds); + + while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0) + { + beg = GetTickCount(); + + while (XPending(xfi->display) > 0) + { + ZeroMemory(&xevent, sizeof(xevent)); + XNextEvent(xfi->display, &xevent); + + if (xevent.type == xfi->xdamage_notify_event) + { + notify = (XDamageNotifyEvent*) &xevent; + + x = notify->area.x; + y = notify->area.y; + width = notify->area.width; + height = notify->area.height; + + if (xf_update_encode(client, x, y, width, height) >= 0) + { + xf_xdamage_subtract_region(xfp, x, y, width, height); + + SetEvent(xfp->updateReadyEvent); + + WaitForSingleObject(xfp->updateSentEvent, INFINITE); + ResetEvent(xfp->updateSentEvent); + } + } + else if (xevent.type == xfi->xfixes_notify_event) + { + XFixesCursorImage* ci = XFixesGetCursorImage(xfi->display); + + XFree(ci); + } + } + + end = GetTickCount(); + diff = end - beg; + + if (diff < rate) + Sleep(rate - diff); + } + + return NULL; +} diff --git a/client/X11/cli/xfreerdp.h b/server/X11/xf_update.h similarity index 73% rename from client/X11/cli/xfreerdp.h rename to server/X11/xf_update.h index c8e4780a6..9e3c27342 100644 --- a/client/X11/cli/xfreerdp.h +++ b/server/X11/xf_update.h @@ -1,8 +1,8 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Client + * X11 Server Graphical Updates * - * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,12 @@ * limitations under the License. */ -#ifndef __XFREERDP_H -#define __XFREERDP_H +#ifndef __XF_UPDATE_H +#define __XF_UPDATE_H +#include "xfreerdp.h" +void* xf_update_thread(void* param); + +#endif /* __XF_UPDATE_H */ -#endif /* __XFREERDP_H */ diff --git a/server/X11/xfreerdp.h b/server/X11/xfreerdp.h index d2d4a8f41..db6231893 100644 --- a/server/X11/xfreerdp.h +++ b/server/X11/xfreerdp.h @@ -20,8 +20,15 @@ #ifndef __XFREERDP_H #define __XFREERDP_H +#include "xf_interface.h" + +#include <freerdp/api.h> +#include <freerdp/freerdp.h> +#include <freerdp/listener.h> #include <freerdp/codec/color.h> +#include <X11/Xlib.h> + #ifdef WITH_XSHM #include <X11/extensions/XShm.h> #endif @@ -38,8 +45,6 @@ #include <X11/extensions/Xdamage.h> #endif -typedef struct xf_info xfInfo; - struct xf_info { int bpp; @@ -56,6 +61,7 @@ struct xf_info int bytesPerPixel; HCLRCONV clrconv; BOOL use_xshm; + int activePeerCount; XImage* fb_image; Pixmap fb_pixmap; @@ -68,6 +74,19 @@ struct xf_info int xdamage_notify_event; XserverRegion xdamage_region; #endif + +#ifdef WITH_XFIXES + int xfixes_notify_event; +#endif }; +struct xf_server +{ + DWORD port; + HANDLE thread; + freerdp_listener* listener; +}; + +void* xf_server_thread(void* param); + #endif /* __XFREERDP_H */ diff --git a/winpr/include/winpr/asn1.h b/winpr/include/winpr/asn1.h index 69f95e550..6c2e46e6c 100644 --- a/winpr/include/winpr/asn1.h +++ b/winpr/include/winpr/asn1.h @@ -23,6 +23,10 @@ #include <winpr/winpr.h> #include <winpr/wtypes.h> +#ifdef __cplusplus +extern "C" { +#endif + typedef unsigned char ASN1uint8_t; typedef signed char ASN1int8_t; @@ -304,6 +308,7 @@ enum ASN1DECODE_NOASSERT = ASN1FLAGS_NOASSERT, }; + WINPR_API ASN1module_t ASN1_CreateModule(ASN1uint32_t nVersion, ASN1encodingrule_e eRule, ASN1uint32_t dwFlags, ASN1uint32_t cPDU, const ASN1GenericFun_t apfnEncoder[], const ASN1GenericFun_t apfnDecoder[], const ASN1FreeFun_t apfnFreeMemory[], @@ -501,5 +506,9 @@ WINPR_API int ASN1DEREncNewBlkElement(void* pBlk, ASN1encoding_t* enc2); WINPR_API int ASN1DEREncFlushBlkElement(void* pBlk); WINPR_API int ASN1DEREncEndBlk(void* pBlk); +#ifdef __cplusplus +} +#endif + #endif /* WINPR_ASN1_H */ diff --git a/winpr/include/winpr/bcrypt.h b/winpr/include/winpr/bcrypt.h index d9e4f1d33..cf9a784eb 100644 --- a/winpr/include/winpr/bcrypt.h +++ b/winpr/include/winpr/bcrypt.h @@ -83,6 +83,10 @@ typedef PVOID BCRYPT_SECRET_HANDLE; #define BCRYPT_PRIMITIVE_TYPE L"PrimitiveType" #define BCRYPT_IS_KEYED_HASH L"IsKeyedHash" +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API NTSTATUS BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE* phAlgorithm, LPCWSTR pszAlgId, LPCWSTR pszImplementation, ULONG dwFlags); @@ -122,4 +126,7 @@ WINPR_API NTSTATUS BCryptDecrypt(BCRYPT_KEY_HANDLE hKey, PUCHAR pbInput, ULONG c VOID* pPaddingInfo, PUCHAR pbIV, ULONG cbIV, PUCHAR pbOutput, ULONG cbOutput, ULONG* pcbResult, ULONG dwFlags); +#ifdef __cplusplus +} +#endif #endif /* WINPR_BCRYPT_MEMORY_H */ diff --git a/winpr/include/winpr/cmdline.h b/winpr/include/winpr/cmdline.h index 6a3b8c6b8..bc67d4f52 100644 --- a/winpr/include/winpr/cmdline.h +++ b/winpr/include/winpr/cmdline.h @@ -123,6 +123,10 @@ typedef int (*COMMAND_LINE_PRE_FILTER_FN_W)(void* context, int index, int argc, typedef int (*COMMAND_LINE_POST_FILTER_FN_A)(void* context, COMMAND_LINE_ARGUMENT_A* arg); typedef int (*COMMAND_LINE_POST_FILTER_FN_W)(void* context, COMMAND_LINE_ARGUMENT_W* arg); +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API int CommandLineClearArgumentsA(COMMAND_LINE_ARGUMENT_A* options); WINPR_API int CommandLineClearArgumentsW(COMMAND_LINE_ARGUMENT_W* options); @@ -136,6 +140,10 @@ WINPR_API COMMAND_LINE_ARGUMENT_W* CommandLineFindArgumentW(COMMAND_LINE_ARGUMEN WINPR_API COMMAND_LINE_ARGUMENT_A* CommandLineFindNextArgumentA(COMMAND_LINE_ARGUMENT_A* argument); +#ifdef __cplusplus +} +#endif + #ifdef UNICODE #define CommandLineClearArguments CommandLineClearArgumentsW #define CommandLineParseArguments CommandLineParseArgumentsW diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 32b412529..a8ed0765e 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -28,6 +28,11 @@ #include <winpr/wtypes.h> #include <winpr/synch.h> +#include <winpr/stream.h> + +#ifdef __cplusplus +extern "C" { +#endif typedef void* (*OBJECT_NEW_FN)(void); typedef void (*OBJECT_FREE_FN)(void* obj); @@ -334,4 +339,7 @@ WINPR_API void MessagePipe_PostQuit(wMessagePipe* pipe, int nExitCode); WINPR_API wMessagePipe* MessagePipe_New(void); WINPR_API void MessagePipe_Free(wMessagePipe* pipe); +#ifdef __cplusplus +} +#endif #endif /* WINPR_COLLECTIONS_H */ diff --git a/winpr/include/winpr/credentials.h b/winpr/include/winpr/credentials.h index a5f4f0d82..f3764cd0f 100644 --- a/winpr/include/winpr/credentials.h +++ b/winpr/include/winpr/credentials.h @@ -167,6 +167,10 @@ typedef enum _CRED_PROTECTION_TYPE #define PCREDENTIAL_TARGET_INFORMATION PCREDENTIAL_TARGET_INFORMATIONA #endif +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API BOOL CredWriteW(PCREDENTIALW Credential, DWORD Flags); WINPR_API BOOL CredWriteA(PCREDENTIALA Credential, DWORD Flags); @@ -220,6 +224,10 @@ WINPR_API BOOL CredGetSessionTypes(DWORD MaximumPersistCount, LPDWORD MaximumPer WINPR_API VOID CredFree(PVOID Buffer); +#ifdef __cplusplus +} +#endif + #ifdef UNICODE #define CredWrite CredWriteW #define CredRead CredReadW diff --git a/winpr/include/winpr/credui.h b/winpr/include/winpr/credui.h index abefd1e78..3fac9f77b 100644 --- a/winpr/include/winpr/credui.h +++ b/winpr/include/winpr/credui.h @@ -96,6 +96,10 @@ typedef struct _CREDUI_INFOW #define PCREDUI_INFO PCREDUI_INFOA #endif +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API DWORD CredUIPromptForCredentialsW(PCREDUI_INFOW pUiInfo, PCWSTR pszTargetName, PCtxtHandle pContext, DWORD dwAuthError, PWSTR pszUserName, ULONG ulUserNameBufferSize, PWSTR pszPassword, ULONG ulPasswordBufferSize, BOOL* save, DWORD dwFlags); @@ -122,6 +126,10 @@ WINPR_API DWORD CredUIStoreSSOCredA(PCSTR pszRealm, PCSTR pszUsername, PCSTR psz WINPR_API DWORD CredUIReadSSOCredW(PCWSTR pszRealm, PWSTR* ppszUsername); WINPR_API DWORD CredUIReadSSOCredA(PCSTR pszRealm, PSTR* ppszUsername); +#ifdef __cplusplus +} +#endif + #ifdef UNICODE #define CredUIPromptForCredentials CredUIPromptForCredentialsW #define CredUIParseUserName CredUIParseUserNameW diff --git a/winpr/include/winpr/crt.h b/winpr/include/winpr/crt.h index ed5e56a9a..70ea058e5 100644 --- a/winpr/include/winpr/crt.h +++ b/winpr/include/winpr/crt.h @@ -44,6 +44,10 @@ typedef int errno_t; #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A) #define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A) +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API void* _aligned_malloc(size_t size, size_t alignment); WINPR_API void* _aligned_realloc(void* memblock, size_t size, size_t alignment); WINPR_API void* _aligned_recalloc(void* memblock, size_t num, size_t size, size_t alignment); @@ -65,6 +69,11 @@ WINPR_API errno_t _itoa_s(int value, char* buffer, size_t sizeInCharacters, int WINPR_API errno_t memmove_s(void* dest, size_t numberOfElements, const void* src, size_t count); WINPR_API errno_t wmemmove_s(WCHAR* dest, size_t numberOfElements, const WCHAR* src, size_t count); +#ifdef __cplusplus +} +#endif + + #endif #endif /* WINPR_CRT_H */ diff --git a/winpr/include/winpr/crypto.h b/winpr/include/winpr/crypto.h index 56fd6d981..1ce92b2b9 100644 --- a/winpr/include/winpr/crypto.h +++ b/winpr/include/winpr/crypto.h @@ -365,6 +365,10 @@ WINPR_API BOOL CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags); #define CertOpenSystemStore CertOpenSystemStoreA #endif +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API PCCERT_CONTEXT CertFindCertificateInStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, const void* pvFindPara, PCCERT_CONTEXT pPrevCertContext); @@ -375,6 +379,10 @@ DWORD CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void* pvTypePara, LPSTR pszNameString, DWORD cchNameString); +#ifdef __cplusplus +} +#endif + #ifdef UNICODE #define CertGetNameString CertGetNameStringW #else diff --git a/winpr/include/winpr/dsparse.h b/winpr/include/winpr/dsparse.h index 013aadb2d..91455873a 100644 --- a/winpr/include/winpr/dsparse.h +++ b/winpr/include/winpr/dsparse.h @@ -93,6 +93,10 @@ typedef struct PDS_NAME_RESULT_ITEM rItems; } DS_NAME_RESULT, *PDS_NAME_RESULT; +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API DWORD DsCrackSpnW(LPCWSTR pszSpn, DWORD* pcServiceClass, LPWSTR ServiceClass, DWORD* pcServiceName, LPWSTR ServiceName, DWORD* pcInstanceName, LPWSTR InstanceName, USHORT* pInstancePort); @@ -111,6 +115,10 @@ WINPR_API DWORD DsMakeSpnW(LPCWSTR ServiceClass, LPCWSTR ServiceName, LPCWSTR In WINPR_API DWORD DsMakeSpnA(LPCSTR ServiceClass, LPCSTR ServiceName, LPCSTR InstanceName, USHORT InstancePort, LPCSTR Referrer, DWORD* pcSpnLength, LPSTR pszSpn); +#ifdef __cplusplus +} +#endif + #ifdef UNICODE #define DsMakeSpn DsMakeSpnW #else diff --git a/winpr/include/winpr/endian.h b/winpr/include/winpr/endian.h new file mode 100644 index 000000000..9d9834076 --- /dev/null +++ b/winpr/include/winpr/endian.h @@ -0,0 +1,133 @@ +/* + * WinPR: Windows Portable Runtime + * Endianness Macros + * + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_ENDIAN_H +#define WINPR_ENDIAN_H + +#include <winpr/winpr.h> +#include <winpr/wtypes.h> +#include <winpr/platform.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define Data_Read_UINT8_NE(_d, _v) do { _v = \ + *_d; } while (0) + +#define Data_Read_UINT8(_d, _v) do { _v = \ + *_d; } while (0) + +#define Data_Read_UINT16_NE(_d, _v) do { _v = \ + *((UINT16*) _d); } while (0) + +#define Data_Read_UINT16(_d, _v) do { _v = \ + (UINT16)(*_d) + \ + (((UINT16)(*(_d))) << 8); \ + } while (0) + +#define Data_Read_UINT16_BE(_d, _v) do { _v = \ + (((UINT16)(*_d)) << 8) + \ + (UINT16)(*(_d + 1)); \ + } while (0) + +#define Data_Read_UINT32_NE(_d, _v) do { _v = \ + *((UINT32*) _d); } while (0) + +#define Data_Read_UINT32(_d, _v) do { _v = \ + (UINT32)(*_d) + \ + (((UINT32)(*(_d + 1))) << 8) + \ + (((UINT32)(*(_d + 2))) << 16) + \ + (((UINT32)(*(_d + 3))) << 24); \ + } while (0) + +#define Data_Read_UINT32_BE(_d, _v) do { _v = \ + (((UINT32)(*(_d))) << 24) + \ + (((UINT32)(*(_d + 1))) << 16) + \ + (((UINT32)(*(_d + 2))) << 8) + \ + (((UINT32)(*(_d + 3)))); \ + } while (0) + +#define Data_Read_UINT64_NE(_d, _v) do { _v = \ + *((UINT64*) _d); } while (0) + +#define Data_Read_UINT64(_d, _v) do { _v = \ + (UINT64)(*_d) + \ + (((UINT64)(*(_d + 1))) << 8) + \ + (((UINT64)(*(_d + 2))) << 16) + \ + (((UINT64)(*(_d + 3))) << 24) + \ + (((UINT64)(*(_d + 4))) << 32) + \ + (((UINT64)(*(_d + 5))) << 40) + \ + (((UINT64)(*(_d + 6))) << 48) + \ + (((UINT64)(*(_d + 7))) << 56); \ + } while (0) + +#define Data_Write_UINT8_NE(_d, _v) do { \ + *((UINT8*) _d) = v; } while (0) + +#define Data_Write_UINT8(_d, _v) do { \ + *_d = (UINT8)(_v); } while (0) + +#define Data_Write_UINT16_NE(_d, _v) do { \ + *((UINT16*) _d) = _v; } while (0) + +#define Data_Write_UINT16(_d, _v) do { \ + *(_d) = (_v) & 0xFF; \ + *(_d + 1) = ((_v) >> 8) & 0xFF; \ + } while (0) + +#define Data_Write_UINT16_BE(_d, _v) do { \ + *(_d) = ((_v) >> 8) & 0xFF; \ + *(_d + 1) = (_v) & 0xFF; \ + } while (0) + +#define Data_Write_UINT32_NE(_d, _v) do { \ + *((UINT32*) _d) = _v; } while (0) + +#define Data_Write_UINT32(_d, _v) do { \ + *(_d) = (_v) & 0xFF; \ + *(_d + 1) = ((_v) >> 8) & 0xFF; \ + *(_d + 2) = ((_v) >> 16) & 0xFF; \ + *(_d + 3) = ((_v) >> 24) & 0xFF; \ + } while (0) + +#define Data_Write_UINT32_BE(_d, _v) do { \ + Data_Write_UINT16_BE(_d, ((_v) >> 16 & 0xFFFF)); \ + Data_Write_UINT16_BE(_d + 2, ((_v) & 0xFFFF)); \ + } while (0) + +#define Data_Write_UINT64_NE(_d, _v) do { \ + *((UINT64*) _d) = _v; } while (0) + +#define Data_Write_UINT64(_d, _v) do { \ + *(_d) = (UINT64)(_v) & 0xFF; \ + *(_d + 1) = ((UINT64)(_v) >> 8) & 0xFF; \ + *(_d + 2) = ((UINT64)(_v) >> 16) & 0xFF; \ + *(_d + 3) = ((UINT64)(_v) >> 24) & 0xFF; \ + *(_d + 4) = ((UINT64)(_v) >> 32) & 0xFF; \ + *(_d + 5) = ((UINT64)(_v) >> 40) & 0xFF; \ + *(_d + 6) = ((UINT64)(_v) >> 48) & 0xFF; \ + *(_d + 7) = ((UINT64)(_v) >> 56) & 0xFF; \ + } while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* WINPR_ENDIAN_H */ diff --git a/winpr/include/winpr/environment.h b/winpr/include/winpr/environment.h index eab6a8891..b77ab71bf 100644 --- a/winpr/include/winpr/environment.h +++ b/winpr/include/winpr/environment.h @@ -25,6 +25,10 @@ #ifndef _WIN32 +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API DWORD GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer); WINPR_API DWORD GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer); @@ -62,6 +66,11 @@ WINPR_API DWORD ExpandEnvironmentStringsW(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSi WINPR_API BOOL FreeEnvironmentStringsA(LPCH lpszEnvironmentBlock); WINPR_API BOOL FreeEnvironmentStringsW(LPWCH lpszEnvironmentBlock); +#ifdef __cplusplus +} +#endif + + #ifdef UNICODE #define GetCurrentDirectory GetCurrentDirectoryW #define SetCurrentDirectory SetCurrentDirectoryW diff --git a/winpr/include/winpr/file.h b/winpr/include/winpr/file.h index efc190b23..b1dfe22f5 100644 --- a/winpr/include/winpr/file.h +++ b/winpr/include/winpr/file.h @@ -194,6 +194,10 @@ typedef VOID (*LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD dwErrorCode, DWORD dwNumbe #define LPWIN32_FIND_DATA LPWIN32_FIND_DATAA #endif +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); @@ -260,6 +264,10 @@ WINPR_API BOOL FindClose(HANDLE hFindFile); WINPR_API BOOL CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); WINPR_API BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); +#ifdef __cplusplus +} +#endif + #ifdef UNICODE #define CreateFile CreateFileW #define DeleteFile DeleteFileW @@ -287,8 +295,16 @@ WINPR_API BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecu #define WILDCARD_DOS_QM 0x00000120 #define WILDCARD_DOS_DOT 0x00000140 +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API BOOL FilePatternMatchA(LPCSTR lpFileName, LPCSTR lpPattern); WINPR_API LPSTR FilePatternFindNextWildcardA(LPCSTR lpPattern, DWORD* pFlags); +#ifdef __cplusplus +} +#endif + #endif /* WINPR_FILE_H */ diff --git a/winpr/include/winpr/handle.h b/winpr/include/winpr/handle.h index f479a4a63..c418427e8 100644 --- a/winpr/include/winpr/handle.h +++ b/winpr/include/winpr/handle.h @@ -27,21 +27,9 @@ #include <winpr/wtypes.h> #include <winpr/security.h> -#define HANDLE_TYPE_NONE 0 -#define HANDLE_TYPE_THREAD 1 -#define HANDLE_TYPE_EVENT 2 -#define HANDLE_TYPE_MUTEX 3 -#define HANDLE_TYPE_SEMAPHORE 4 -#define HANDLE_TYPE_TIMER 5 -#define HANDLE_TYPE_NAMED_PIPE 6 -#define HANDLE_TYPE_ANONYMOUS_PIPE 7 - -WINPR_API HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object); -WINPR_API BOOL winpr_Handle_Remove(HANDLE handle); - -WINPR_API ULONG winpr_Handle_GetType(HANDLE handle); -WINPR_API PVOID winpr_Handle_GetObject(HANDLE handle); -WINPR_API BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject); +#ifdef __cplusplus +extern "C" { +#endif #ifndef _WIN32 @@ -58,5 +46,9 @@ WINPR_API BOOL SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags) #endif +#ifdef __cplusplus +} +#endif + #endif /* WINPR_HANDLE_H */ diff --git a/winpr/include/winpr/heap.h b/winpr/include/winpr/heap.h index 2d5d256cd..30ab48ca9 100644 --- a/winpr/include/winpr/heap.h +++ b/winpr/include/winpr/heap.h @@ -33,11 +33,19 @@ #define HEAP_ZERO_MEMORY 0x00000008 #define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API HANDLE GetProcessHeap(void); WINPR_API LPVOID HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); WINPR_API LPVOID HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes); WINPR_API BOOL HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem); +#ifdef __cplusplus +} +#endif + #endif #endif /* WINPR_HEAP_H */ diff --git a/winpr/include/winpr/input.h b/winpr/include/winpr/input.h index 3c22ec6d2..6779f30fa 100644 --- a/winpr/include/winpr/input.h +++ b/winpr/include/winpr/input.h @@ -20,6 +20,7 @@ #ifndef WINPR_INPUT_H #define WINPR_INPUT_H + #include <winpr/winpr.h> #include <winpr/wtypes.h> @@ -854,6 +855,10 @@ #define APPLE_VK_DownArrow 0x7D #define APPLE_VK_UpArrow 0x7E +#ifdef __cplusplus +extern "C" { +#endif + /** * Functions */ @@ -869,5 +874,10 @@ WINPR_API DWORD GetVirtualScanCodeFromVirtualKeyCode(DWORD vkcode, DWORD dwKeybo #define KEYCODE_TYPE_EVDEV 0x00000002 WINPR_API DWORD GetVirtualKeyCodeFromKeycode(DWORD keycode, DWORD dwFlags); +WINPR_API DWORD GetKeycodeFromVirtualKeyCode(DWORD keycode, DWORD dwFlags); + +#ifdef __cplusplus +} +#endif #endif /* WINPR_INPUT_H */ diff --git a/winpr/include/winpr/interlocked.h b/winpr/include/winpr/interlocked.h index 0fea91a72..e96a2b62f 100644 --- a/winpr/include/winpr/interlocked.h +++ b/winpr/include/winpr/interlocked.h @@ -25,6 +25,10 @@ #include <winpr/wtypes.h> #include <winpr/platform.h> +#ifdef __cplusplus +extern "C" { +#endif + #ifndef _WIN32 /* workaround for SLIST_ENTRY conflict */ @@ -172,5 +176,9 @@ WINPR_API VOID AppendTailList(PLIST_ENTRY ListHead, PLIST_ENTRY ListToAppend); WINPR_API VOID PushEntryList(PSINGLE_LIST_ENTRY ListHead, PSINGLE_LIST_ENTRY Entry); WINPR_API PSINGLE_LIST_ENTRY PopEntryList(PSINGLE_LIST_ENTRY ListHead); +#ifdef __cplusplus +} +#endif + #endif /* WINPR_INTERLOCKED_H */ diff --git a/winpr/include/winpr/io.h b/winpr/include/winpr/io.h index 237f2674b..3f4365b85 100644 --- a/winpr/include/winpr/io.h +++ b/winpr/include/winpr/io.h @@ -49,6 +49,10 @@ typedef struct _OVERLAPPED_ENTRY DWORD dwNumberOfBytesTransferred; } OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY; +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API BOOL GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait); WINPR_API BOOL GetOverlappedResultEx(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, DWORD dwMilliseconds, BOOL bAlertable); @@ -72,6 +76,10 @@ WINPR_API BOOL CancelIoEx(HANDLE hFile, LPOVERLAPPED lpOverlapped); WINPR_API BOOL CancelSynchronousIo(HANDLE hThread); +#ifdef __cplusplus +} +#endif + #endif #endif /* WINPR_IO_H */ diff --git a/winpr/include/winpr/library.h b/winpr/include/winpr/library.h index b38cf2a6e..721d2b70e 100644 --- a/winpr/include/winpr/library.h +++ b/winpr/include/winpr/library.h @@ -32,6 +32,10 @@ typedef HANDLE DLL_DIRECTORY_COOKIE; #define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 #define LOAD_LIBRARY_SEARCH_USER_DIRS 0x00000400 +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API DLL_DIRECTORY_COOKIE AddDllDirectory(PCWSTR NewDirectory); WINPR_API BOOL RemoveDllDirectory(DLL_DIRECTORY_COOKIE Cookie); WINPR_API BOOL SetDefaultDllDirectories(DWORD DirectoryFlags); @@ -54,6 +58,10 @@ WINPR_API FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName); WINPR_API BOOL FreeLibrary(HMODULE hLibModule); +#ifdef __cplusplus +} +#endif + #endif #endif /* WINPR_LIBRARY_H */ diff --git a/winpr/include/winpr/midl.h b/winpr/include/winpr/midl.h index 0f87efe8d..a0daaa4da 100644 --- a/winpr/include/winpr/midl.h +++ b/winpr/include/winpr/midl.h @@ -22,6 +22,10 @@ #include <winpr/rpc.h> +#ifdef __cplusplus +extern "C" { +#endif + #ifndef _WIN32 WINPR_API void* MIDL_user_allocate(size_t cBytes); @@ -29,4 +33,8 @@ WINPR_API void MIDL_user_free(void* p); #endif +#ifdef __cplusplus +} +#endif + #endif /* WINPR_RPC_MIDL_H */ diff --git a/winpr/include/winpr/ndr.h b/winpr/include/winpr/ndr.h index adafd5467..12ab5c2e5 100644 --- a/winpr/include/winpr/ndr.h +++ b/winpr/include/winpr/ndr.h @@ -523,8 +523,16 @@ typedef void (*NDR_TYPE_MARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned typedef void (*NDR_TYPE_UNMARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); typedef void (*NDR_TYPE_FREE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...); +#ifdef __cplusplus +} +#endif + #endif #endif /* WINPR_RPC_NDR_H */ diff --git a/winpr/include/winpr/ntlm.h b/winpr/include/winpr/ntlm.h index d6514f92a..8b62ebdc8 100644 --- a/winpr/include/winpr/ntlm.h +++ b/winpr/include/winpr/ntlm.h @@ -26,6 +26,10 @@ #include <winpr/winpr.h> #include <winpr/wtypes.h> +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API BYTE* NTOWFv1W(LPWSTR Password, UINT32 PasswordLength, BYTE* NtHash); WINPR_API BYTE* NTOWFv1A(LPSTR Password, UINT32 PasswordLength, BYTE* NtHash); @@ -39,6 +43,10 @@ WINPR_API BYTE* NTOWFv2FromHashW(BYTE* NtHashV1, LPWSTR User, UINT32 UserLength, WINPR_API BYTE* NTOWFv2FromHashA(BYTE* NtHashV1, LPSTR User, UINT32 UserLength, LPSTR Domain, UINT32 DomainLength, BYTE* NtHash); +#ifdef __cplusplus +} +#endif + #ifdef UNICODE #define NTOWFv1 NTOWFv1W #define NTOWFv2 NTOWFv2W diff --git a/winpr/include/winpr/path.h b/winpr/include/winpr/path.h index d320ee17d..9c3ec4c01 100644 --- a/winpr/include/winpr/path.h +++ b/winpr/include/winpr/path.h @@ -33,6 +33,10 @@ #else +#ifdef __cplusplus +extern "C" { +#endif + #define PATHCCH_ALLOW_LONG_PATHS 0x00000001 /* Allow building of \\?\ paths if longer than MAX_PATH */ #define VOLUME_PREFIX _T("\\\\?\\Volume") @@ -111,6 +115,7 @@ WINPR_API HRESULT PathCchStripPrefixW(PWSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchRemoveFileSpecA(PSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchRemoveFileSpecW(PWSTR pszPath, size_t cchPath); + #ifdef UNICODE #define PathCchAddBackslash PathCchAddBackslashW #define PathCchRemoveBackslash PathCchRemoveBackslashW @@ -248,6 +253,10 @@ WINPR_API PCWSTR PathGetSharedLibraryExtensionW(unsigned long dwFlags); #define PathGetSharedLibraryExtension PathGetSharedLibraryExtensionA #endif +#ifdef __cplusplus +} +#endif + #endif /** @@ -261,6 +270,10 @@ WINPR_API PCWSTR PathGetSharedLibraryExtensionW(unsigned long dwFlags); #define KNOWN_PATH_XDG_CACHE_HOME 5 #define KNOWN_PATH_XDG_RUNTIME_DIR 6 +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API char* GetKnownPath(int id); WINPR_API char* GetKnownSubPath(int id, char* path); WINPR_API char* GetCombinedPath(char* basePath, char* subPath); @@ -270,6 +283,10 @@ WINPR_API char* GetCombinedPath(char* basePath, char* subPath); WINPR_API BOOL PathFileExistsA(LPCSTR pszPath); WINPR_API BOOL PathFileExistsW(LPCWSTR pszPath); +#ifdef __cplusplus +} +#endif + #ifdef UNICODE #define PathFileExists PathFileExistsW #else diff --git a/winpr/include/winpr/pipe.h b/winpr/include/winpr/pipe.h index e95de7106..3875c4b6c 100644 --- a/winpr/include/winpr/pipe.h +++ b/winpr/include/winpr/pipe.h @@ -28,8 +28,16 @@ #ifndef _WIN32 +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize); +#ifdef __cplusplus +} +#endif + #endif #endif /* WINPR_PIPE_H */ diff --git a/winpr/include/winpr/pool.h b/winpr/include/winpr/pool.h index 4ea9751b3..8ff2ff855 100644 --- a/winpr/include/winpr/pool.h +++ b/winpr/include/winpr/pool.h @@ -152,6 +152,10 @@ typedef VOID (*PTP_WIN32_IO_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Cont #endif +#ifdef __cplusplus +extern "C" { +#endif + /* Synch */ @@ -225,4 +229,8 @@ WINPR_API VOID DisassociateCurrentThreadFromCallback(PTP_CALLBACK_INSTANCE pci); WINPR_API void winpr_pool_dummy(void); +#ifdef __cplusplus +} +#endif + #endif /* WINPR_POOL_H */ diff --git a/winpr/include/winpr/print.h b/winpr/include/winpr/print.h index 72049692d..d5e9cc724 100644 --- a/winpr/include/winpr/print.h +++ b/winpr/include/winpr/print.h @@ -25,8 +25,16 @@ #define WINPR_HEXDUMP_LINE_LENGTH 16 +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API void winpr_HexDump(BYTE* data, int length); WINPR_API int wprintfx(const char *fmt, ...); +#ifdef __cplusplus +} +#endif + #endif /* WINPR_UTILS_PRINT_H */ diff --git a/winpr/include/winpr/registry.h b/winpr/include/winpr/registry.h index 2994ae8bc..a4021b360 100644 --- a/winpr/include/winpr/registry.h +++ b/winpr/include/winpr/registry.h @@ -28,6 +28,10 @@ #else +#ifdef __cplusplus +extern "C" { +#endif + #include <winpr/winpr.h> #include <winpr/wtypes.h> @@ -402,6 +406,10 @@ WINPR_API LONG RegUnLoadKeyA(HKEY hKey, LPCSTR lpSubKey); #define RegUnLoadKey RegUnLoadKeyA #endif +#ifdef __cplusplus +} +#endif + #endif #endif /* WINPR_REGISTRY_H */ diff --git a/winpr/include/winpr/rpc.h b/winpr/include/winpr/rpc.h index b009bd1f1..428ebf7e7 100644 --- a/winpr/include/winpr/rpc.h +++ b/winpr/include/winpr/rpc.h @@ -445,6 +445,10 @@ typedef struct _RPC_BINDING_HANDLE_TEMPLATE #include <winpr/ndr.h> #include <winpr/midl.h> +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API RPC_STATUS RpcBindingCopy(RPC_BINDING_HANDLE SourceBinding, RPC_BINDING_HANDLE* DestinationBinding); WINPR_API RPC_STATUS RpcBindingFree(RPC_BINDING_HANDLE* Binding); WINPR_API RPC_STATUS RpcBindingSetOption(RPC_BINDING_HANDLE hBinding, unsigned long option, ULONG_PTR optionValue); @@ -601,6 +605,10 @@ WINPR_API RPC_STATUS RpcMgmtSetAuthorizationFn(RPC_MGMT_AUTHORIZATION_FN Authori WINPR_API RPC_STATUS RpcServerInqBindingHandle(RPC_BINDING_HANDLE* Binding); +#ifdef __cplusplus +} +#endif + #endif #endif /* WINPR_RPC_H */ diff --git a/winpr/include/winpr/sam.h b/winpr/include/winpr/sam.h index 92475947f..ea252e01a 100644 --- a/winpr/include/winpr/sam.h +++ b/winpr/include/winpr/sam.h @@ -43,6 +43,10 @@ struct winpr_sam_entry }; typedef struct winpr_sam_entry WINPR_SAM_ENTRY; +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API WINPR_SAM_ENTRY* SamLookupUserA(WINPR_SAM* sam, LPSTR User, UINT32 UserLength, LPSTR Domain, UINT32 DomainLength); WINPR_API WINPR_SAM_ENTRY* SamLookupUserW(WINPR_SAM* sam, LPWSTR User, UINT32 UserLength, LPWSTR Domain, UINT32 DomainLength); @@ -51,5 +55,9 @@ WINPR_API void SamFreeEntry(WINPR_SAM* sam, WINPR_SAM_ENTRY* entry); WINPR_API WINPR_SAM* SamOpen(BOOL read_only); WINPR_API void SamClose(WINPR_SAM* sam); +#ifdef __cplusplus +} +#endif + #endif /* WINPR_UTILS_SAM_H */ diff --git a/winpr/include/winpr/security.h b/winpr/include/winpr/security.h index ab342cf3d..59f02d953 100644 --- a/winpr/include/winpr/security.h +++ b/winpr/include/winpr/security.h @@ -23,13 +23,6 @@ #include <winpr/winpr.h> #include <winpr/wtypes.h> -typedef struct _LSA_UNICODE_STRING -{ - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; - /** * Windows Integrity Mechanism Design: * http://msdn.microsoft.com/en-us/library/bb625963.aspx @@ -37,6 +30,13 @@ typedef struct _LSA_UNICODE_STRING #ifndef _WIN32 +typedef struct _LSA_UNICODE_STRING +{ + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; + #define SECURITY_MANDATORY_UNTRUSTED_RID 0x0000 #define SECURITY_MANDATORY_LOW_RID 0x1000 #define SECURITY_MANDATORY_MEDIUM_RID 0x2000 diff --git a/winpr/include/winpr/sspi.h b/winpr/include/winpr/sspi.h index a2d780a47..f2adcd2bb 100644 --- a/winpr/include/winpr/sspi.h +++ b/winpr/include/winpr/sspi.h @@ -930,6 +930,10 @@ typedef PSecurityFunctionTableW (SEC_ENTRY * INIT_SECURITY_INTERFACE_W)(void); #define INIT_SECURITY_INTERFACE INIT_SECURITY_INTERFACE_A #endif +#ifdef __cplusplus +extern "C" { +#endif + /* Package Management */ WINPR_API SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesA(ULONG* pcPackages, PSecPkgInfoA* ppPackageInfo); @@ -992,6 +996,15 @@ WINPR_API SECURITY_STATUS SEC_ENTRY EncryptMessage(PCtxtHandle phContext, ULONG WINPR_API SECURITY_STATUS SEC_ENTRY MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo); WINPR_API SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP); +#ifdef __cplusplus +} +#endif + +#endif // WINPR_SSPI + + +#ifdef __cplusplus +extern "C" { #endif /* Custom API */ @@ -1005,4 +1018,8 @@ WINPR_API void sspi_SecBufferFree(PSecBuffer SecBuffer); WINPR_API void sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, char* user, char* domain, char* password); WINPR_API void sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDENTITY* srcIdentity); +#ifdef __cplusplus +} +#endif + #endif /* WINPR_SSPI_H */ diff --git a/winpr/include/winpr/sspicli.h b/winpr/include/winpr/sspicli.h index 602da2931..30869a1ab 100644 --- a/winpr/include/winpr/sspicli.h +++ b/winpr/include/winpr/sspicli.h @@ -75,9 +75,17 @@ typedef enum } EXTENDED_NAME_FORMAT, *PEXTENDED_NAME_FORMAT; +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize); WINPR_API BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize); +#ifdef __cplusplus +} +#endif + #ifdef UNICODE #define GetUserNameEx GetUserNameExW #else diff --git a/winpr/include/winpr/stream.h b/winpr/include/winpr/stream.h index 3c0924eb0..0232841ad 100644 --- a/winpr/include/winpr/stream.h +++ b/winpr/include/winpr/stream.h @@ -23,21 +23,28 @@ #include <winpr/winpr.h> #include <winpr/wtypes.h> +#include <winpr/endian.h> #ifdef __cplusplus extern "C" { #endif +typedef struct _wStreamPool wStreamPool; + struct _wStream { BYTE* buffer; BYTE* pointer; size_t length; size_t capacity; + + DWORD count; + wStreamPool* pool; }; typedef struct _wStream wStream; WINPR_API void Stream_EnsureCapacity(wStream* s, size_t size); +WINPR_API void Stream_EnsureRemainingCapacity(wStream* s, size_t size); WINPR_API wStream* Stream_New(BYTE* buffer, size_t size); WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer); @@ -63,10 +70,10 @@ WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer); _s->pointer += 4; } while (0) #define Stream_Read_UINT32_BE(_s, _v) do { _v = \ - (((uint32)(*(_s->pointer))) << 24) + \ - (((uint32)(*(_s->pointer + 1))) << 16) + \ - (((uint32)(*(_s->pointer + 2))) << 8) + \ - (((uint32)(*(_s->pointer + 3)))); \ + (((UINT32)(*(_s->pointer))) << 24) + \ + (((UINT32)(*(_s->pointer + 1))) << 16) + \ + (((UINT32)(*(_s->pointer + 2))) << 8) + \ + (((UINT32)(*(_s->pointer + 3)))); \ _s->pointer += 4; } while (0) #define Stream_Read_UINT64(_s, _v) do { _v = \ @@ -181,162 +188,69 @@ WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer); _src->pointer += _n; \ } while (0) -#define Stream_Pointer(_s) _s->pointer -#define Stream_Buffer(_s) _s->buffer -#define Stream_Length(_s) _s->length -#define Stream_Capacity(_s) _s->capacity -#define Stream_Position(_s) (_s->pointer - _s->buffer) +#define Stream_Buffer(_s) _s->buffer +#define Stream_GetBuffer(_s, _b) _b = _s->buffer +#define Stream_SetBuffer(_s, _b) _s->buffer = _b +#define Stream_Pointer(_s) _s->pointer +#define Stream_GetPointer(_s, _p) _p = _s->pointer +#define Stream_SetPointer(_s, _p) _s->pointer = _p + +#define Stream_Length(_s) _s->length +#define Stream_GetLength(_s, _l) _l = _s->length +#define Stream_SetLength(_s, _l) _s->length = _l + +#define Stream_Capacity(_s) _s->capacity +#define Stream_GetCapacity(_s, _c) _c = _s->capacity +#define Stream_SetCapacity(_s, _c) _s->capacity = _c + +#define Stream_GetPosition(_s) (_s->pointer - _s->buffer) #define Stream_SetPosition(_s, _p) _s->pointer = _s->buffer + (_p) -/* Deprecated STREAM API */ +#define Stream_SealLength(_s) _s->length = (_s->pointer - _s->buffer) +#define Stream_GetRemainingLength(_s) (_s->length - (_s->pointer - _s->buffer)) -WINPR_API wStream* stream_new(int size); -WINPR_API void stream_free(wStream* stream); +#define Stream_Clear(_s) memset(_s->buffer, 0, _s->capacity) -#define stream_attach(_s, _buf, _size) do { \ - _s->capacity = _size; \ - _s->buffer = _buf; \ - _s->pointer = _buf; } while (0) -#define stream_detach(_s) memset(_s, 0, sizeof(wStream)) -#define stream_clear(_s) memset(_s->buffer, 0, _s->capacity) - -WINPR_API void stream_extend(wStream* stream, int request_size); -#define stream_check_size(_s, _n) \ - while (_s->pointer - _s->buffer + (_n) > _s->capacity) \ - stream_extend(_s, _n) - -#define stream_get_pos(_s) (_s->pointer - _s->buffer) -#define stream_set_pos(_s,_m) _s->pointer = _s->buffer + (_m) -#define stream_seek(_s,_offset) _s->pointer += (_offset) -#define stream_rewind(_s,_offset) _s->pointer -= (_offset) -#define stream_seal(_s) _s->capacity = (_s->pointer - _s->buffer) -#define stream_get_mark(_s,_mark) _mark = _s->pointer -#define stream_set_mark(_s,_mark) _s->pointer = _mark -#define stream_get_head(_s) _s->buffer -#define stream_get_tail(_s) _s->pointer -#define stream_get_length(_s) (_s->pointer - _s->buffer) -#define stream_get_data(_s) (_s->buffer) -#define stream_get_size(_s) (_s->capacity) -#define stream_get_left(_s) (_s->capacity - (_s->pointer - _s->buffer)) - -#define stream_read_BYTE(_s, _v) do { _v = *_s->pointer++; } while (0) -#define stream_read_UINT16(_s, _v) do { _v = \ - (UINT16)(*_s->pointer) + \ - (UINT16)(((UINT16)(*(_s->pointer + 1))) << 8); \ - _s->pointer += 2; } while (0) -#define stream_read_UINT32(_s, _v) do { _v = \ - (UINT32)(*_s->pointer) + \ - (((UINT32)(*(_s->pointer + 1))) << 8) + \ - (((UINT32)(*(_s->pointer + 2))) << 16) + \ - (((UINT32)(*(_s->pointer + 3))) << 24); \ - _s->pointer += 4; } while (0) -#define stream_read_UINT64(_s, _v) do { _v = \ - (UINT64)(*_s->pointer) + \ - (((UINT64)(*(_s->pointer + 1))) << 8) + \ - (((UINT64)(*(_s->pointer + 2))) << 16) + \ - (((UINT64)(*(_s->pointer + 3))) << 24) + \ - (((UINT64)(*(_s->pointer + 4))) << 32) + \ - (((UINT64)(*(_s->pointer + 5))) << 40) + \ - (((UINT64)(*(_s->pointer + 6))) << 48) + \ - (((UINT64)(*(_s->pointer + 7))) << 56); \ - _s->pointer += 8; } while (0) -#define stream_read(_s, _b, _n) do { \ - memcpy(_b, (_s->pointer), (_n)); \ - _s->pointer += (_n); \ - } while (0) - -#define stream_write_BYTE(_s, _v) do { \ - *_s->pointer++ = (BYTE)(_v); } while (0) -#define stream_write_UINT16(_s, _v) do { \ - *_s->pointer++ = (_v) & 0xFF; \ - *_s->pointer++ = ((_v) >> 8) & 0xFF; } while (0) -#define stream_write_UINT32(_s, _v) do { \ - *_s->pointer++ = (_v) & 0xFF; \ - *_s->pointer++ = ((_v) >> 8) & 0xFF; \ - *_s->pointer++ = ((_v) >> 16) & 0xFF; \ - *_s->pointer++ = ((_v) >> 24) & 0xFF; } while (0) -#define stream_write_UINT64(_s, _v) do { \ - *_s->pointer++ = (UINT64)(_v) & 0xFF; \ - *_s->pointer++ = ((UINT64)(_v) >> 8) & 0xFF; \ - *_s->pointer++ = ((UINT64)(_v) >> 16) & 0xFF; \ - *_s->pointer++ = ((UINT64)(_v) >> 24) & 0xFF; \ - *_s->pointer++ = ((UINT64)(_v) >> 32) & 0xFF; \ - *_s->pointer++ = ((UINT64)(_v) >> 40) & 0xFF; \ - *_s->pointer++ = ((UINT64)(_v) >> 48) & 0xFF; \ - *_s->pointer++ = ((UINT64)(_v) >> 56) & 0xFF; } while (0) -#define stream_write(_s, _b, _n) do { \ - memcpy(_s->pointer, (_b), (_n)); \ - _s->pointer += (_n); \ - } while (0) -#define stream_write_zero(_s, _n) do { \ - memset(_s->pointer, '\0', (_n)); \ - _s->pointer += (_n); \ - } while (0) -#define stream_set_byte(_s, _v, _n) do { \ - memset(_s->pointer, _v, (_n)); \ - _s->pointer += (_n); \ - } while (0) - -#define stream_peek_BYTE(_s, _v) do { _v = *_s->pointer; } while (0) -#define stream_peek_UINT16(_s, _v) do { _v = \ - (UINT16)(*_s->pointer) + \ - (((UINT16)(*(_s->pointer + 1))) << 8); \ - } while (0) -#define stream_peek_UINT32(_s, _v) do { _v = \ - (UINT32)(*_s->pointer) + \ - (((UINT32)(*(_s->pointer + 1))) << 8) + \ - (((UINT32)(*(_s->pointer + 2))) << 16) + \ - (((UINT32)(*(_s->pointer + 3))) << 24); \ - } while (0) -#define stream_peek_UINT64(_s, _v) do { _v = \ - (UINT64)(*_s->pointer) + \ - (((UINT64)(*(_s->pointer + 1))) << 8) + \ - (((UINT64)(*(_s->pointer + 2))) << 16) + \ - (((UINT64)(*(_s->pointer + 3))) << 24) + \ - (((UINT64)(*(_s->pointer + 4))) << 32) + \ - (((UINT64)(*(_s->pointer + 5))) << 40) + \ - (((UINT64)(*(_s->pointer + 6))) << 48) + \ - (((UINT64)(*(_s->pointer + 7))) << 56); \ - } while (0) - -#define stream_seek_BYTE(_s) stream_seek(_s, 1) -#define stream_seek_UINT16(_s) stream_seek(_s, 2) -#define stream_seek_UINT32(_s) stream_seek(_s, 4) -#define stream_seek_UINT64(_s) stream_seek(_s, 8) - -#define stream_read_UINT16_be(_s, _v) do { _v = \ - (((UINT16)(*_s->pointer)) << 8) + \ - (UINT16)(*(_s->pointer + 1)); \ - _s->pointer += 2; } while (0) -#define stream_read_UINT32_be(_s, _v) do { _v = \ - (((UINT32)(*(_s->pointer))) << 24) + \ - (((UINT32)(*(_s->pointer + 1))) << 16) + \ - (((UINT32)(*(_s->pointer + 2))) << 8) + \ - (((UINT32)(*(_s->pointer + 3)))); \ - _s->pointer += 4; } while (0) - -#define stream_write_UINT16_be(_s, _v) do { \ - *_s->pointer++ = ((_v) >> 8) & 0xFF; \ - *_s->pointer++ = (_v) & 0xFF; } while (0) -#define stream_write_UINT32_be(_s, _v) do { \ - stream_write_UINT16_be(_s, ((_v) >> 16 & 0xFFFF)); \ - stream_write_UINT16_be(_s, ((_v) & 0xFFFF)); \ - } while (0) - -#define stream_copy(_dst, _src, _n) do { \ - memcpy(_dst->pointer, _src->pointer, _n); \ - _dst->pointer += _n; \ - _src->pointer += _n; \ - } while (0) - -static INLINE BOOL stream_skip(wStream* s, int sz) { - if ((int) stream_get_left(s) < sz) +static INLINE BOOL Stream_SafeSeek(wStream* s, size_t size) { + if (Stream_GetRemainingLength(s) < size) return FALSE; - stream_seek(s, sz); + Stream_Seek(s, size); return TRUE; } +/* StreamPool */ + +struct _wStreamPool +{ + int aSize; + int aCapacity; + wStream** aArray; + + int uSize; + int uCapacity; + wStream** uArray; + + HANDLE mutex; + BOOL synchronized; + size_t defaultSize; +}; + +WINPR_API wStream* StreamPool_Take(wStreamPool* pool, size_t size); +WINPR_API void StreamPool_Return(wStreamPool* pool, wStream* s); + +WINPR_API void Stream_AddRef(wStream* s); +WINPR_API void Stream_Release(wStream* s); + +WINPR_API wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr); +WINPR_API void StreamPool_AddRef(wStreamPool* pool, BYTE* ptr); +WINPR_API void StreamPool_Release(wStreamPool* pool, BYTE* ptr); + +WINPR_API void StreamPool_Clear(wStreamPool* pool); + +WINPR_API wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize); +WINPR_API void StreamPool_Free(wStreamPool* pool); + #ifdef __cplusplus } #endif diff --git a/winpr/include/winpr/string.h b/winpr/include/winpr/string.h index 6bcae3eee..8cb2466f0 100644 --- a/winpr/include/winpr/string.h +++ b/winpr/include/winpr/string.h @@ -25,6 +25,10 @@ #include <winpr/winpr.h> #include <winpr/wtypes.h> +#ifdef __cplusplus +extern "C" { +#endif + #ifndef _WIN32 #define CSTR_LESS_THAN 1 @@ -174,4 +178,8 @@ WINPR_API int ConvertToUnicode(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteS WINPR_API int ConvertFromUnicode(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR* lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar); +#ifdef __cplusplus +} +#endif + #endif /* WINPR_CRT_STRING_H */ diff --git a/winpr/include/winpr/synch.h b/winpr/include/winpr/synch.h index dd9bd13b4..c9bb0ad39 100644 --- a/winpr/include/winpr/synch.h +++ b/winpr/include/winpr/synch.h @@ -273,6 +273,8 @@ WINPR_API HANDLE CreateWaitObjectEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, #endif WINPR_API int GetEventFileDescriptor(HANDLE hEvent); +WINPR_API int SetEventFileDescriptor(HANDLE hEvent, int FileDescriptor); + WINPR_API void* GetEventWaitObject(HANDLE hEvent); #ifdef __cplusplus diff --git a/winpr/include/winpr/sysinfo.h b/winpr/include/winpr/sysinfo.h index 0a6ad2e42..80f4e4af7 100644 --- a/winpr/include/winpr/sysinfo.h +++ b/winpr/include/winpr/sysinfo.h @@ -26,6 +26,10 @@ #include <winpr/winpr.h> #include <winpr/wtypes.h> +#ifdef __cplusplus +extern "C" { +#endif + #ifndef _WIN32 #define PROCESSOR_ARCHITECTURE_INTEL 0 @@ -310,4 +314,8 @@ WINPR_API BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature); #define PF_SSE_INSTRUCTIONS_AVAILABLE PF_XMMI_INSTRUCTIONS_AVAILABLE #define PF_SSE2_INSTRUCTIONS_AVAILABLE PF_XMMI64_INSTRUCTIONS_AVAILABLE +#ifdef __cplusplus +} +#endif + #endif /* WINPR_SYSINFO_H */ diff --git a/winpr/include/winpr/winhttp.h b/winpr/include/winpr/winhttp.h index 5f296eb9d..07762bc37 100644 --- a/winpr/include/winpr/winhttp.h +++ b/winpr/include/winpr/winhttp.h @@ -593,6 +593,10 @@ typedef struct #define WINHTTP_ERROR_LAST (WINHTTP_ERROR_BASE + 186) +#ifdef __cplusplus +extern "C" { +#endif + WINPR_API BOOL WinHttpTimeFromSystemTime(const SYSTEMTIME* pst, LPWSTR pwszTime); WINPR_API BOOL WinHttpTimeToSystemTime(LPCWSTR pwszTime, SYSTEMTIME* pst); @@ -651,6 +655,10 @@ WINPR_API BOOL WinHttpGetProxyForUrl(HINTERNET hSession, LPCWSTR lpcwszUrl, WINPR_API BOOL WinHttpGetIEProxyConfigForCurrentUser(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* pProxyConfig); +#ifdef __cplusplus +} +#endif + #endif #endif /* WINPR_WINHTTP_H */ diff --git a/winpr/libwinpr/CMakeLists.txt b/winpr/libwinpr/CMakeLists.txt index 0a56165ad..fdb2bdac5 100644 --- a/winpr/libwinpr/CMakeLists.txt +++ b/winpr/libwinpr/CMakeLists.txt @@ -48,7 +48,7 @@ if(MONOLITHIC_BUILD) set(${MODULE_PREFIX}_OBJECTS ${${MODULE_PREFIX}_OBJECTS} "$<TARGET_OBJECTS:${MODULE_NAME}-${${MODULE_PREFIX}_SUBMODULE}>") endforeach() - add_library(${MODULE_NAME} ${${MODULE_PREFIX}_OBJECTS}) + add_library(${MODULE_NAME} dummy.c ${${MODULE_PREFIX}_OBJECTS}) set_target_properties(${MODULE_NAME} PROPERTIES LINKER_LANGUAGE C) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") diff --git a/winpr/libwinpr/dummy.c b/winpr/libwinpr/dummy.c new file mode 100644 index 000000000..b959f9be3 --- /dev/null +++ b/winpr/libwinpr/dummy.c @@ -0,0 +1,5 @@ + +int dummy() +{ + return 0; +} diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 16cdabf63..b43cd215c 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -139,6 +139,10 @@ #include <sys/statvfs.h> #endif +#include "../handle/handle.h" + +#include "../pipe/pipe.h" + HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { @@ -166,6 +170,7 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, { ULONG Type; PVOID Object; + WINPR_PIPE* pipe; if (!winpr_Handle_GetInfo(hFile, &Type, &Object)) return FALSE; @@ -173,11 +178,10 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, if (Type == HANDLE_TYPE_ANONYMOUS_PIPE) { int status; - int read_fd; - read_fd = (int) ((ULONG_PTR) Object); + pipe = (WINPR_PIPE*) Object; - status = read(read_fd, lpBuffer, nNumberOfBytesToRead); + status = read(pipe->fd, lpBuffer, nNumberOfBytesToRead); *lpNumberOfBytesRead = status; @@ -204,6 +208,7 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, { ULONG Type; PVOID Object; + WINPR_PIPE* pipe; if (!winpr_Handle_GetInfo(hFile, &Type, &Object)) return FALSE; @@ -211,11 +216,10 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, if (Type == HANDLE_TYPE_ANONYMOUS_PIPE) { int status; - int write_fd; - write_fd = (int) ((ULONG_PTR) Object); + pipe = (WINPR_PIPE*) Object; - status = write(write_fd, lpBuffer, nNumberOfBytesToWrite); + status = write(pipe->fd, lpBuffer, nNumberOfBytesToWrite); *lpNumberOfBytesWritten = status; diff --git a/winpr/libwinpr/handle/CMakeLists.txt b/winpr/libwinpr/handle/CMakeLists.txt index 73b73d336..db25fea70 100644 --- a/winpr/libwinpr/handle/CMakeLists.txt +++ b/winpr/libwinpr/handle/CMakeLists.txt @@ -20,6 +20,7 @@ set(MODULE_PREFIX "WINPR_HANDLE") set(${MODULE_PREFIX}_SRCS handle.c + handle.h table.c) if(MSVC AND (NOT MONOLITHIC_BUILD)) diff --git a/winpr/libwinpr/handle/handle.c b/winpr/libwinpr/handle/handle.c index 1994eae0a..d198a11a2 100644 --- a/winpr/libwinpr/handle/handle.c +++ b/winpr/libwinpr/handle/handle.c @@ -27,11 +27,14 @@ #include "../synch/synch.h" #include "../thread/thread.h" +#include "../pipe/pipe.h" #ifdef HAVE_UNISTD_H #include <unistd.h> #endif +#include "../handle/handle.h" + BOOL CloseHandle(HANDLE hObject) { ULONG Type; @@ -46,14 +49,18 @@ BOOL CloseHandle(HANDLE hObject) thread = (WINPR_THREAD*) Object; - free(thread); + free(Object); return TRUE; } else if (Type == HANDLE_TYPE_MUTEX) { - pthread_mutex_destroy((pthread_mutex_t*) Object); - winpr_Handle_Remove(Object); + WINPR_MUTEX* mutex; + + mutex = (WINPR_MUTEX*) Object; + + pthread_mutex_destroy(&mutex->mutex); + free(Object); return TRUE; @@ -78,8 +85,7 @@ BOOL CloseHandle(HANDLE hObject) } } - winpr_Handle_Remove(Object); - free(event); + free(Object); return TRUE; } @@ -112,23 +118,22 @@ BOOL CloseHandle(HANDLE hObject) #endif #endif - winpr_Handle_Remove(Object); free(Object); return TRUE; } else if (Type == HANDLE_TYPE_ANONYMOUS_PIPE) { - int pipe_fd; + WINPR_PIPE* pipe; - pipe_fd = (int) ((ULONG_PTR) Object); + pipe = (WINPR_PIPE*) Object; - if (pipe_fd != -1) + if (pipe->fd != -1) { - close(pipe_fd); + close(pipe->fd); } - winpr_Handle_Remove(Object); + free(Object); return TRUE; } diff --git a/winpr/libwinpr/handle/handle.h b/winpr/libwinpr/handle/handle.h new file mode 100644 index 000000000..5011e826d --- /dev/null +++ b/winpr/libwinpr/handle/handle.h @@ -0,0 +1,58 @@ +/** + * WinPR: Windows Portable Runtime + * Handle Management + * + * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_HANDLE_PRIVATE_H +#define WINPR_HANDLE_PRIVATE_H + +#include <winpr/handle.h> + +#define HANDLE_TYPE_NONE 0 +#define HANDLE_TYPE_THREAD 1 +#define HANDLE_TYPE_EVENT 2 +#define HANDLE_TYPE_MUTEX 3 +#define HANDLE_TYPE_SEMAPHORE 4 +#define HANDLE_TYPE_TIMER 5 +#define HANDLE_TYPE_NAMED_PIPE 6 +#define HANDLE_TYPE_ANONYMOUS_PIPE 7 + +#define WINPR_HANDLE_DEF() \ + ULONG Type; + +struct winpr_handle +{ + WINPR_HANDLE_DEF(); +}; +typedef struct winpr_handle WINPR_HANDLE; + +#define WINPR_HANDLE_SET_TYPE(_handle, _type) \ + _handle->Type = _type + +static inline BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject) +{ + WINPR_HANDLE* wHandle; + + wHandle = (WINPR_HANDLE*) handle; + + *pType = wHandle->Type; + *pObject = handle; + + return TRUE; +} + +#endif /* WINPR_HANDLE_PRIVATE_H */ diff --git a/winpr/libwinpr/handle/table.c b/winpr/libwinpr/handle/table.c index 40e082c75..eb81e2b0c 100644 --- a/winpr/libwinpr/handle/table.c +++ b/winpr/libwinpr/handle/table.c @@ -26,193 +26,7 @@ #ifndef _WIN32 -#include <pthread.h> - -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - -typedef struct _HANDLE_TABLE_ENTRY -{ - ULONG Type; - PVOID Object; -} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; - -typedef struct _HANDLE_TABLE -{ - LONG Count; - LONG MaxCount; - PHANDLE_TABLE_ENTRY Entries; -} HANDLE_TABLE, *PHANDLE_TABLE; - -static HANDLE_TABLE HandleTable = { 0, 0, NULL }; - -#define HandleTable_GetInstance() \ - if (HandleTable.MaxCount < 1) \ - winpr_HandleTable_New() - -void winpr_HandleTable_New() -{ - size_t size; - - pthread_mutex_lock(&mutex); - - if (HandleTable.MaxCount < 1) - { - HandleTable.Count = 0; - HandleTable.MaxCount = 64; - - size = sizeof(HANDLE_TABLE_ENTRY) * HandleTable.MaxCount; - - HandleTable.Entries = (PHANDLE_TABLE_ENTRY) malloc(size); - ZeroMemory(HandleTable.Entries, size); - } - - pthread_mutex_unlock(&mutex); -} - -void winpr_HandleTable_Grow() -{ - size_t size; - - pthread_mutex_lock(&mutex); - - HandleTable.MaxCount *= 2; - - size = sizeof(HANDLE_TABLE_ENTRY) * HandleTable.MaxCount; - - HandleTable.Entries = (PHANDLE_TABLE_ENTRY) realloc(HandleTable.Entries, size); - ZeroMemory((void*) &HandleTable.Entries[HandleTable.MaxCount / 2], size / 2); - - pthread_mutex_unlock(&mutex); -} - -void winpr_HandleTable_Free() -{ - pthread_mutex_lock(&mutex); - - HandleTable.Count = 0; - HandleTable.MaxCount = 0; - - free(HandleTable.Entries); - HandleTable.Entries = NULL; - - pthread_mutex_unlock(&mutex); -} - -HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object) -{ - int index; - - HandleTable_GetInstance(); - - pthread_mutex_lock(&mutex); - - for (index = 0; index < (int) HandleTable.MaxCount; index++) - { - if (HandleTable.Entries[index].Object == NULL) - { - HandleTable.Count++; - - HandleTable.Entries[index].Type = Type; - HandleTable.Entries[index].Object = Object; - - pthread_mutex_unlock(&mutex); - - return Object; - } - } - - pthread_mutex_unlock(&mutex); - - /* no available entry was found, the table needs to be grown */ - - winpr_HandleTable_Grow(); - - /* the next call should now succeed */ - - return winpr_Handle_Insert(Type, Object); -} - -BOOL winpr_Handle_Remove(HANDLE handle) -{ - int index; - - HandleTable_GetInstance(); - - pthread_mutex_lock(&mutex); - - for (index = 0; index < (int) HandleTable.MaxCount; index++) - { - if (HandleTable.Entries[index].Object == handle) - { - HandleTable.Entries[index].Type = HANDLE_TYPE_NONE; - HandleTable.Entries[index].Object = NULL; - HandleTable.Count--; - - pthread_mutex_unlock(&mutex); - - return TRUE; - } - } - - pthread_mutex_unlock(&mutex); - - return FALSE; -} - -ULONG winpr_Handle_GetType(HANDLE handle) -{ - int index; - - HandleTable_GetInstance(); - - pthread_mutex_lock(&mutex); - - for (index = 0; index < (int) HandleTable.MaxCount; index++) - { - if (HandleTable.Entries[index].Object == handle) - { - pthread_mutex_unlock(&mutex); - return HandleTable.Entries[index].Type; - } - } - - pthread_mutex_unlock(&mutex); - - return HANDLE_TYPE_NONE; -} - -PVOID winpr_Handle_GetObject(HANDLE handle) -{ - HandleTable_GetInstance(); - - return handle; -} - -BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject) -{ - int index; - - HandleTable_GetInstance(); - - pthread_mutex_lock(&mutex); - - for (index = 0; index < (int) HandleTable.MaxCount; index++) - { - if (HandleTable.Entries[index].Object == handle) - { - *pType = HandleTable.Entries[index].Type; - *pObject = HandleTable.Entries[index].Object; - - pthread_mutex_unlock(&mutex); - - return TRUE; - } - } - - pthread_mutex_unlock(&mutex); - - return FALSE; -} +#include "../handle/handle.h" #endif diff --git a/winpr/libwinpr/input/keycode.c b/winpr/libwinpr/input/keycode.c index 63960a152..295fe3b1b 100644 --- a/winpr/libwinpr/input/keycode.c +++ b/winpr/libwinpr/input/keycode.c @@ -584,3 +584,34 @@ DWORD GetVirtualKeyCodeFromKeycode(DWORD keycode, DWORD dwFlags) return vkcode; } + +DWORD GetKeycodeFromVirtualKeyCode(DWORD vkcode, DWORD dwFlags) +{ + int index; + DWORD keycode = 0; + + if (dwFlags & KEYCODE_TYPE_APPLE) + { + for (index = 0; index < 256; index++) + { + if (vkcode == KEYCODE_TO_VKCODE_APPLE[index]) + { + keycode = index; + break; + } + } + } + else if (dwFlags & KEYCODE_TYPE_EVDEV) + { + for (index = 0; index < 256; index++) + { + if (vkcode == KEYCODE_TO_VKCODE_EVDEV[index]) + { + keycode = index; + break; + } + } + } + + return keycode; +} diff --git a/winpr/libwinpr/path/shell.c b/winpr/libwinpr/path/shell.c index c60baa7ac..0c41e54c0 100644 --- a/winpr/libwinpr/path/shell.c +++ b/winpr/libwinpr/path/shell.c @@ -140,6 +140,9 @@ char* GetPath_XDG_CONFIG_HOME() home = GetPath_HOME(); + if (!home) + home = GetPath_TEMP(); + path = (char*) malloc(strlen(home) + strlen("/.config") + 1); sprintf(path, "%s%s", home, "/.config"); diff --git a/winpr/libwinpr/pipe/CMakeLists.txt b/winpr/libwinpr/pipe/CMakeLists.txt index b5b055828..d30b31cbb 100644 --- a/winpr/libwinpr/pipe/CMakeLists.txt +++ b/winpr/libwinpr/pipe/CMakeLists.txt @@ -19,7 +19,8 @@ set(MODULE_NAME "winpr-pipe") set(MODULE_PREFIX "WINPR_PIPE") set(${MODULE_PREFIX}_SRCS - pipe.c) + pipe.c + pipe.h) if(MSVC AND (NOT MONOLITHIC_BUILD)) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 14d784beb..8b2ee59e9 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -32,11 +32,17 @@ #ifndef _WIN32 +#include "../handle/handle.h" + +#include "pipe.h" + BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize) { void* ptr; HANDLE handle; int pipe_fd[2]; + WINPR_PIPE* pReadPipe; + WINPR_PIPE* pWritePipe; pipe_fd[0] = -1; pipe_fd[1] = -1; @@ -47,13 +53,20 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP return FALSE; } - ptr = (void*) ((ULONG_PTR) pipe_fd[0]); - handle = winpr_Handle_Insert(HANDLE_TYPE_ANONYMOUS_PIPE, ptr); - *((ULONG_PTR*) hReadPipe) = (ULONG_PTR) handle; + pReadPipe = (WINPR_PIPE*) malloc(sizeof(WINPR_PIPE)); + pWritePipe = (WINPR_PIPE*) malloc(sizeof(WINPR_PIPE)); - ptr = (void*) ((ULONG_PTR) pipe_fd[1]); - handle = winpr_Handle_Insert(HANDLE_TYPE_ANONYMOUS_PIPE, ptr); - *((ULONG_PTR*) hWritePipe) = (ULONG_PTR) handle; + if (!pReadPipe || !pWritePipe) + return FALSE; + + pReadPipe->fd = pipe_fd[0]; + pWritePipe->fd = pipe_fd[1]; + + WINPR_HANDLE_SET_TYPE(pReadPipe, HANDLE_TYPE_ANONYMOUS_PIPE); + *((ULONG_PTR*) hReadPipe) = (ULONG_PTR) pReadPipe; + + WINPR_HANDLE_SET_TYPE(pWritePipe, HANDLE_TYPE_ANONYMOUS_PIPE); + *((ULONG_PTR*) hWritePipe) = (ULONG_PTR) pWritePipe; return TRUE; } diff --git a/winpr/libwinpr/pipe/pipe.h b/winpr/libwinpr/pipe/pipe.h new file mode 100644 index 000000000..f884fdc3f --- /dev/null +++ b/winpr/libwinpr/pipe/pipe.h @@ -0,0 +1,41 @@ +/** + * WinPR: Windows Portable Runtime + * Pipe Functions + * + * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_PIPE_PRIVATE_H +#define WINPR_PIPE_PRIVATE_H + +#ifndef _WIN32 + +#include <winpr/pipe.h> + +#include "../handle/handle.h" + +struct winpr_pipe +{ + WINPR_HANDLE_DEF(); + + int fd; +}; +typedef struct winpr_pipe WINPR_PIPE; + +#endif + +#endif /* WINPR_PIPE_PRIVATE_H */ + + diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c index 050d1fabf..854e13581 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -119,7 +119,7 @@ void ntlm_read_ntlm_v2_client_challenge(wStream* s, NTLMv2_CLIENT_CHALLENGE* cha Stream_Read(s, challenge->ClientChallenge, 8); Stream_Read_UINT32(s, challenge->Reserved3); - size = Stream_Length(s) - Stream_Position(s); + size = Stream_Length(s) - Stream_GetPosition(s); challenge->AvPairs = (NTLM_AV_PAIR*) malloc(size); Stream_Read(s, challenge->AvPairs, size); } diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_message.c b/winpr/libwinpr/sspi/NTLM/ntlm_message.c index d4789c6e3..8b17d6990 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_message.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_message.c @@ -233,7 +233,7 @@ SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buf if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION) ntlm_read_version_info(s, &(message->Version)); /* Version (8 bytes) */ - length = Stream_Position(s); + length = Stream_GetPosition(s); buffer->cbBuffer = length; sspi_SecBufferAlloc(&context->NegotiateMessage, length); @@ -317,7 +317,7 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION) ntlm_write_version_info(s, &(message->Version)); - length = Stream_Position(s); + length = Stream_GetPosition(s); buffer->cbBuffer = length; sspi_SecBufferAlloc(&context->NegotiateMessage, length); @@ -326,7 +326,7 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu #ifdef WITH_DEBUG_NTLM fprintf(stderr, "NEGOTIATE_MESSAGE (length = %d)\n", length); - winpr_HexDump(s->buffer, length); + winpr_HexDump(Stream_Buffer(s), length); fprintf(stderr, "\n"); if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION) @@ -606,11 +606,11 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_TARGET_INFO) ntlm_write_message_fields_buffer(s, &(message->TargetInfo)); - length = Stream_Position(s); + length = Stream_GetPosition(s); buffer->cbBuffer = length; sspi_SecBufferAlloc(&context->ChallengeMessage, length); - CopyMemory(context->ChallengeMessage.pvBuffer, s->buffer, length); + CopyMemory(context->ChallengeMessage.pvBuffer, Stream_Buffer(s), length); #ifdef WITH_DEBUG_NTLM fprintf(stderr, "CHALLENGE_MESSAGE (length = %d)\n", length); @@ -682,7 +682,7 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION) ntlm_read_version_info(s, &(message->Version)); /* Version (8 bytes) */ - PayloadBufferOffset = Stream_Position(s); + PayloadBufferOffset = Stream_GetPosition(s); ntlm_read_message_fields_buffer(s, &(message->DomainName)); /* DomainName */ @@ -718,16 +718,16 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer ntlm_read_message_fields_buffer(s, &(message->EncryptedRandomSessionKey)); CopyMemory(context->EncryptedRandomSessionKey, message->EncryptedRandomSessionKey.Buffer, 16); - length = Stream_Position(s); + length = Stream_GetPosition(s); sspi_SecBufferAlloc(&context->AuthenticateMessage, length); - CopyMemory(context->AuthenticateMessage.pvBuffer, s->buffer, length); + CopyMemory(context->AuthenticateMessage.pvBuffer, Stream_Buffer(s), length); buffer->cbBuffer = length; Stream_SetPosition(s, PayloadBufferOffset); if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK) { - MicOffset = Stream_Position(s); + MicOffset = Stream_GetPosition(s); Stream_Read(s, message->MessageIntegrityCheck, 16); PayloadBufferOffset += 16; } @@ -995,7 +995,7 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer if (context->UseMIC) { - MicOffset = Stream_Position(s); + MicOffset = Stream_GetPosition(s); Stream_Zero(s, 16); /* Message Integrity Check (16 bytes) */ } @@ -1014,9 +1014,9 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer if (message->NegotiateFlags & NTLMSSP_NEGOTIATE_KEY_EXCH) ntlm_write_message_fields_buffer(s, &(message->EncryptedRandomSessionKey)); /* EncryptedRandomSessionKey */ - length = Stream_Position(s); + length = Stream_GetPosition(s); sspi_SecBufferAlloc(&context->AuthenticateMessage, length); - CopyMemory(context->AuthenticateMessage.pvBuffer, s->buffer, length); + CopyMemory(context->AuthenticateMessage.pvBuffer, Stream_Buffer(s), length); buffer->cbBuffer = length; if (context->UseMIC) @@ -1031,7 +1031,7 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer #ifdef WITH_DEBUG_NTLM fprintf(stderr, "AUTHENTICATE_MESSAGE (length = %d)\n", length); - winpr_HexDump(s->buffer, length); + winpr_HexDump(Stream_Buffer(s), length); fprintf(stderr, "\n"); ntlm_print_negotiate_flags(message->NegotiateFlags); diff --git a/winpr/libwinpr/synch/event.c b/winpr/libwinpr/synch/event.c index 7298cb56c..173afafb7 100644 --- a/winpr/libwinpr/synch/event.c +++ b/winpr/libwinpr/synch/event.c @@ -40,6 +40,8 @@ #include <errno.h> #endif +#include "../handle/handle.h" + CRITICAL_SECTION cs = { NULL, 0, 0, NULL, NULL, 0 }; HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName) @@ -78,7 +80,8 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, } #endif - handle = winpr_Handle_Insert(HANDLE_TYPE_EVENT, event); + WINPR_HANDLE_SET_TYPE(event, HANDLE_TYPE_EVENT); + handle = (HANDLE) event; } if (!cs.LockSemaphore) @@ -122,8 +125,6 @@ BOOL SetEvent(HANDLE hEvent) status = FALSE; - EnterCriticalSection(&cs); - if (winpr_Handle_GetInfo(hEvent, &Type, &Object)) { event = (WINPR_EVENT*) Object; @@ -153,8 +154,6 @@ BOOL SetEvent(HANDLE hEvent) #endif } - LeaveCriticalSection(&cs); - return status; } @@ -168,8 +167,6 @@ BOOL ResetEvent(HANDLE hEvent) status = FALSE; - EnterCriticalSection(&cs); - if (winpr_Handle_GetInfo(hEvent, &Type, &Object)) { event = (WINPR_EVENT*) Object; @@ -196,8 +193,6 @@ BOOL ResetEvent(HANDLE hEvent) } } - LeaveCriticalSection(&cs); - return status; } @@ -219,7 +214,8 @@ HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL event->pipe_fd[0] = FileDescriptor; event->pipe_fd[1] = -1; - handle = winpr_Handle_Insert(HANDLE_TYPE_EVENT, event); + WINPR_HANDLE_SET_TYPE(event, HANDLE_TYPE_EVENT); + handle = (HANDLE) event; } return handle; @@ -273,6 +269,31 @@ int GetEventFileDescriptor(HANDLE hEvent) #endif } +/* + * Set inner file descriptor for usage with select() + * This file descriptor is not usable on Windows + */ + +int SetEventFileDescriptor(HANDLE hEvent, int FileDescriptor) +{ +#ifndef _WIN32 + ULONG Type; + PVOID Object; + WINPR_EVENT* event; + + if (!winpr_Handle_GetInfo(hEvent, &Type, &Object)) + return -1; + + event = (WINPR_EVENT*) Object; + + event->pipe_fd[0] = FileDescriptor; + + return 0; +#else + return -1; +#endif +} + /** * Returns platform-specific wait object as a void pointer * diff --git a/winpr/libwinpr/synch/mutex.c b/winpr/libwinpr/synch/mutex.c index 62c2e2611..bc0e3f02b 100644 --- a/winpr/libwinpr/synch/mutex.c +++ b/winpr/libwinpr/synch/mutex.c @@ -37,19 +37,24 @@ #ifndef _WIN32 +#include "../handle/handle.h" + HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName) { HANDLE handle = NULL; - pthread_mutex_t* pMutex; + WINPR_MUTEX* mutex; - pMutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t)); + mutex = (WINPR_MUTEX*) malloc(sizeof(WINPR_MUTEX)); - if (pMutex) + if (mutex) { - pthread_mutex_init(pMutex, 0); - handle = winpr_Handle_Insert(HANDLE_TYPE_MUTEX, pMutex); + pthread_mutex_init(&mutex->mutex, 0); + + WINPR_HANDLE_SET_TYPE(mutex, HANDLE_TYPE_MUTEX); + handle = (HANDLE) mutex; + if (bInitialOwner) - pthread_mutex_lock(pMutex); + pthread_mutex_lock(&mutex->mutex); } return handle; @@ -84,13 +89,15 @@ BOOL ReleaseMutex(HANDLE hMutex) { ULONG Type; PVOID Object; + WINPR_MUTEX* mutex; if (!winpr_Handle_GetInfo(hMutex, &Type, &Object)) return FALSE; if (Type == HANDLE_TYPE_MUTEX) { - pthread_mutex_unlock((pthread_mutex_t*) Object); + mutex = (WINPR_MUTEX*) Object; + pthread_mutex_unlock(&mutex->mutex); return TRUE; } diff --git a/winpr/libwinpr/synch/semaphore.c b/winpr/libwinpr/synch/semaphore.c index d0b7f0945..e2d3771fc 100644 --- a/winpr/libwinpr/synch/semaphore.c +++ b/winpr/libwinpr/synch/semaphore.c @@ -31,6 +31,8 @@ #ifndef _WIN32 +#include "../handle/handle.h" + HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName) { HANDLE handle; @@ -71,7 +73,8 @@ HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lIniti #endif } - handle = winpr_Handle_Insert(HANDLE_TYPE_SEMAPHORE, (PVOID) semaphore); + WINPR_HANDLE_SET_TYPE(semaphore, HANDLE_TYPE_SEMAPHORE); + handle = (HANDLE) semaphore; return handle; } diff --git a/winpr/libwinpr/synch/synch.h b/winpr/libwinpr/synch/synch.h index a7c84167e..158f3bcea 100644 --- a/winpr/libwinpr/synch/synch.h +++ b/winpr/libwinpr/synch/synch.h @@ -24,6 +24,8 @@ #ifndef _WIN32 +#include "../handle/handle.h" + #define WINPR_PIPE_SEMAPHORE 1 #if defined __APPLE__ @@ -39,8 +41,18 @@ #define winpr_sem_t sem_t #endif +struct winpr_mutex +{ + WINPR_HANDLE_DEF(); + + pthread_mutex_t mutex; +}; +typedef struct winpr_mutex WINPR_MUTEX; + struct winpr_semaphore { + WINPR_HANDLE_DEF(); + int pipe_fd[2]; winpr_sem_t* sem; }; @@ -48,6 +60,8 @@ typedef struct winpr_semaphore WINPR_SEMAPHORE; struct winpr_event { + WINPR_HANDLE_DEF(); + int pipe_fd[2]; BOOL bAttached; BOOL bManualReset; diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index 441d3ced9..3006fe246 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -41,6 +41,8 @@ #ifndef _WIN32 +#include "../handle/handle.h" + DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { ULONG Type; @@ -70,10 +72,14 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) } else if (Type == HANDLE_TYPE_MUTEX) { + WINPR_MUTEX* mutex; + + mutex = (WINPR_MUTEX*) Object; + if (dwMilliseconds != INFINITE) fprintf(stderr, "WaitForSingleObject: timeout not implemented for mutex wait\n"); - pthread_mutex_lock((pthread_mutex_t*) Object); + pthread_mutex_lock(&mutex->mutex); } else if (Type == HANDLE_TYPE_EVENT) { diff --git a/winpr/libwinpr/thread/thread.c b/winpr/libwinpr/thread/thread.c index 895c14a1e..d24159b6c 100644 --- a/winpr/libwinpr/thread/thread.c +++ b/winpr/libwinpr/thread/thread.c @@ -71,6 +71,8 @@ #include "thread.h" +#include "../handle/handle.h" + /** * TODO: implement thread suspend/resume using pthreads * http://stackoverflow.com/questions/3140867/suspend-pthreads-without-using-condition @@ -109,7 +111,8 @@ HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize pthread_mutex_init(&thread->mutex, 0); - handle = winpr_Handle_Insert(HANDLE_TYPE_THREAD, (void*) thread); + WINPR_HANDLE_SET_TYPE(thread, HANDLE_TYPE_THREAD); + handle = (HANDLE) thread; if (!(dwCreationFlags & CREATE_SUSPENDED)) winpr_StartThread(thread); diff --git a/winpr/libwinpr/thread/thread.h b/winpr/libwinpr/thread/thread.h index 263512fee..c13ff5278 100644 --- a/winpr/libwinpr/thread/thread.h +++ b/winpr/libwinpr/thread/thread.h @@ -22,14 +22,18 @@ #ifndef _WIN32 +#include <pthread.h> + #include <winpr/thread.h> -#include <pthread.h> +#include "../handle/handle.h" typedef void *(*pthread_start_routine)(void*); struct winpr_thread { + WINPR_HANDLE_DEF(); + BOOL started; DWORD dwExitCode; pthread_t thread; diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index d3f210838..50c6eaad7 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -29,6 +29,7 @@ set(${MODULE_PREFIX}_COLLECTIONS_SRCS collections/CountdownEvent.c collections/BufferPool.c collections/ObjectPool.c + collections/StreamPool.c collections/MessageQueue.c collections/MessagePipe.c) diff --git a/winpr/libwinpr/utils/collections/StreamPool.c b/winpr/libwinpr/utils/collections/StreamPool.c new file mode 100644 index 000000000..1605c5332 --- /dev/null +++ b/winpr/libwinpr/utils/collections/StreamPool.c @@ -0,0 +1,355 @@ +/** + * WinPR: Windows Portable Runtime + * Object Pool + * + * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <winpr/crt.h> + +#include <winpr/collections.h> + +/** + * Methods + */ + +void StreamPool_ShiftUsed(wStreamPool* pool, int index, int count) +{ + if (count > 0) + { + if (pool->uSize + count > pool->uCapacity) + { + pool->uCapacity *= 2; + pool->uArray = (wStream**) realloc(pool->uArray, sizeof(wStream*) * pool->uCapacity); + } + + MoveMemory(&pool->uArray[index + count], &pool->uArray[index], (pool->uSize - index) * sizeof(wStream*)); + pool->uSize += count; + } + else if (count < 0) + { + MoveMemory(&pool->uArray[index], &pool->uArray[index - count], (pool->uSize - index) * sizeof(wStream*)); + pool->uSize += count; + } +} + +/** + * Adds a used stream to the pool. + */ + +void StreamPool_AddUsed(wStreamPool* pool, wStream* s) +{ + if ((pool->uSize + 1) >= pool->uCapacity) + { + pool->uCapacity *= 2; + pool->uArray = (wStream**) realloc(pool->uArray, sizeof(wStream*) * pool->uCapacity); + } + + pool->uArray[(pool->uSize)++] = s; +} + +/** + * Removes a used stream from the pool. + */ + +void StreamPool_RemoveUsed(wStreamPool* pool, wStream* s) +{ + int index; + BOOL found = FALSE; + + for (index = 0; index < pool->uSize; index++) + { + if (pool->uArray[index] == s) + { + found = TRUE; + break; + } + } + + if (found) + StreamPool_ShiftUsed(pool, index, -1); +} + +void StreamPool_ShiftAvailable(wStreamPool* pool, int index, int count) +{ + if (count > 0) + { + if (pool->aSize + count > pool->aCapacity) + { + pool->aCapacity *= 2; + pool->aArray = (wStream**) realloc(pool->aArray, sizeof(wStream*) * pool->aCapacity); + } + + MoveMemory(&pool->aArray[index + count], &pool->aArray[index], (pool->aSize - index) * sizeof(wStream*)); + pool->aSize += count; + } + else if (count < 0) + { + MoveMemory(&pool->aArray[index], &pool->aArray[index - count], (pool->aSize - index) * sizeof(wStream*)); + pool->aSize += count; + } +} + +/** + * Gets a stream from the pool. + */ + +wStream* StreamPool_Take(wStreamPool* pool, size_t size) +{ + int index; + int foundIndex; + wStream* s = NULL; + BOOL found = FALSE; + + if (pool->synchronized) + WaitForSingleObject(pool->mutex, INFINITE); + + if (size == 0) + size = pool->defaultSize; + + for (index = 0; index < pool->aSize; index++) + { + s = pool->aArray[index]; + + if (Stream_Capacity(s) >= size) + { + foundIndex = index; + found = TRUE; + break; + } + } + + if (!found) + { + s = Stream_New(NULL, size); + } + else + { + StreamPool_ShiftAvailable(pool, foundIndex, -1); + + Stream_EnsureCapacity(s, size); + Stream_Pointer(s) = Stream_Buffer(s); + } + + s->pool = pool; + s->count = 1; + + StreamPool_AddUsed(pool, s); + + if (pool->synchronized) + ReleaseMutex(pool->mutex); + + return s; +} + +/** + * Returns an object to the pool. + */ + +void StreamPool_Return(wStreamPool* pool, wStream* s) +{ + if (pool->synchronized) + WaitForSingleObject(pool->mutex, INFINITE); + + if ((pool->aSize + 1) >= pool->aCapacity) + { + pool->aCapacity *= 2; + pool->aArray = (wStream**) realloc(pool->aArray, sizeof(wStream*) * pool->aCapacity); + } + + pool->aArray[(pool->aSize)++] = s; + StreamPool_RemoveUsed(pool, s); + + if (pool->synchronized) + ReleaseMutex(pool->mutex); +} + +/** + * Lock the stream pool + */ + +void StreamPool_Lock(wStreamPool* pool) +{ + WaitForSingleObject(pool->mutex, INFINITE); +} + +/** + * Unlock the stream pool + */ + +void StreamPool_Unlock(wStreamPool* pool) +{ + ReleaseMutex(pool->mutex); +} + +/** + * Increment stream reference count + */ + +void Stream_AddRef(wStream* s) +{ + if (s->pool) + { + StreamPool_Lock(s->pool); + s->count++; + StreamPool_Unlock(s->pool); + } +} + +/** + * Decrement stream reference count + */ + +void Stream_Release(wStream* s) +{ + DWORD count; + + if (s->pool) + { + StreamPool_Lock(s->pool); + count = --(s->count); + StreamPool_Unlock(s->pool); + + if (count == 0) + StreamPool_Return(s->pool, s); + } +} + +/** + * Find stream in pool using pointer inside buffer + */ + +wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr) +{ + int index; + wStream* s = NULL; + BOOL found = FALSE; + + WaitForSingleObject(pool->mutex, INFINITE); + + for (index = 0; index < pool->uSize; index++) + { + s = pool->uArray[index]; + + if ((ptr >= Stream_Buffer(s)) && (ptr < (Stream_Buffer(s) + Stream_Capacity(s)))) + { + found = TRUE; + break; + } + } + + ReleaseMutex(pool->mutex); + + return (found) ? s : NULL; +} + +/** + * Find stream in pool and increment reference count + */ + +void StreamPool_AddRef(wStreamPool* pool, BYTE* ptr) +{ + wStream* s; + + s = StreamPool_Find(pool, ptr); + + if (s) + Stream_AddRef(s); +} + +/** + * Find stream in pool and decrement reference count + */ + +void StreamPool_Release(wStreamPool* pool, BYTE* ptr) +{ + wStream* s; + + s = StreamPool_Find(pool, ptr); + + if (s) + Stream_Release(s); +} + +/** + * Releases the streams currently cached in the pool. + */ + +void StreamPool_Clear(wStreamPool* pool) +{ + if (pool->synchronized) + WaitForSingleObject(pool->mutex, INFINITE); + + while (pool->aSize > 0) + { + (pool->aSize)--; + Stream_Free(pool->aArray[pool->aSize], TRUE); + } + + if (pool->synchronized) + ReleaseMutex(pool->mutex); +} + +/** + * Construction, Destruction + */ + +wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize) +{ + wStreamPool* pool = NULL; + + pool = (wStreamPool*) malloc(sizeof(wStreamPool)); + + if (pool) + { + ZeroMemory(pool, sizeof(wStreamPool)); + + pool->synchronized = synchronized; + pool->defaultSize = defaultSize; + + if (pool->synchronized) + pool->mutex = CreateMutex(NULL, FALSE, NULL); + + pool->aSize = 0; + pool->aCapacity = 32; + pool->aArray = (wStream**) malloc(sizeof(wStream*) * pool->aCapacity); + + pool->uSize = 0; + pool->uCapacity = 32; + pool->uArray = (wStream**) malloc(sizeof(wStream*) * pool->uCapacity); + } + + return pool; +} + +void StreamPool_Free(wStreamPool* pool) +{ + if (pool) + { + StreamPool_Clear(pool); + + if (pool->synchronized) + CloseHandle(pool->mutex); + + free(pool->aArray); + free(pool->uArray); + + free(pool); + } +} diff --git a/winpr/libwinpr/utils/stream.c b/winpr/libwinpr/utils/stream.c index 1dad2ec92..cae3b401e 100644 --- a/winpr/libwinpr/utils/stream.c +++ b/winpr/libwinpr/utils/stream.c @@ -29,12 +29,38 @@ void Stream_EnsureCapacity(wStream* s, size_t size) { if (s->capacity < size) { - s->capacity = size; - s->buffer = (BYTE*) realloc(s->buffer, size); - s->pointer = s->buffer; + size_t position; + size_t old_capacity; + size_t new_capacity; + + old_capacity = s->capacity; + new_capacity = old_capacity; + + do + { + new_capacity *= 2; + } + while (new_capacity < size); + + s->capacity = new_capacity; + s->length = new_capacity; + + position = Stream_GetPosition(s); + + s->buffer = (BYTE*) realloc(s->buffer, s->capacity); + + ZeroMemory(&s->buffer[old_capacity], s->capacity - old_capacity); + + Stream_SetPosition(s, position); } } +void Stream_EnsureRemainingCapacity(wStream* s, size_t size) +{ + if (Stream_GetPosition(s) + size > Stream_Capacity(s)) + Stream_EnsureCapacity(s, Stream_Capacity(s) + size); +} + wStream* Stream_New(BYTE* buffer, size_t size) { wStream* s; @@ -51,6 +77,9 @@ wStream* Stream_New(BYTE* buffer, size_t size) s->pointer = s->buffer; s->capacity = size; s->length = size; + + s->pool = NULL; + s->count = 0; } return s; @@ -69,94 +98,3 @@ void Stream_Free(wStream* s, BOOL bFreeBuffer) free(s); } } - -/* Deprecated STREAM API */ - -/** - * Allocates and initializes a STREAM structure. - * STREAM are used to ease data access in read and write operations. - * They consist of a buffer containing the data we want to access, and an offset associated to it, and keeping - * track of the 'current' position in the stream. A list of functions can then be used to read/write different - * type of data to/from it. - * @see stream.h for the list of data access functions. - * - * @param size [in] - size of the buffer that will ba allocated to the stream. - * If 0, there will be no buffer attached to the stream. The caller - * then needs to call stream_attach() to link an existing buffer to this stream. - * Caution: calling stream_attach() on a stream with an existing buffer will result - * in this buffer being lost, and possible memory leak. - * - * @return A pointer to an allocated and initialized STREAM structure. - * This pointer need to be deallocated using the stream_free() function. - */ -wStream* stream_new(int size) -{ - wStream* stream; - - stream = malloc(sizeof(wStream)); - ZeroMemory(stream, sizeof(wStream)); - - if (stream != NULL) - { - if (size != 0) - { - size = size > 0 ? size : 0x400; - stream->buffer = (BYTE*) malloc(size); - ZeroMemory(stream->buffer, size); - stream->pointer = stream->buffer; - stream->capacity = size; - } - } - - return stream; -} - -/** - * This function is used to deallocate a stream that was allocated using stream_new(). - * Caution: the buffer linked to the stream will be deallocated in the process. If this buffer was attached - * using the stream_attach() function, the stream_detach() function needs to be called before calling stream_free() - * otherwise it will be freed in the process. - * - * @param stream [in] - Pointer to the STREAM structure that needs to be deallocated. - * This pointer is invalid on return. - */ -void stream_free(wStream* stream) -{ - if (stream != NULL) - { - if (stream->buffer != NULL) - free(stream->buffer); - - free(stream); - } -} - -/** - * This function is used to extend the size of an existing stream. - * It will infact extend the attached buffer, fill the newly allocated region with 0, and reset the current - * stream position. - * If the stream did not have a buffer attached, a new one will be allocated and attached. - * - * @param stream [in/out] pointer to the STREAM structure that needs to be extended. - * @param request_size [in] Number of bytes to add to the existing stream. - * If the value is < the existing size, then the existing size is doubled. - */ -void stream_extend(wStream* stream, int request_size) -{ - int pos; - int original_size; - int increased_size; - - pos = stream_get_pos(stream); - original_size = stream->capacity; - increased_size = (request_size > original_size ? request_size : original_size); - stream->capacity += increased_size; - - if (original_size == 0) - stream->buffer = (BYTE*) malloc(stream->capacity); - else - stream->buffer = (BYTE*) realloc(stream->buffer, stream->capacity); - - memset(stream->buffer + original_size, 0, increased_size); - stream_set_pos(stream, pos); -} diff --git a/winpr/libwinpr/utils/test/CMakeLists.txt b/winpr/libwinpr/utils/test/CMakeLists.txt index cf967be4b..307aae204 100644 --- a/winpr/libwinpr/utils/test/CMakeLists.txt +++ b/winpr/libwinpr/utils/test/CMakeLists.txt @@ -9,6 +9,7 @@ set(${MODULE_PREFIX}_TESTS TestPrint.c TestArrayList.c TestCmdLine.c + TestStreamPool.c TestMessageQueue.c TestMessagePipe.c) diff --git a/winpr/libwinpr/utils/test/TestStreamPool.c b/winpr/libwinpr/utils/test/TestStreamPool.c new file mode 100644 index 000000000..ab8a371e4 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestStreamPool.c @@ -0,0 +1,101 @@ + +#include <winpr/crt.h> +#include <winpr/stream.h> +#include <winpr/collections.h> + +#define BUFFER_SIZE 16384 + +int TestStreamPool(int argc, char* argv[]) +{ + wStream* s[5]; + wStreamPool* pool; + + pool = StreamPool_New(TRUE, BUFFER_SIZE); + + s[0] = StreamPool_Take(pool, 0); + s[1] = StreamPool_Take(pool, 0); + s[2] = StreamPool_Take(pool, 0); + + printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize); + + Stream_Release(s[0]); + Stream_Release(s[1]); + Stream_Release(s[2]); + + printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize); + + s[3] = StreamPool_Take(pool, 0); + s[4] = StreamPool_Take(pool, 0); + + printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize); + + Stream_Release(s[3]); + Stream_Release(s[4]); + + printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize); + + s[2] = StreamPool_Take(pool, 0); + s[3] = StreamPool_Take(pool, 0); + s[4] = StreamPool_Take(pool, 0); + + printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize); + + Stream_AddRef(s[2]); + + Stream_AddRef(s[3]); + Stream_AddRef(s[3]); + + Stream_AddRef(s[4]); + Stream_AddRef(s[4]); + Stream_AddRef(s[4]); + + Stream_Release(s[2]); + Stream_Release(s[2]); + + Stream_Release(s[3]); + Stream_Release(s[3]); + Stream_Release(s[3]); + + Stream_Release(s[4]); + Stream_Release(s[4]); + Stream_Release(s[4]); + Stream_Release(s[4]); + + printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize); + + s[2] = StreamPool_Take(pool, 0); + s[3] = StreamPool_Take(pool, 0); + s[4] = StreamPool_Take(pool, 0); + + printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize); + + StreamPool_AddRef(pool, s[2]->buffer + 1024); + + StreamPool_AddRef(pool, s[3]->buffer + 1024); + StreamPool_AddRef(pool, s[3]->buffer + 1024 * 2); + + StreamPool_AddRef(pool, s[4]->buffer + 1024); + StreamPool_AddRef(pool, s[4]->buffer + 1024 * 2); + StreamPool_AddRef(pool, s[4]->buffer + 1024 * 3); + + printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize); + + StreamPool_Release(pool, s[2]->buffer + 2048); + StreamPool_Release(pool, s[2]->buffer + 2048 * 2); + + StreamPool_Release(pool, s[3]->buffer + 2048); + StreamPool_Release(pool, s[3]->buffer + 2048 * 2); + StreamPool_Release(pool, s[3]->buffer + 2048 * 3); + + StreamPool_Release(pool, s[4]->buffer + 2048); + StreamPool_Release(pool, s[4]->buffer + 2048 * 2); + StreamPool_Release(pool, s[4]->buffer + 2048 * 3); + StreamPool_Release(pool, s[4]->buffer + 2048 * 4); + + printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize); + + StreamPool_Free(pool); + + return 0; +} + diff --git a/winpr/tools/makecert/CMakeLists.txt b/winpr/tools/makecert/CMakeLists.txt index 17b164aae..7663caa18 100644 --- a/winpr/tools/makecert/CMakeLists.txt +++ b/winpr/tools/makecert/CMakeLists.txt @@ -25,7 +25,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(${ZLIB_INCLUDE_DIRS}) include_directories(${OPENSSL_INCLUDE_DIR}) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_library(${MODULE_NAME} STATIC ${${MODULE_PREFIX}_SRCS}) set(${MODULE_PREFIX}_LIBS ${ZLIB_LIBRARIES} diff --git a/winpr/tools/makecert/makecert.c b/winpr/tools/makecert/makecert.c index 0a5538fa9..6b16dc76b 100644 --- a/winpr/tools/makecert/makecert.c +++ b/winpr/tools/makecert/makecert.c @@ -362,6 +362,12 @@ int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, char** return 1; } +int makecert_context_set_output_file_name(MAKECERT_CONTEXT* context, char* name) +{ + context->output_file = _strdup(name); + return 1; +} + int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* path) { FILE* fp; diff --git a/winpr/tools/makecert/makecert.h b/winpr/tools/makecert/makecert.h index b46e5c320..e06154a49 100644 --- a/winpr/tools/makecert/makecert.h +++ b/winpr/tools/makecert/makecert.h @@ -27,6 +27,7 @@ typedef struct _MAKECERT_CONTEXT MAKECERT_CONTEXT; WINPR_API int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv); +WINPR_API int makecert_context_set_output_file_name(MAKECERT_CONTEXT* context, char* name); WINPR_API int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* path); WINPR_API int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* path);