Updated with changes from awakecoding repository.

This commit is contained in:
Benoit LeBlanc
2013-05-31 14:54:15 -04:00
313 changed files with 18844 additions and 7638 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View 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_ */

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,6 +8,6 @@
# project structure.
# Project target.
target=android-8
target=android-11
android.library.reference.1=../FreeRDPCore
manifestmerger.enabled=true

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

View File

@@ -1,2 +1,3 @@
*.app
*.framework

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View 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

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

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

View 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

View File

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

View 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\
}

View File

@@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

File diff suppressed because it is too large Load Diff

16
client/Mac/cli/main.m Normal file
View 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);
}

View 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