mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
Updated with changes from awakecoding repository.
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -44,14 +44,10 @@
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#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: */
|
||||
|
||||
122
channels/client/channels.h
Normal file
122
channels/client/channels.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channels
|
||||
*
|
||||
* 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_PRIVATE_CLIENT_CHANNELS
|
||||
#define FREERDP_PRIVATE_CLIENT_CHANNELS
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/constants.h>
|
||||
|
||||
#include <freerdp/svc.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/event.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
#include <freerdp/client/drdynvc.h>
|
||||
#include <freerdp/channels/channels.h>
|
||||
|
||||
#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 */
|
||||
135
channels/client/init.c
Normal file
135
channels/client/init.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channels
|
||||
*
|
||||
* 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 "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;
|
||||
}
|
||||
28
channels/client/init.h
Normal file
28
channels/client/init.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channels
|
||||
*
|
||||
* 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_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 */
|
||||
103
channels/client/open.c
Normal file
103
channels/client/open.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channels
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "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;
|
||||
}
|
||||
30
channels/client/open.h
Normal file
30
channels/client/open.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channels
|
||||
*
|
||||
* 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_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 */
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -26,35 +26,15 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/constants.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -20,10 +20,36 @@
|
||||
#ifndef __DRDYNVC_MAIN_H
|
||||
#define __DRDYNVC_MAIN_H
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/svc.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/client/drdynvc.h>
|
||||
#include <freerdp/utils/svc_plugin.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
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -27,70 +27,14 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,65 @@
|
||||
#include <freerdp/dvc.h>
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#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
|
||||
|
||||
|
||||
@@ -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]"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Implementation
|
||||
# FreeRDP cmake build script
|
||||
#
|
||||
# Copyright 2012 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.
|
||||
@@ -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})
|
||||
|
||||
|
||||
589
channels/rdpei/client/rdpei_common.c
Normal file
589
channels/rdpei/client/rdpei_common.c
Normal file
@@ -0,0 +1,589 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Input 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
38
channels/rdpei/client/rdpei_common.h
Normal file
38
channels/rdpei/client/rdpei_common.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Input 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_RDPEI_CLIENT_COMMON_H
|
||||
#define FREERDP_CHANNEL_RDPEI_CLIENT_COMMON_H
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
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 */
|
||||
|
||||
@@ -26,24 +26,38 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/cmdline.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include <winpr/stream.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,36 @@
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
|
||||
#include <freerdp/client/rdpei.h>
|
||||
|
||||
#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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
android:installLocation="auto"
|
||||
package="com.freerdp.freerdpcore"
|
||||
android:versionCode="1"
|
||||
android:versionName="@FREERDP_VERSION_FULL@" >
|
||||
android:versionName="@GIT_REVISION@" >
|
||||
|
||||
<uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" />
|
||||
|
||||
<application>
|
||||
|
||||
@@ -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)
|
||||
|
||||
619
client/Android/FreeRDPCore/jni/android_cliprdr.c
Normal file
619
client/Android/FreeRDPCore/jni/android_cliprdr.c
Normal file
@@ -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 <jni.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/utils/event.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
#include <freerdp/client/cliprdr.h>
|
||||
|
||||
#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, "<body");
|
||||
|
||||
if (in == NULL)
|
||||
{
|
||||
in = (BYTE*) strstr((char*) inbuf, "<BODY");
|
||||
}
|
||||
/* StartHTML */
|
||||
snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf));
|
||||
memcpy(outbuf + 23, num, 10);
|
||||
if (in == NULL)
|
||||
{
|
||||
strcat((char*) outbuf, "<HTML><BODY>");
|
||||
}
|
||||
strcat((char*) outbuf, "<!--StartFragment-->");
|
||||
/* 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, "<!--EndFragment-->");
|
||||
if (in == NULL)
|
||||
{
|
||||
strcat((char*) outbuf, "</BODY></HTML>");
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <Cocoa/Cocoa.h>
|
||||
#import "MRDPView.h"
|
||||
#ifndef __ANDROID_CLIPRDR_H__
|
||||
#define __ANDROID_CLIPRDR_H__
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
#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__ */
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -16,21 +16,23 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <sys/select.h>
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/channels/channels.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
#include <freerdp/client/cmdline.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/utils/event.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
|
||||
#include <android/bitmap.h>
|
||||
#include <machine/cpu-features.h>
|
||||
|
||||
#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, "<init>", "(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, "<init>", "()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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
211
client/Android/FreeRDPCore/jni/android_jni_utils.c
Normal file
211
client/Android/FreeRDPCore/jni/android_jni_utils.c
Normal file
@@ -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 <locale.h>
|
||||
#include <freerdp/channels/channels.h>
|
||||
|
||||
#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, "<init>", "(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, "<init>", "()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;
|
||||
}
|
||||
|
||||
34
client/Android/FreeRDPCore/jni/android_jni_utils.h
Normal file
34
client/Android/FreeRDPCore/jni/android_jni_utils.h
Normal file
@@ -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 <jni.h>
|
||||
|
||||
#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_ */
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<string name="section_bookmarks">Conexión Manual</string>
|
||||
<string name="section_active_sessions">Sesiones Activas</string>
|
||||
<!-- Search strings -->
|
||||
<string name="search_hint">Connectarse a iWinCloud</string>
|
||||
<string name="search_hint">Connect to Computer</string>
|
||||
<!-- List placeholder labels -->
|
||||
<string name="list_placeholder_login">Login</string>
|
||||
<string name="list_placeholder_no_servers">No hay escritorios virtuales</string>
|
||||
@@ -37,13 +37,13 @@
|
||||
<string name="list_placeholder_connection_error">Conexión perdida</string>
|
||||
<string name="list_placeholder_wrong_password">Contraseña equivocada</string>
|
||||
<string name="list_placeholder_invalid_username">Usuario Invalido</string>
|
||||
<string name="list_placeholder_add_bookmark">Agregar escritorio virtual de iWinCloud</string>
|
||||
<string name="list_placeholder_add_bookmark">Add Connection</string>
|
||||
<!-- Bookmark settings strings -->
|
||||
<string name="settings_cat_host">Host</string>
|
||||
<string name="settings_label">Su nombre</string>
|
||||
<string name="settings_hostname">IP</string>
|
||||
<string name="settings_port">Puerto</string>
|
||||
<string name="settings_cat_credentials">Credenciales de iWinCloud</string>
|
||||
<string name="settings_cat_credentials">Credenciales</string>
|
||||
<string name="settings_credentials">Credenciales</string>
|
||||
<string name="settings_username">Usuario</string>
|
||||
<string name="settings_password">Contraseña</string>
|
||||
@@ -105,6 +105,10 @@
|
||||
<string name="settings_enable_3g_settings">Configuracion 3G</string>
|
||||
<string name="settings_screen_3g">Pantalla 3G</string>
|
||||
<string name="settings_performance_3g">Rendimiento 3G</string>
|
||||
<string name="settings_cat_gateway">Gateway</string>
|
||||
<string name="settings_enable_gateway_settings">Enable Gateway</string>
|
||||
<string name="settings_gateway_settings">Gateway Settings</string>
|
||||
<string name="settings_redirect_sdcard">Redirect SDCard</string>
|
||||
<string name="settings_security">Seguridad</string>
|
||||
<string-array name="security_array">
|
||||
<item>Automatico</item>
|
||||
@@ -141,28 +145,28 @@
|
||||
<!-- Activity titles -->
|
||||
<string name="title_bookmark_settings">Configuración de la conexión</string>
|
||||
<string name="title_application_settings">Configuración</string>
|
||||
<string name="title_home">iWinCloud - iWinCloud para Android</string>
|
||||
<string name="title_home">aFreeRDP - aFreeRDP para Android</string>
|
||||
<string name="title_create_shortcut">Conexiones RDP</string>
|
||||
<string name="title_help">Ayuda</string>
|
||||
<string name="title_about">Sobre</string>
|
||||
<!-- Error message strings -->
|
||||
<string name="error_bookmark_incomplete_title">Cancelar sin guardar?</string>
|
||||
<string name="error_bookmark_incomplete">Pulse el botón "Cancelar" para abortar! \ NPulse "Continuar" para especificar los campos obligatorios!</string>
|
||||
<string name="error_connection_failure">No se pudo establecer una conexión con iWinCloud!</string>
|
||||
<string name="error_connection_failure">Failed to establish a connection to the server!</string>
|
||||
<!-- Info message strings -->
|
||||
<string name="info_capabilities_changed">Los ajustes de pantalla se han cambiado porque el escritorio virtual no es compatible con la configuración especificada!</string>
|
||||
<string name="info_reset_success">Eliminado el cache del certificado!</string>
|
||||
<string name="info_reset_failed">No se pudo borrar el caché del certificado!</string>
|
||||
<!-- Dialog strings -->
|
||||
<string name="dlg_title_verify_certificate">verificar el certificado</string>
|
||||
<string name="dlg_msg_verify_certificate">La identidad de su escritorio de iWinCloud debe ser verificada. ¿Desea conectarse de todos modos?</string>
|
||||
<string name="dlg_msg_verify_certificate">The identity of the remote computer cannot be verified. Do you want to connect anyway?</string>
|
||||
<string name="dlg_title_credentials">Por favor, introduzca sus credenciales</string>
|
||||
<string name="dlg_title_create_shortcut">Crear acceso directo</string>
|
||||
<string name="dlg_msg_create_shortcut">Nombre corto:</string>
|
||||
<string name="dlg_msg_connecting">Conectando ...</string>
|
||||
<string name="dlg_msg_logging_in">Ingresando a ...</string>
|
||||
<string name="dlg_title_about">Sobre iWinCloud</string>
|
||||
<string name="dlg_msg_about">Version: %1$s\n\u00A9 2012 iWinCloud LLc</string>
|
||||
<string name="dlg_title_about">Sobre aFreeRDP</string>
|
||||
<string name="dlg_msg_about">Version: %1$s\n\u00A9 2012 Thinstuff Technologies GmbH</string>
|
||||
<string name="dlg_title_create_bookmark_after_qc">Guardar configuración de conexión?</string>
|
||||
<string name="dlg_msg_create_bookmark_after_qc">La configuración de conexión no se han guardado! ¿Quieres guardarlos?</string>
|
||||
<string name="dlg_title_save_bookmark">Guardar Conexión</string>
|
||||
|
||||
@@ -104,6 +104,10 @@
|
||||
<string name="settings_enable_3g_settings">"Paramètres 3G"</string>
|
||||
<string name="settings_screen_3g">"Écran 3G"</string>
|
||||
<string name="settings_performance_3g">"Performance 3G"</string>
|
||||
<string name="settings_cat_gateway">Gateway</string>
|
||||
<string name="settings_enable_gateway_settings">Enable Gateway</string>
|
||||
<string name="settings_gateway_settings">Gateway Settings</string>
|
||||
<string name="settings_redirect_sdcard">"Redirect SDCard"</string>
|
||||
<string name="settings_security">"Securité"</string>
|
||||
<string-array name="security_array">
|
||||
<item>"Automatique"</item>
|
||||
|
||||
175
client/Android/FreeRDPCore/res/values-nl/strings.xml
Normal file
175
client/Android/FreeRDPCore/res/values-nl/strings.xml
Normal file
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<resources>
|
||||
<!-- Button labels -->
|
||||
<string name="yes">Ja</string>
|
||||
<string name="no">Nee</string>
|
||||
<string name="cancel">Annuleren</string>
|
||||
<string name="cont">Doorgaan</string>
|
||||
<string name="login">Inloggen</string>
|
||||
<string name="logout">Uitloggen</string>
|
||||
<!-- Home menu items -->
|
||||
<string name="menu_exit">Sluiten</string>
|
||||
<string name="menu_about">Over</string>
|
||||
<string name="menu_help">Help</string>
|
||||
<string name="menu_new_bookmark">Nieuwe connectie</string>
|
||||
<string name="menu_app_settings">Instellingen</string>
|
||||
<!-- Bookmark menu items -->
|
||||
<string name="menu_title_bookmark">Connectie</string>
|
||||
<string name="menu_connect">Verbinden</string>
|
||||
<string name="menu_edit">Bewerken</string>
|
||||
<string name="menu_delete">Verwijderen</string>
|
||||
<!-- Session menu items -->
|
||||
<string name="menu_sys_keyboard">Toetsenbord</string>
|
||||
<string name="menu_ext_keyboard">Functietoetsen</string>
|
||||
<string name="menu_touch_pointer">Touch Pointer</string>
|
||||
<string name="menu_home">home</string>
|
||||
<string name="menu_disconnect">Verbinding verbreken</string>
|
||||
<!-- List section headers -->
|
||||
<string name="section_bookmarks">Handmatige connecties</string>
|
||||
<string name="section_active_sessions">Actieve sessies</string>
|
||||
<!-- Search strings -->
|
||||
<string name="search_hint">Verbinden met computer</string>
|
||||
<!-- List placeholder labels -->
|
||||
<string name="list_placeholder_login">Login</string>
|
||||
<string name="list_placeholder_no_servers">Geen servers</string>
|
||||
<string name="list_placeholder_connecting">Verbinden ...</string>
|
||||
<string name="list_placeholder_disconnecting">Verbinding verbreken ...</string>
|
||||
<string name="list_placeholder_connection_error">Connectie verloren</string>
|
||||
<string name="list_placeholder_wrong_password">Ongeldig wachtwoord</string>
|
||||
<string name="list_placeholder_invalid_username">Ongeldige gebruikersnaam</string>
|
||||
<string name="list_placeholder_add_bookmark">Connectie toevoegen</string>
|
||||
<!-- Bookmark settings strings -->
|
||||
<string name="settings_cat_host">Host</string>
|
||||
<string name="settings_label">Label</string>
|
||||
<string name="settings_hostname">Host</string>
|
||||
<string name="settings_port">Poort</string>
|
||||
<string name="settings_cat_credentials">Inloggegevens</string>
|
||||
<string name="settings_credentials">Inloggegevens</string>
|
||||
<string name="settings_username">Gebruikersnaam</string>
|
||||
<string name="settings_password">Wachtwoord</string>
|
||||
<string name="settings_domain">Domein</string>
|
||||
<string name="settings_cat_settings">Instellingen</string>
|
||||
<string name="settings_screen">Scherm</string>
|
||||
<string name="settings_cat_screen">Scherminstellingen</string>
|
||||
<string name="settings_colors">Kleuren</string>
|
||||
<string-array name="colors_array">
|
||||
<item>Hoge kleuren (16 Bit)</item>
|
||||
<item>Ware kleuren (24 Bit)</item>
|
||||
<item>Hoogste kwaliteit (32 Bit)</item>
|
||||
</string-array>
|
||||
<string-array name="colors_values_array">
|
||||
<item>16</item>
|
||||
<item>24</item>
|
||||
<item>32</item>
|
||||
</string-array>
|
||||
<string name="settings_resolution">Resolutie</string>
|
||||
<string name="resolution_automatic">Automatisch</string>
|
||||
<string name="resolution_custom">Aangepast</string>
|
||||
<string-array name="resolutions_array">
|
||||
<item>Automatisch</item>
|
||||
<item>Aangepast</item>
|
||||
<item>640x480</item>
|
||||
<item>720x480</item>
|
||||
<item>800x600</item>
|
||||
<item>1024x768</item>
|
||||
<item>1280x1024</item>
|
||||
<item>1440x900</item>
|
||||
<item>1920x1080</item>
|
||||
<item>1920x1200</item>
|
||||
</string-array>
|
||||
<string-array name="resolutions_values_array">
|
||||
<item>Automatisch</item>
|
||||
<item>Aangepast</item>
|
||||
<item>640x480</item>
|
||||
<item>720x480</item>
|
||||
<item>800x600</item>
|
||||
<item>1024x768</item>
|
||||
<item>1280x1024</item>
|
||||
<item>1440x900</item>
|
||||
<item>1920x1080</item>
|
||||
<item>1920x1200</item>
|
||||
</string-array>
|
||||
<string name="settings_width">Breedte</string>
|
||||
<string name="settings_height">Hoogte</string>
|
||||
<string name="settings_performance">Prestatie</string>
|
||||
<string name="settings_cat_performance">Prestatieinstellingen</string>
|
||||
<string name="settings_perf_remotefx">RemoteFX</string>
|
||||
<string name="settings_perf_wallpaper">Bureaublad achtergrond</string>
|
||||
<string name="settings_perf_font_smoothing">Lettertype Smoothing</string>
|
||||
<string name="settings_perf_desktop_composition">Bureaublad compositie</string>
|
||||
<string name="settings_perf_full_window_drag">Inhoud van het venster weergeven tijdens slepen</string>
|
||||
<string name="settings_perf_menu_animation">Menu animatie</string>
|
||||
<string name="settings_perf_theming">Visuele stijlen</string>
|
||||
<string name="settings_advanced">Geavanceerd</string>
|
||||
<string name="settings_cat_advanced">Geavanceerde instellingen</string>
|
||||
<string name="settings_enable_3g_settings">3G Instellingen</string>
|
||||
<string name="settings_screen_3g">3G Scherm</string>
|
||||
<string name="settings_performance_3g">3G Prestatie</string>
|
||||
<string name="settings_security">Beveiliging</string>
|
||||
<string-array name="security_array">
|
||||
<item>Automatisch</item>
|
||||
<item>RDP</item>
|
||||
<item>TLS</item>
|
||||
<item>NLA</item>
|
||||
</string-array>
|
||||
<string-array name="security_values_array">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
</string-array>
|
||||
<string name="settings_remote_program">Extern programma</string>
|
||||
<string name="settings_work_dir">Werkmap</string>
|
||||
<string name="settings_console_mode">Console modus</string>
|
||||
<!-- App settings strings -->
|
||||
<string name="settings_password_present">*******</string>
|
||||
<string name="settings_password_empty">Niet ingesteld</string>
|
||||
<string name="settings_cat_ui">Gebruikersinterface</string>
|
||||
<string name="settings_ui_hide_status_bar">Verberg statusbalk</string>
|
||||
<string name="settings_ui_hide_zoom_controls">Verberg Zoom Controls</string>
|
||||
<string name="settings_ui_swap_mouse_buttons">Wissel muisknoppen</string>
|
||||
<string name="settings_ui_invert_scrolling">Scrollen omkeren</string>
|
||||
<string name="settings_ui_auto_scroll_touchpointer">Touch Pointer Auto Scroll</string>
|
||||
<string name="settings_ui_ask_on_exit">Toon dialoog bij sluiten</string>
|
||||
<string name="settings_cat_power">Energiebesparing</string>
|
||||
<string name="settings_power_disconnect_timeout">Sluit inactieve ingen</string>
|
||||
<string name="settings_cat_security">Beveiliging</string>
|
||||
<string name="settings_security_accept_certificates">Accepteer alle certificaten</string>
|
||||
<string name="settings_security_clear_certificate_cache">Certificaat cache opschonen</string>
|
||||
<string name="settings_description_after_minutes">na %1$d minuten</string>
|
||||
<string name="settings_description_disabled">Uitgeschakeld</string>
|
||||
<!-- Activity titles -->
|
||||
<string name="title_bookmark_settings">Connectie instellingen</string>
|
||||
<string name="title_application_settings">Instellingen</string>
|
||||
<string name="title_home">aFreeRDP - FreeRDP voor Android</string>
|
||||
<string name="title_create_shortcut">RDP verbinding</string>
|
||||
<string name="title_help">Help</string>
|
||||
<string name="title_about">Over</string>
|
||||
<!-- Error message strings -->
|
||||
<string name="error_bookmark_incomplete_title">Annuleren zonder opslaan?</string>
|
||||
<string name="error_bookmark_incomplete">Druk op "Annuleren" om af te breken!\nKlik op "Doorgaan" om de verplichte velden op te geven!</string>
|
||||
<string name="error_connection_failure">Fout bij het verbinden met de server!</string>
|
||||
<!-- Info message strings -->
|
||||
<string name="info_capabilities_changed">De scherm instellingen zijn veranderd omdat de server de door u opgegeven instellingen niet ondersteunt!</string>
|
||||
<string name="info_reset_success">Certificaat cache is verwijderd!</string>
|
||||
<string name="info_reset_failed">Fout bij het verwijderderen van certificaat cache!</string>
|
||||
<!-- Dialog strings -->
|
||||
<string name="dlg_title_verify_certificate">Controleer certificaat</string>
|
||||
<string name="dlg_msg_verify_certificate">De identiteit van de externe computer niet kan worden geverifieerd. Wilt u toch verbinden?</string>
|
||||
<string name="dlg_title_credentials">Vul uw gegevens in</string>
|
||||
<string name="dlg_title_create_shortcut">Snelkoppeling maken</string>
|
||||
<string name="dlg_msg_create_shortcut">Snelkoppeling naam:</string>
|
||||
<string name="dlg_msg_connecting">Verbinden ...</string>
|
||||
<string name="dlg_msg_logging_in">Aanmelden ...</string>
|
||||
<string name="dlg_title_about">Over aFreeRDP</string>
|
||||
<string name="dlg_msg_about">Versie: %1$s\n\u00A9 2012 Thinstuff Technologies GmbH</string>
|
||||
<string name="dlg_title_create_bookmark_after_qc">Connectie instellingen opslaan?</string>
|
||||
<string name="dlg_msg_create_bookmark_after_qc">Uw connectie instellingen zijn niet opgeslagen! Wilt u deze opslaan?</string>
|
||||
<string name="dlg_title_save_bookmark">Verbinding opslaan?</string>
|
||||
<string name="dlg_save_bookmark">Wilt u alle wijzigingen opslaan?</string>
|
||||
<string name="dlg_dont_show_again">Niet opnieuw vragen</string>
|
||||
<string name="dlg_title_exit">Toepassing sluiten?</string>
|
||||
<string name="dlg_msg_exit">Weet u zeker dat u de applicatie wilt sluiten?</string>
|
||||
<string name="dlg_title_clear_cert_cache">Verwijder certificaten?</string>
|
||||
<string name="dlg_msg_clear_cert_cache">Weet u zeker dat u al uw cache certificaten wilt verwijderen?</string>
|
||||
</resources>
|
||||
@@ -105,6 +105,10 @@
|
||||
<string name="settings_enable_3g_settings">3G Settings</string>
|
||||
<string name="settings_screen_3g">3G Screen</string>
|
||||
<string name="settings_performance_3g">3G Performance</string>
|
||||
<string name="settings_cat_gateway">Gateway</string>
|
||||
<string name="settings_enable_gateway_settings">Enable Gateway</string>
|
||||
<string name="settings_gateway_settings">Gateway Settings</string>
|
||||
<string name="settings_redirect_sdcard">Redirect SDCard</string>
|
||||
<string name="settings_security">Security</string>
|
||||
<string-array name="security_array">
|
||||
<item>Automatic</item>
|
||||
|
||||
@@ -12,8 +12,15 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<PreferenceCategory android:title="Advanced">
|
||||
|
||||
<CheckBoxPreference android:key="bookmark.enable_3g_settings" android:title="@string/settings_enable_3g_settings" />
|
||||
|
||||
<CheckBoxPreference android:key="bookmark.enable_gateway_settings" android:title="@string/settings_enable_gateway_settings" />
|
||||
<PreferenceScreen android:key="bookmark.gateway_settings" android:title="@string/settings_gateway_settings">
|
||||
<intent android:action="android.intent.action.VIEW"
|
||||
android:targetPackage="*"
|
||||
android:targetClass="com.freerdp.freerdpcore.presentation.BookmarkActivity"
|
||||
android:data="preferences://gateway_settings" />
|
||||
</PreferenceScreen>
|
||||
|
||||
<CheckBoxPreference android:key="bookmark.enable_3g_settings" android:title="@string/settings_enable_3g_settings" />
|
||||
<PreferenceScreen android:key="bookmark.screen_3g" android:title="@string/settings_screen_3g">
|
||||
<intent android:action="android.intent.action.VIEW"
|
||||
android:targetPackage="*"
|
||||
@@ -28,6 +35,7 @@
|
||||
android:data="preferences://performance_flags_3g" />
|
||||
</PreferenceScreen>
|
||||
|
||||
<CheckBoxPreference android:key="bookmark.redirect_sdcard" android:title="@string/settings_redirect_sdcard"/>
|
||||
<com.freerdp.freerdpcore.utils.IntListPreference android:key="bookmark.security" android:title="@string/settings_security" android:entries="@array/security_array" android:entryValues="@array/security_values_array" />
|
||||
<EditTextPreference android:key="bookmark.remote_program" android:title="@string/settings_remote_program" android:summary="notepad.exe"/>
|
||||
<EditTextPreference android:key="bookmark.work_dir" android:title="@string/settings_work_dir"/>
|
||||
|
||||
20
client/Android/FreeRDPCore/res/xml/gateway_settings.xml
Normal file
20
client/Android/FreeRDPCore/res/xml/gateway_settings.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
Credential Settings Layout
|
||||
|
||||
Copyright 2013 Felix Long
|
||||
|
||||
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/.
|
||||
*/
|
||||
-->
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:freerdp="http://schemas.android.com/apk/res-auto">
|
||||
<PreferenceCategory android:title="@string/settings_cat_gateway">
|
||||
<EditTextPreference android:key="bookmark.gateway_hostname" android:title="@string/settings_hostname" android:summary="Name or address of the target computer"/>
|
||||
<com.freerdp.freerdpcore.utils.IntEditTextPreference android:key="bookmark.gateway_port" android:title="@string/settings_port" android:summary="Gateway Port on the target computer" android:numeric="integer" android:inputType="number" freerdp:bounds_min="10" freerdp:bounds_max="65535" freerdp:bounds_default="443" />
|
||||
<EditTextPreference android:key="bookmark.gateway_username" android:title="@string/settings_username"/>
|
||||
<EditTextPreference android:key="bookmark.gateway_password" android:title="@string/settings_password" android:inputType="textPassword" />
|
||||
<EditTextPreference android:key="bookmark.gateway_domain" android:title="@string/settings_domain" android:summary="Optional"/>
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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", ""));
|
||||
|
||||
@@ -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<GatewaySettings> CREATOR = new Parcelable.Creator<GatewaySettings>()
|
||||
{
|
||||
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<ManualBookmark> CREATOR = new Parcelable.Creator<ManualBookmark>()
|
||||
{
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")));
|
||||
|
||||
@@ -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<String> 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<String> GetColumns(SQLiteDatabase db, String tableName) {
|
||||
List<String> ar = null;
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 1", null);
|
||||
if (c != null) {
|
||||
ar = new ArrayList<String>(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<String> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.<ManualBookmark>get().getEnableGatewaySettings())
|
||||
{
|
||||
ManualBookmark.GatewaySettings gatewaySettings = bookmark.<ManualBookmark>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();
|
||||
|
||||
@@ -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<String> 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")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:installLocation="auto"
|
||||
package="com.freerdp.afreerdp"
|
||||
android:versionCode="1"
|
||||
android:versionName="@FREERDP_VERSION_FULL@" >
|
||||
android:versionCode="3"
|
||||
android:versionName="@GIT_REVISION@" >
|
||||
|
||||
<uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8"/>
|
||||
<supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" />
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-8
|
||||
target=android-11
|
||||
android.library.reference.1=../FreeRDPCore
|
||||
manifestmerger.enabled=true
|
||||
|
||||
7
client/Android/aFreeRDP/res/values-fr/strings.xml
Normal file
7
client/Android/aFreeRDP/res/values-fr/strings.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<resources>
|
||||
<string name="app_title">aFreeRDP</string>
|
||||
<!-- Search strings -->
|
||||
<string name="search_label">aFreeRDP</string>
|
||||
<string name="search_settings_description">L\'ordinateur distant</string>
|
||||
</resources>
|
||||
1
client/Mac/.gitignore
vendored
1
client/Mac/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
*.app
|
||||
*.framework
|
||||
|
||||
|
||||
@@ -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
|
||||
"$<TARGET_FILE:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
COMMENT "Copying ${LIB} to output directory"
|
||||
COMMAND install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>" "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>" "${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 "$<TARGET_SONAME_FILE:${LIB}>" "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>" "${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 "$<TARGET_SONAME_FILE:${LIB}>" "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>" "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${DEST}>"
|
||||
COMMENT Setting install name for ${LIB} in module ${DEST}
|
||||
)
|
||||
|
||||
# COMMAND "${CMAKE_COMMAND}" -E echo install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>" #"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>" #"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${DEST}>"
|
||||
# )
|
||||
|
||||
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()
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string></string>
|
||||
<string>English</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>FreeRDP</string>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>FreeRDP.Mac</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
@@ -15,20 +13,14 @@
|
||||
<key>CFBundleName</key>
|
||||
<string></string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string></string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2012 __MyCompanyName__. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -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 <Cocoa/Cocoa.h>
|
||||
|
||||
#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
|
||||
@@ -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
|
||||
|
||||
@@ -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 <Cocoa/Cocoa.h>
|
||||
|
||||
@interface MRDPRailWindow : NSWindow
|
||||
|
||||
@end
|
||||
@@ -19,8 +19,12 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
|
||||
@@ -51,9 +51,113 @@
|
||||
|
||||
#include <freerdp/constants.h>
|
||||
|
||||
#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
|
||||
|
||||
@@ -20,7 +20,15 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@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;
|
||||
|
||||
@@ -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="</path/to/your/staging/dir>"
|
||||
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 <Cocoa/Cocoa.h>
|
||||
#import "MRDPView.h"
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@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
|
||||
|
||||
22
client/Mac/cli/AppDelegate.h
Normal file
22
client/Mac/cli/AppDelegate.h
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// MacClient2
|
||||
//
|
||||
// Created by Benoît et Kathy on 2013-05-08.
|
||||
//
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <MacFreeRDP-library/MRDPView.h>
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
{
|
||||
@public
|
||||
NSWindow* window;
|
||||
MRDPView* mrdpView;
|
||||
}
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
@property (assign) IBOutlet MRDPView *mrdpView;
|
||||
|
||||
@end
|
||||
32
client/Mac/cli/AppDelegate.m
Normal file
32
client/Mac/cli/AppDelegate.m
Normal file
@@ -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
|
||||
127
client/Mac/cli/CMakeLists.txt
Normal file
127
client/Mac/cli/CMakeLists.txt
Normal file
@@ -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")
|
||||
34
client/Mac/cli/Info.plist
Normal file
34
client/Mac/cli/Info.plist
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string></string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>FreeRDP</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>FreeRDP.Mac</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string></string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string></string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2012 __MyCompanyName__. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
32
client/Mac/cli/MacClient2-Info.plist
Normal file
32
client/Mac/cli/MacClient2-Info.plist
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>awakecoding.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
7
client/Mac/cli/MacClient2-Prefix.pch
Normal file
7
client/Mac/cli/MacClient2-Prefix.pch
Normal file
@@ -0,0 +1,7 @@
|
||||
//
|
||||
// Prefix header for all source files of the 'MacClient2' target in the 'MacClient2' project
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
@@ -2,10 +2,10 @@
|
||||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1070</int>
|
||||
<string key="IBDocument.SystemVersion">12C60</string>
|
||||
<string key="IBDocument.SystemVersion">12D78</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.34</string>
|
||||
<string key="IBDocument.HIToolboxVersion">625.00</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.37</string>
|
||||
<string key="IBDocument.HIToolboxVersion">626.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="NS.object.0">3084</string>
|
||||
@@ -375,7 +375,7 @@
|
||||
<reference key="source" ref="976324537"/>
|
||||
<reference key="destination" ref="467991374"/>
|
||||
</object>
|
||||
<int key="connectionID">565</int>
|
||||
<int key="connectionID">569</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
@@ -383,7 +383,7 @@
|
||||
<reference key="source" ref="976324537"/>
|
||||
<reference key="destination" ref="972006081"/>
|
||||
</object>
|
||||
<int key="connectionID">567</int>
|
||||
<int key="connectionID">570</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
@@ -736,7 +736,7 @@
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">568</int>
|
||||
<int key="maxID">570</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
@@ -770,6 +770,14 @@
|
||||
<string key="minorKey">./Classes/MRDPView.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">NSLayoutConstraint</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
29
client/Mac/cli/en.lproj/Credits.rtf
Normal file
29
client/Mac/cli/en.lproj/Credits.rtf
Normal file
@@ -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\
|
||||
}
|
||||
2
client/Mac/cli/en.lproj/InfoPlist.strings
Normal file
2
client/Mac/cli/en.lproj/InfoPlist.strings
Normal file
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
3299
client/Mac/cli/en.lproj/MainMenu.xib
Normal file
3299
client/Mac/cli/en.lproj/MainMenu.xib
Normal file
File diff suppressed because it is too large
Load Diff
16
client/Mac/cli/main.m
Normal file
16
client/Mac/cli/main.m
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// main.m
|
||||
// MacClient2
|
||||
//
|
||||
// Created by Benoît et Kathy on 2013-05-08.
|
||||
//
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <MacFreeRDP-library/MRDPView.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
[MRDPView class];
|
||||
return NSApplicationMain(argc, (const char **)argv);
|
||||
}
|
||||
2
client/Mac/en.lproj/InfoPlist.strings
Normal file
2
client/Mac/en.lproj/InfoPlist.strings
Normal file
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user