Merge pull request #1574 from awakecoding/master
Refactoring, Robustness, Valgrind Fixes, WinPR
This commit is contained in:
commit
2e28621802
4
.gitignore
vendored
4
.gitignore
vendored
@ -15,8 +15,10 @@ DartConfiguration.tcl
|
||||
CMakeCPackOptions.cmake
|
||||
_CPack_Packages
|
||||
LICENSE.txt
|
||||
external/*
|
||||
/external/*
|
||||
!external/README
|
||||
*Config.cmake
|
||||
*ConfigVersion.cmake
|
||||
include/freerdp/version.h
|
||||
|
||||
*.a.objlist.cmake
|
||||
|
@ -51,6 +51,7 @@ include(ComplexLibrary)
|
||||
include(FeatureSummary)
|
||||
include(CheckCCompilerFlag)
|
||||
include(GNUInstallDirsWrapper)
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
# Soname versioning
|
||||
set(FREERDP_VERSION_MAJOR "1")
|
||||
@ -166,7 +167,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Weverything -Wno-unused-parameter")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-macros -Wno-padded")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-c11-extensions -Wno-gnu")
|
||||
if(WITH_SSE2)
|
||||
@ -552,6 +553,31 @@ if(WITH_SERVER)
|
||||
add_subdirectory(server)
|
||||
endif()
|
||||
|
||||
# Exporting
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_GREATER "2.8.10")
|
||||
|
||||
export(PACKAGE freerdp)
|
||||
|
||||
set(FREERDP_CMAKE_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/FreeRDP")
|
||||
|
||||
set(FREERDP_INCLUDE_DIR "include")
|
||||
set(FREERDP_MONOLITHIC_BUILD ${MONOLITHIC_BUILD})
|
||||
|
||||
configure_package_config_file(FreeRDPConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FreeRDPConfig.cmake
|
||||
INSTALL_DESTINATION ${FREERDP_CMAKE_INSTALL_DIR}
|
||||
PATH_VARS FREERDP_INCLUDE_DIR FREERDP_MONOLITHIC_BUILD)
|
||||
|
||||
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/FreeRDPConfigVersion.cmake
|
||||
VERSION ${FREERDP_VERSION} COMPATIBILITY SameMajorVersion)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FreeRDPConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/FreeRDPConfigVersion.cmake
|
||||
DESTINATION ${FREERDP_CMAKE_INSTALL_DIR})
|
||||
|
||||
install(EXPORT FreeRDPTargets DESTINATION ${FREERDP_CMAKE_INSTALL_DIR})
|
||||
|
||||
endif()
|
||||
|
||||
# Packaging
|
||||
|
||||
set(CMAKE_CPACK_INCLUDE_FILE "CMakeCPack.cmake")
|
||||
|
11
FreeRDPConfig.cmake.in
Normal file
11
FreeRDPConfig.cmake.in
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set(FreeRDP_VERSION_MAJOR "@FREERDP_VERSION_MAJOR@")
|
||||
set(FreeRDP_VERSION_MINOR "@FREERDP_VERSION_MINOR@")
|
||||
set(FreeRDP_VERSION_REVISION "@FREERDP_VERSION_REVISION@")
|
||||
set(FreeRDP_MONOLITHIC_BUILD "@FREERDP_MONOLITHIC_BUILD@")
|
||||
|
||||
set_and_check(FreeRDP_INCLUDE_DIR "@PACKAGE_FREERDP_INCLUDE_DIR@")
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/FreeRDPTargets.cmake")
|
@ -34,9 +34,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
|
@ -39,3 +39,7 @@ target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT FreeRDPTargets)
|
||||
endif()
|
||||
|
@ -17,8 +17,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __AUDIN_MAIN_H
|
||||
#define __AUDIN_MAIN_H
|
||||
#ifndef FREERDP_AUDIN_CLIENT_MAIN_H
|
||||
#define FREERDP_AUDIN_CLIENT_MAIN_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@ -28,6 +28,7 @@
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/client/audin.h>
|
||||
|
||||
#ifdef WITH_DEBUG_DVC
|
||||
#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__)
|
||||
@ -35,44 +36,5 @@
|
||||
#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
typedef BOOL (*AudinReceive) (BYTE* data, int size, void* user_data);
|
||||
|
||||
typedef struct audin_format audinFormat;
|
||||
struct audin_format
|
||||
{
|
||||
UINT16 wFormatTag;
|
||||
UINT16 nChannels;
|
||||
UINT32 nSamplesPerSec;
|
||||
UINT16 nBlockAlign;
|
||||
UINT16 wBitsPerSample;
|
||||
UINT16 cbSize;
|
||||
BYTE* data;
|
||||
};
|
||||
|
||||
typedef struct _IAudinDevice IAudinDevice;
|
||||
struct _IAudinDevice
|
||||
{
|
||||
void (*Open) (IAudinDevice* devplugin, AudinReceive receive, void* user_data);
|
||||
BOOL (*FormatSupported) (IAudinDevice* devplugin, audinFormat* format);
|
||||
void (*SetFormat) (IAudinDevice* devplugin, audinFormat* format, UINT32 FramesPerPacket);
|
||||
void (*Close) (IAudinDevice* devplugin);
|
||||
void (*Free) (IAudinDevice* devplugin);
|
||||
};
|
||||
|
||||
#define AUDIN_DEVICE_EXPORT_FUNC_NAME "freerdp_audin_client_subsystem_entry"
|
||||
|
||||
typedef void (*PREGISTERAUDINDEVICE)(IWTSPlugin* plugin, IAudinDevice* device);
|
||||
|
||||
struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS
|
||||
{
|
||||
IWTSPlugin* plugin;
|
||||
PREGISTERAUDINDEVICE pRegisterAudinDevice;
|
||||
ADDIN_ARGV* args;
|
||||
};
|
||||
typedef struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS FREERDP_AUDIN_DEVICE_ENTRY_POINTS;
|
||||
typedef FREERDP_AUDIN_DEVICE_ENTRY_POINTS* PFREERDP_AUDIN_DEVICE_ENTRY_POINTS;
|
||||
|
||||
typedef int (*PFREERDP_AUDIN_DEVICE_ENTRY)(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints);
|
||||
|
||||
#endif /* __AUDIN_MAIN_H */
|
||||
#endif /* FREERDP_AUDIN_CLIENT_MAIN_H */
|
||||
|
||||
|
@ -39,6 +39,4 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${OPENSLES_LIBRARIES})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
@ -36,6 +36,4 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PULSE_LIBRARY})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
@ -29,4 +29,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MODULE freerdp
|
||||
MODULES freerdp-codec freerdp-utils)
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server")
|
||||
|
@ -74,12 +74,12 @@ CHANNEL_INIT_DATA g_ChannelInitData;
|
||||
static wArrayList* g_ChannelsList = NULL;
|
||||
|
||||
/* To generate unique sequence for all open handles */
|
||||
int g_open_handle_sequence;
|
||||
int g_open_handle_sequence = 1;
|
||||
|
||||
/* For locking the global resources */
|
||||
static HANDLE g_mutex_init;
|
||||
static CRITICAL_SECTION g_channels_lock;
|
||||
|
||||
rdpChannels* freerdp_channels_find_by_open_handle(int open_handle, int* pindex)
|
||||
rdpChannels* freerdp_channels_find_by_open_handle(int OpenHandle, int* pindex)
|
||||
{
|
||||
int i, j;
|
||||
BOOL found = FALSE;
|
||||
@ -94,7 +94,7 @@ rdpChannels* freerdp_channels_find_by_open_handle(int open_handle, int* pindex)
|
||||
{
|
||||
for (j = 0; j < channels->openDataCount; j++)
|
||||
{
|
||||
if (channels->openDataList[j].OpenHandle == open_handle)
|
||||
if (channels->openDataList[j].OpenHandle == OpenHandle)
|
||||
{
|
||||
*pindex = j;
|
||||
found = TRUE;
|
||||
@ -324,21 +324,17 @@ UINT32 FreeRDP_VirtualChannelEventPush(UINT32 openHandle, wMessage* event)
|
||||
*/
|
||||
int freerdp_channels_global_init(void)
|
||||
{
|
||||
g_open_handle_sequence = 1;
|
||||
g_mutex_init = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
if (!g_ChannelsList)
|
||||
{
|
||||
g_ChannelsList = ArrayList_New(TRUE);
|
||||
InitializeCriticalSectionAndSpinCount(&g_channels_lock, 4000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int freerdp_channels_global_uninit(void)
|
||||
{
|
||||
/* TODO: free channels list */
|
||||
|
||||
CloseHandle(g_mutex_init);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -397,12 +393,12 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v
|
||||
channels->can_call_init = TRUE;
|
||||
channels->settings = settings;
|
||||
|
||||
WaitForSingleObject(g_mutex_init, INFINITE);
|
||||
EnterCriticalSection(&g_channels_lock);
|
||||
|
||||
g_ChannelInitData.channels = channels;
|
||||
status = pChannelClientData->entry((PCHANNEL_ENTRY_POINTS) &ep);
|
||||
|
||||
ReleaseMutex(g_mutex_init);
|
||||
LeaveCriticalSection(&g_channels_lock);
|
||||
|
||||
/* disable MyVirtualChannelInit */
|
||||
channels->settings = NULL;
|
||||
@ -499,22 +495,39 @@ int freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance)
|
||||
int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance)
|
||||
{
|
||||
int index;
|
||||
char* hostname;
|
||||
int hostnameLength;
|
||||
char* name;
|
||||
char* hostname;
|
||||
int hostnameLength;
|
||||
CHANNEL_CLIENT_DATA* pChannelClientData;
|
||||
|
||||
channels->is_connected = 1;
|
||||
hostname = instance->settings->ServerHostname;
|
||||
hostnameLength = strlen(hostname);
|
||||
|
||||
DEBUG_CHANNELS("hostname [%s] channels->num_libs [%d]", hostname, channels->clientDataCount);
|
||||
|
||||
for (index = 0; index < channels->clientDataCount; index++)
|
||||
{
|
||||
pChannelClientData = &channels->clientDataList[index];
|
||||
|
||||
if (pChannelClientData->pChannelInitEventProc)
|
||||
{
|
||||
ChannelConnectedEventArgs e;
|
||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||
|
||||
pChannelOpenData = &channels->openDataList[index];
|
||||
|
||||
pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_CONNECTED, hostname, hostnameLength);
|
||||
|
||||
name = (char*) malloc(9);
|
||||
CopyMemory(name, pChannelOpenData->name, 8);
|
||||
name[8] = '\0';
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.name = name;
|
||||
e.pInterface = pChannelOpenData->pInterface;
|
||||
PubSub_OnChannelConnected(instance->context->pubSub, instance->context, &e);
|
||||
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
||||
channels->drdynvc = (DrdynvcClientContext*) freerdp_channels_get_static_channel_interface(channels, "drdynvc");
|
||||
@ -774,19 +787,37 @@ wMessage* freerdp_channels_pop_event(rdpChannels* channels)
|
||||
void freerdp_channels_close(rdpChannels* channels, freerdp* instance)
|
||||
{
|
||||
int index;
|
||||
char* name;
|
||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||
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->clientDataCount; index++)
|
||||
{
|
||||
ChannelDisconnectedEventArgs e;
|
||||
|
||||
pChannelClientData = &channels->clientDataList[index];
|
||||
|
||||
if (pChannelClientData->pChannelInitEventProc)
|
||||
pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0);
|
||||
|
||||
pChannelOpenData = &channels->openDataList[index];
|
||||
|
||||
name = (char*) malloc(9);
|
||||
CopyMemory(name, pChannelOpenData->name, 8);
|
||||
name[8] = '\0';
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.name = name;
|
||||
e.pInterface = pChannelOpenData->pInterface;
|
||||
PubSub_OnChannelDisconnected(instance->context->pubSub, instance->context, &e);
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
/* Emit a quit signal to the internal message pipe. */
|
||||
|
@ -37,8 +37,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MODULE winpr
|
||||
MODULES winpr-crt)
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
@ -32,4 +32,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server")
|
||||
|
@ -39,9 +39,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
|
@ -38,5 +38,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MODULE winpr
|
||||
MODULES winpr-synch)
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
|
@ -32,4 +32,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server")
|
||||
|
@ -45,8 +45,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
@ -40,10 +40,9 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/file.h>
|
||||
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@ -125,7 +124,6 @@ static BOOL drive_file_remove_dir(const char* path)
|
||||
|
||||
if (STAT(p, &st) != 0)
|
||||
{
|
||||
DEBUG_WARN("stat %s failed.", p);
|
||||
ret = FALSE;
|
||||
}
|
||||
else if (S_ISDIR(st.st_mode))
|
||||
@ -134,7 +132,6 @@ static BOOL drive_file_remove_dir(const char* path)
|
||||
}
|
||||
else if (unlink(p) < 0)
|
||||
{
|
||||
DEBUG_WARN("unlink %s failed.", p);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
@ -156,7 +153,6 @@ static BOOL drive_file_remove_dir(const char* path)
|
||||
{
|
||||
if (rmdir(path) < 0)
|
||||
{
|
||||
DEBUG_WARN("rmdir %s failed.", path);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
@ -422,7 +418,6 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
||||
|
||||
default:
|
||||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@ -517,12 +512,10 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||
/* TODO rename does not work on win32 */
|
||||
if (rename(file->fullpath, fullpath) == 0)
|
||||
{
|
||||
DEBUG_SVC("renamed %s to %s", file->fullpath, fullpath);
|
||||
drive_file_set_fullpath(file, fullpath);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_WARN("rename %s to %s failed, errno = %d", file->fullpath, fullpath, errno);
|
||||
free(fullpath);
|
||||
return FALSE;
|
||||
}
|
||||
@ -530,7 +523,6 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -546,8 +538,6 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
||||
struct STAT st;
|
||||
struct dirent* ent;
|
||||
|
||||
DEBUG_SVC("path %s FsInformationClass %d InitialQuery %d", path, FsInformationClass, InitialQuery);
|
||||
|
||||
if (!file->dir)
|
||||
{
|
||||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
@ -586,9 +576,8 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
||||
ent = readdir(file->dir);
|
||||
}
|
||||
|
||||
if (ent == NULL)
|
||||
if (!ent)
|
||||
{
|
||||
DEBUG_SVC(" pattern %s not found.", file->pattern);
|
||||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
Stream_Write_UINT8(output, 0); /* Padding */
|
||||
return FALSE;
|
||||
@ -600,10 +589,9 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
||||
|
||||
if (STAT((char*) ent_path, &st) != 0)
|
||||
{
|
||||
DEBUG_WARN("stat %s failed. errno = %d", (char*) ent_path, errno);
|
||||
|
||||
}
|
||||
|
||||
DEBUG_SVC(" pattern %s matched %s", file->pattern, ent_path);
|
||||
free(ent_path);
|
||||
ent_path = NULL;
|
||||
|
||||
@ -682,7 +670,6 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
||||
default:
|
||||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
Stream_Write_UINT8(output, 0); /* Padding */
|
||||
DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass);
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
|
@ -38,12 +38,11 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/interlocked.h>
|
||||
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/interlocked.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#include "drive_file.h"
|
||||
|
||||
@ -54,12 +53,10 @@ struct _DRIVE_DEVICE
|
||||
DEVICE device;
|
||||
|
||||
char* path;
|
||||
LIST* files;
|
||||
wListDictionary* files;
|
||||
|
||||
HANDLE thread;
|
||||
HANDLE irpEvent;
|
||||
HANDLE stopEvent;
|
||||
PSLIST_HEADER pIrpList;
|
||||
wMessageQueue* IrpQueue;
|
||||
|
||||
DEVMAN* devman;
|
||||
};
|
||||
@ -94,31 +91,23 @@ static UINT32 drive_map_posix_err(int fs_errno)
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG_SVC("errno 0x%x mapped to 0x%x", fs_errno, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static DRIVE_FILE* drive_get_file_by_id(DRIVE_DEVICE* disk, UINT32 id)
|
||||
static DRIVE_FILE* drive_get_file_by_id(DRIVE_DEVICE* drive, UINT32 id)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
DRIVE_FILE* file;
|
||||
DRIVE_FILE* file = NULL;
|
||||
void* key = (void*) (size_t) id;
|
||||
|
||||
for (item = disk->files->head; item; item = item->next)
|
||||
{
|
||||
file = (DRIVE_FILE*) item->data;
|
||||
file = (DRIVE_FILE*) ListDictionary_GetItemValue(drive->files, key);
|
||||
|
||||
if (file->id == id)
|
||||
return file;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return file;
|
||||
}
|
||||
|
||||
static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
char* path = NULL;
|
||||
int status;
|
||||
void* key;
|
||||
UINT32 FileId;
|
||||
DRIVE_FILE* file;
|
||||
BYTE Information;
|
||||
@ -126,6 +115,7 @@ static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp)
|
||||
UINT32 CreateDisposition;
|
||||
UINT32 CreateOptions;
|
||||
UINT32 PathLength;
|
||||
char* path = NULL;
|
||||
|
||||
Stream_Read_UINT32(irp->input, DesiredAccess);
|
||||
Stream_Seek(irp->input, 16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */
|
||||
@ -141,16 +131,14 @@ static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp)
|
||||
|
||||
FileId = irp->devman->id_sequence++;
|
||||
|
||||
file = drive_file_new(disk->path, path, FileId,
|
||||
file = drive_file_new(drive->path, path, FileId,
|
||||
DesiredAccess, CreateDisposition, CreateOptions);
|
||||
|
||||
if (file == NULL)
|
||||
if (!file)
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
FileId = 0;
|
||||
Information = 0;
|
||||
|
||||
DEBUG_WARN("failed to create %s.", path);
|
||||
}
|
||||
else if (file->err)
|
||||
{
|
||||
@ -163,7 +151,8 @@ static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp)
|
||||
}
|
||||
else
|
||||
{
|
||||
list_enqueue(disk->files, file);
|
||||
key = (void*) (size_t) file->id;
|
||||
ListDictionary_Add(drive->files, key, file);
|
||||
|
||||
switch (CreateDisposition)
|
||||
{
|
||||
@ -183,7 +172,6 @@ static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp)
|
||||
Information = 0;
|
||||
break;
|
||||
}
|
||||
DEBUG_SVC("%s(%d) created.", file->fullpath, file->id);
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(irp->output, FileId);
|
||||
@ -194,23 +182,22 @@ static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp)
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
static void drive_process_irp_close(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_close(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
void* key;
|
||||
DRIVE_FILE* file;
|
||||
|
||||
file = drive_get_file_by_id(disk, irp->FileId);
|
||||
file = drive_get_file_by_id(drive, irp->FileId);
|
||||
|
||||
if (file == NULL)
|
||||
key = (void*) (size_t) irp->FileId;
|
||||
|
||||
if (!file)
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
|
||||
DEBUG_WARN("FileId %d not valid.", irp->FileId);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_SVC("%s(%d) closed.", file->fullpath, file->id);
|
||||
|
||||
list_remove(disk->files, file);
|
||||
ListDictionary_Remove(drive->files, key);
|
||||
drive_file_free(file);
|
||||
}
|
||||
|
||||
@ -219,7 +206,7 @@ static void drive_process_irp_close(DRIVE_DEVICE* disk, IRP* irp)
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
static void drive_process_irp_read(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_read(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
DRIVE_FILE* file;
|
||||
UINT32 Length;
|
||||
@ -229,37 +216,32 @@ static void drive_process_irp_read(DRIVE_DEVICE* disk, IRP* irp)
|
||||
Stream_Read_UINT32(irp->input, Length);
|
||||
Stream_Read_UINT64(irp->input, Offset);
|
||||
|
||||
file = drive_get_file_by_id(disk, irp->FileId);
|
||||
file = drive_get_file_by_id(drive, irp->FileId);
|
||||
|
||||
if (file == NULL)
|
||||
if (!file)
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
Length = 0;
|
||||
|
||||
DEBUG_WARN("FileId %d not valid.", irp->FileId);
|
||||
}
|
||||
else if (!drive_file_seek(file, Offset))
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
Length = 0;
|
||||
|
||||
DEBUG_WARN("seek %s(%d) failed.", file->fullpath, file->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = (BYTE*) malloc(Length);
|
||||
|
||||
if (!drive_file_read(file, buffer, &Length))
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
Length = 0;
|
||||
|
||||
DEBUG_WARN("read %s(%d) failed.", file->fullpath, file->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_SVC("read %llu-%llu from %s(%d).", Offset, Offset + Length, file->fullpath, file->id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,7 +258,7 @@ static void drive_process_irp_read(DRIVE_DEVICE* disk, IRP* irp)
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
static void drive_process_irp_write(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_write(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
DRIVE_FILE* file;
|
||||
UINT32 Length;
|
||||
@ -286,32 +268,26 @@ static void drive_process_irp_write(DRIVE_DEVICE* disk, IRP* irp)
|
||||
Stream_Read_UINT64(irp->input, Offset);
|
||||
Stream_Seek(irp->input, 20); /* Padding */
|
||||
|
||||
file = drive_get_file_by_id(disk, irp->FileId);
|
||||
file = drive_get_file_by_id(drive, irp->FileId);
|
||||
|
||||
if (file == NULL)
|
||||
if (!file)
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
Length = 0;
|
||||
|
||||
DEBUG_WARN("FileId %d not valid.", irp->FileId);
|
||||
}
|
||||
else if (!drive_file_seek(file, Offset))
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
Length = 0;
|
||||
|
||||
DEBUG_WARN("seek %s(%d) failed.", file->fullpath, file->id);
|
||||
}
|
||||
else if (!drive_file_write(file, Stream_Pointer(irp->input), Length))
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
Length = 0;
|
||||
|
||||
DEBUG_WARN("write %s(%d) failed.", file->fullpath, file->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_SVC("write %llu-%llu to %s(%d).", Offset, Offset + Length, file->fullpath, file->id);
|
||||
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(irp->output, Length);
|
||||
@ -320,36 +296,32 @@ static void drive_process_irp_write(DRIVE_DEVICE* disk, IRP* irp)
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
static void drive_process_irp_query_information(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_query_information(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
DRIVE_FILE* file;
|
||||
UINT32 FsInformationClass;
|
||||
|
||||
Stream_Read_UINT32(irp->input, FsInformationClass);
|
||||
|
||||
file = drive_get_file_by_id(disk, irp->FileId);
|
||||
file = drive_get_file_by_id(drive, irp->FileId);
|
||||
|
||||
if (file == NULL)
|
||||
if (!file)
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
|
||||
DEBUG_WARN("FileId %d not valid.", irp->FileId);
|
||||
}
|
||||
else if (!drive_file_query_information(file, FsInformationClass, irp->output))
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
|
||||
DEBUG_WARN("FsInformationClass %d on %s(%d) failed.", FsInformationClass, file->fullpath, file->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_SVC("FsInformationClass %d on %s(%d).", FsInformationClass, file->fullpath, file->id);
|
||||
|
||||
}
|
||||
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
static void drive_process_irp_set_information(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
DRIVE_FILE* file;
|
||||
UINT32 FsInformationClass;
|
||||
@ -359,23 +331,19 @@ static void drive_process_irp_set_information(DRIVE_DEVICE* disk, IRP* irp)
|
||||
Stream_Read_UINT32(irp->input, Length);
|
||||
Stream_Seek(irp->input, 24); /* Padding */
|
||||
|
||||
file = drive_get_file_by_id(disk, irp->FileId);
|
||||
file = drive_get_file_by_id(drive, irp->FileId);
|
||||
|
||||
if (file == NULL)
|
||||
if (!file)
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
|
||||
DEBUG_WARN("FileId %d not valid.", irp->FileId);
|
||||
}
|
||||
else if (!drive_file_set_information(file, FsInformationClass, Length, irp->input))
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
|
||||
DEBUG_WARN("FsInformationClass %d on %s(%d) failed.", FsInformationClass, file->fullpath, file->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_SVC("FsInformationClass %d on %s(%d) ok.", FsInformationClass, file->fullpath, file->id);
|
||||
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(irp->output, Length);
|
||||
@ -383,7 +351,7 @@ static void drive_process_irp_set_information(DRIVE_DEVICE* disk, IRP* irp)
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
UINT32 FsInformationClass;
|
||||
wStream* output = irp->output;
|
||||
@ -396,8 +364,8 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP*
|
||||
|
||||
Stream_Read_UINT32(irp->input, FsInformationClass);
|
||||
|
||||
STATVFS(disk->path, &svfst);
|
||||
STAT(disk->path, &st);
|
||||
STATVFS(drive->path, &svfst);
|
||||
STAT(drive->path, &st);
|
||||
|
||||
switch (FsInformationClass)
|
||||
{
|
||||
@ -470,7 +438,6 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP*
|
||||
default:
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -479,20 +446,19 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP*
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/cc241518.aspx */
|
||||
|
||||
static void drive_process_irp_silent_ignore(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_silent_ignore(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
UINT32 FsInformationClass;
|
||||
wStream* output = irp->output;
|
||||
|
||||
Stream_Read_UINT32(irp->input, FsInformationClass);
|
||||
|
||||
DEBUG_SVC("FsInformationClass %d in drive_process_irp_silent_ignore", FsInformationClass);
|
||||
Stream_Write_UINT32(output, 0); /* Length */
|
||||
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
static void drive_process_irp_query_directory(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
char* path = NULL;
|
||||
int status;
|
||||
@ -512,13 +478,12 @@ static void drive_process_irp_query_directory(DRIVE_DEVICE* disk, IRP* irp)
|
||||
if (status < 1)
|
||||
path = (char*) calloc(1, 1);
|
||||
|
||||
file = drive_get_file_by_id(disk, irp->FileId);
|
||||
file = drive_get_file_by_id(drive, irp->FileId);
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
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))
|
||||
{
|
||||
@ -530,12 +495,12 @@ static void drive_process_irp_query_directory(DRIVE_DEVICE* disk, IRP* irp)
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
static void drive_process_irp_directory_control(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_directory_control(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
switch (irp->MinorFunction)
|
||||
{
|
||||
case IRP_MN_QUERY_DIRECTORY:
|
||||
drive_process_irp_query_directory(disk, irp);
|
||||
drive_process_irp_query_directory(drive, irp);
|
||||
break;
|
||||
|
||||
case IRP_MN_NOTIFY_CHANGE_DIRECTORY: /* TODO */
|
||||
@ -543,7 +508,6 @@ static void drive_process_irp_directory_control(DRIVE_DEVICE* disk, IRP* irp)
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("MinorFunction 0x%X not supported", irp->MinorFunction);
|
||||
irp->IoStatus = STATUS_NOT_SUPPORTED;
|
||||
Stream_Write_UINT32(irp->output, 0); /* Length */
|
||||
irp->Complete(irp);
|
||||
@ -551,142 +515,116 @@ static void drive_process_irp_directory_control(DRIVE_DEVICE* disk, IRP* irp)
|
||||
}
|
||||
}
|
||||
|
||||
static void drive_process_irp_device_control(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp_device_control(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
Stream_Write_UINT32(irp->output, 0); /* OutputBufferLength */
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
static void drive_process_irp(DRIVE_DEVICE* disk, IRP* irp)
|
||||
static void drive_process_irp(DRIVE_DEVICE* drive, IRP* irp)
|
||||
{
|
||||
irp->IoStatus = STATUS_SUCCESS;
|
||||
|
||||
switch (irp->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_CREATE:
|
||||
drive_process_irp_create(disk, irp);
|
||||
drive_process_irp_create(drive, irp);
|
||||
break;
|
||||
|
||||
case IRP_MJ_CLOSE:
|
||||
drive_process_irp_close(disk, irp);
|
||||
drive_process_irp_close(drive, irp);
|
||||
break;
|
||||
|
||||
case IRP_MJ_READ:
|
||||
drive_process_irp_read(disk, irp);
|
||||
drive_process_irp_read(drive, irp);
|
||||
break;
|
||||
|
||||
case IRP_MJ_WRITE:
|
||||
drive_process_irp_write(disk, irp);
|
||||
drive_process_irp_write(drive, irp);
|
||||
break;
|
||||
|
||||
case IRP_MJ_QUERY_INFORMATION:
|
||||
drive_process_irp_query_information(disk, irp);
|
||||
drive_process_irp_query_information(drive, irp);
|
||||
break;
|
||||
|
||||
case IRP_MJ_SET_INFORMATION:
|
||||
drive_process_irp_set_information(disk, irp);
|
||||
drive_process_irp_set_information(drive, irp);
|
||||
break;
|
||||
|
||||
case IRP_MJ_QUERY_VOLUME_INFORMATION:
|
||||
drive_process_irp_query_volume_information(disk, irp);
|
||||
drive_process_irp_query_volume_information(drive, irp);
|
||||
break;
|
||||
|
||||
case IRP_MJ_LOCK_CONTROL :
|
||||
DEBUG_WARN("MajorFunction IRP_MJ_LOCK_CONTROL silent ignored");
|
||||
drive_process_irp_silent_ignore(disk, irp);
|
||||
case IRP_MJ_LOCK_CONTROL:
|
||||
drive_process_irp_silent_ignore(drive, irp);
|
||||
break;
|
||||
|
||||
case IRP_MJ_DIRECTORY_CONTROL:
|
||||
drive_process_irp_directory_control(disk, irp);
|
||||
drive_process_irp_directory_control(drive, irp);
|
||||
break;
|
||||
|
||||
case IRP_MJ_DEVICE_CONTROL:
|
||||
drive_process_irp_device_control(disk, irp);
|
||||
drive_process_irp_device_control(drive, irp);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("MajorFunction 0x%X not supported", irp->MajorFunction);
|
||||
irp->IoStatus = STATUS_NOT_SUPPORTED;
|
||||
irp->Complete(irp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void drive_process_irp_list(DRIVE_DEVICE* disk)
|
||||
{
|
||||
IRP* irp;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (WaitForSingleObject(disk->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
break;
|
||||
|
||||
irp = (IRP*) InterlockedPopEntrySList(disk->pIrpList);
|
||||
|
||||
if (irp == NULL)
|
||||
break;
|
||||
|
||||
drive_process_irp(disk, irp);
|
||||
}
|
||||
}
|
||||
|
||||
static void* drive_thread_func(void* arg)
|
||||
{
|
||||
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) arg;
|
||||
HANDLE hdl[] = {disk->irpEvent, disk->stopEvent};
|
||||
IRP* irp;
|
||||
wMessage message;
|
||||
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) arg;
|
||||
|
||||
while (1)
|
||||
{
|
||||
DWORD rc = WaitForMultipleObjects(2, hdl, FALSE, INFINITE);
|
||||
if (rc == WAIT_OBJECT_0 + 1)
|
||||
break;
|
||||
while (1)
|
||||
{
|
||||
if (!MessageQueue_Wait(drive->IrpQueue))
|
||||
break;
|
||||
|
||||
ResetEvent(disk->irpEvent);
|
||||
drive_process_irp_list(disk);
|
||||
}
|
||||
ExitThread(0);
|
||||
if (!MessageQueue_Peek(drive->IrpQueue, &message, TRUE))
|
||||
break;
|
||||
|
||||
return NULL;
|
||||
if (message.id == WMQ_QUIT)
|
||||
break;
|
||||
|
||||
irp = (IRP*) message.wParam;
|
||||
|
||||
if (irp)
|
||||
drive_process_irp(drive, irp);
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void drive_irp_request(DEVICE* device, IRP* irp)
|
||||
{
|
||||
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) device;
|
||||
|
||||
InterlockedPushEntrySList(disk->pIrpList, &(irp->ItemEntry));
|
||||
|
||||
SetEvent(disk->irpEvent);
|
||||
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device;
|
||||
MessageQueue_Post(drive->IrpQueue, NULL, 0, (void*) irp, NULL);
|
||||
}
|
||||
|
||||
static void drive_free(DEVICE* device)
|
||||
{
|
||||
IRP* irp;
|
||||
DRIVE_FILE* file;
|
||||
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) device;
|
||||
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device;
|
||||
|
||||
SetEvent(disk->stopEvent);
|
||||
WaitForSingleObject(disk->thread, INFINITE);
|
||||
CloseHandle(disk->thread);
|
||||
CloseHandle(disk->irpEvent);
|
||||
CloseHandle(disk->stopEvent);
|
||||
MessageQueue_PostQuit(drive->IrpQueue, 0);
|
||||
WaitForSingleObject(drive->thread, INFINITE);
|
||||
|
||||
while ((irp = (IRP*) InterlockedPopEntrySList(disk->pIrpList)) != NULL)
|
||||
irp->Discard(irp);
|
||||
CloseHandle(drive->thread);
|
||||
|
||||
_aligned_free(disk->pIrpList);
|
||||
ListDictionary_Free(drive->files);
|
||||
|
||||
while ((file = (DRIVE_FILE*) list_dequeue(disk->files)) != NULL)
|
||||
drive_file_free(file);
|
||||
|
||||
list_free(disk->files);
|
||||
|
||||
free(disk);
|
||||
free(drive);
|
||||
}
|
||||
|
||||
void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* name, char* path)
|
||||
{
|
||||
int i, length;
|
||||
DRIVE_DEVICE* disk;
|
||||
DRIVE_DEVICE* drive;
|
||||
|
||||
#ifdef WIN32
|
||||
/*
|
||||
@ -704,33 +642,31 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char*
|
||||
|
||||
if (name[0] && path[0])
|
||||
{
|
||||
disk = (DRIVE_DEVICE*) malloc(sizeof(DRIVE_DEVICE));
|
||||
ZeroMemory(disk, sizeof(DRIVE_DEVICE));
|
||||
drive = (DRIVE_DEVICE*) malloc(sizeof(DRIVE_DEVICE));
|
||||
ZeroMemory(drive, sizeof(DRIVE_DEVICE));
|
||||
|
||||
disk->device.type = RDPDR_DTYP_FILESYSTEM;
|
||||
disk->device.name = name;
|
||||
disk->device.IRPRequest = drive_irp_request;
|
||||
disk->device.Free = drive_free;
|
||||
drive->device.type = RDPDR_DTYP_FILESYSTEM;
|
||||
drive->device.name = name;
|
||||
drive->device.IRPRequest = drive_irp_request;
|
||||
drive->device.Free = drive_free;
|
||||
|
||||
length = strlen(name);
|
||||
disk->device.data = Stream_New(NULL, length + 1);
|
||||
drive->device.data = Stream_New(NULL, length + 1);
|
||||
|
||||
for (i = 0; i <= length; i++)
|
||||
Stream_Write_UINT8(disk->device.data, name[i] < 0 ? '_' : name[i]);
|
||||
Stream_Write_UINT8(drive->device.data, name[i] < 0 ? '_' : name[i]);
|
||||
|
||||
disk->path = path;
|
||||
disk->files = list_new();
|
||||
drive->path = path;
|
||||
|
||||
disk->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
InitializeSListHead(disk->pIrpList);
|
||||
drive->files = ListDictionary_New(TRUE);
|
||||
ListDictionary_Object(drive->files)->fnObjectFree = (OBJECT_FREE_FN) drive_file_free;
|
||||
|
||||
disk->irpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
disk->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
disk->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) drive_thread_func, disk, CREATE_SUSPENDED, NULL);
|
||||
drive->IrpQueue = MessageQueue_New();
|
||||
drive->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) drive_thread_func, drive, CREATE_SUSPENDED, NULL);
|
||||
|
||||
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) disk);
|
||||
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) drive);
|
||||
|
||||
ResumeThread(disk->thread);
|
||||
ResumeThread(drive->thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
|
@ -36,8 +36,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
@ -56,8 +56,6 @@ endif()
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
@ -36,5 +36,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
@ -38,10 +38,18 @@
|
||||
#include "rail_orders.h"
|
||||
#include "rail_main.h"
|
||||
|
||||
void rail_send_channel_data(void* rail_object, void* data, size_t length)
|
||||
RailClientContext* rail_get_client_interface(void* railObject)
|
||||
{
|
||||
RailClientContext* pInterface;
|
||||
rdpSvcPlugin* plugin = (rdpSvcPlugin*) railObject;
|
||||
pInterface = (RailClientContext*) *(plugin->channel_entry_points.ppInterface);
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
void rail_send_channel_data(void* railObject, void* data, size_t length)
|
||||
{
|
||||
wStream* s = NULL;
|
||||
railPlugin* plugin = (railPlugin*) rail_object;
|
||||
railPlugin* plugin = (railPlugin*) railObject;
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
Stream_Write(s, data, length);
|
||||
@ -54,17 +62,17 @@ static void on_free_rail_channel_event(wMessage* event)
|
||||
rail_free_cloned_order(GetMessageType(event->id), event->wParam);
|
||||
}
|
||||
|
||||
void rail_send_channel_event(void* rail_object, UINT16 event_type, void* param)
|
||||
void rail_send_channel_event(void* railObject, UINT16 eventType, void* param)
|
||||
{
|
||||
void * payload = NULL;
|
||||
void* payload = NULL;
|
||||
wMessage* out_event = NULL;
|
||||
railPlugin* plugin = (railPlugin*) rail_object;
|
||||
railPlugin* plugin = (railPlugin*) railObject;
|
||||
|
||||
payload = rail_clone_order(event_type, param);
|
||||
payload = rail_clone_order(eventType, param);
|
||||
|
||||
if (payload != NULL)
|
||||
if (payload)
|
||||
{
|
||||
out_event = freerdp_event_new(RailChannel_Class, event_type,
|
||||
out_event = freerdp_event_new(RailChannel_Class, eventType,
|
||||
on_free_rail_channel_event, payload);
|
||||
|
||||
svc_plugin_send_event((rdpSvcPlugin*) plugin, out_event);
|
||||
@ -78,21 +86,25 @@ static void rail_process_connect(rdpSvcPlugin* plugin)
|
||||
rail->rail_order = rail_order_new();
|
||||
rail->rail_order->settings = (rdpSettings*) plugin->channel_entry_points.pExtendedData;
|
||||
rail->rail_order->plugin = rail;
|
||||
|
||||
WLog_Print(rail->log, WLOG_DEBUG, "Connect");
|
||||
}
|
||||
|
||||
static void rail_process_terminate(rdpSvcPlugin* plugin)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) plugin;
|
||||
|
||||
WLog_Print(rail->log, WLOG_DEBUG, "Terminate");
|
||||
}
|
||||
|
||||
static void rail_process_receive(rdpSvcPlugin* plugin, wStream* s)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) plugin;
|
||||
rail_order_recv(rail->rail_order, s);
|
||||
rail_order_recv(rail, s);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
static void rail_process_addin_args(rdpRailOrder* rail_order, rdpSettings* settings)
|
||||
static void rail_process_addin_args(rdpRailOrder* railOrder, rdpSettings* settings)
|
||||
{
|
||||
char* exeOrFile;
|
||||
|
||||
@ -101,35 +113,35 @@ static void rail_process_addin_args(rdpRailOrder* rail_order, rdpSettings* setti
|
||||
if (strlen(exeOrFile) >= 2)
|
||||
{
|
||||
if (strncmp(exeOrFile, "||", 2) != 0)
|
||||
rail_order->exec.flags |= RAIL_EXEC_FLAG_FILE;
|
||||
railOrder->exec.flags |= RAIL_EXEC_FLAG_FILE;
|
||||
}
|
||||
|
||||
rail_string_to_unicode_string(settings->RemoteApplicationProgram, &rail_order->exec.exeOrFile);
|
||||
rail_string_to_unicode_string(settings->ShellWorkingDirectory, &rail_order->exec.workingDir);
|
||||
rail_string_to_unicode_string(settings->RemoteApplicationCmdLine, &rail_order->exec.arguments);
|
||||
rail_string_to_unicode_string(settings->RemoteApplicationProgram, &railOrder->exec.exeOrFile);
|
||||
rail_string_to_unicode_string(settings->ShellWorkingDirectory, &railOrder->exec.workingDir);
|
||||
rail_string_to_unicode_string(settings->RemoteApplicationCmdLine, &railOrder->exec.arguments);
|
||||
|
||||
rail_send_client_exec_order(rail_order);
|
||||
rail_send_client_exec_order((railPlugin*) railOrder->plugin, &railOrder->exec);
|
||||
}
|
||||
|
||||
static void rail_recv_set_sysparams_event(rdpRailOrder* rail_order, wMessage* event)
|
||||
static void rail_recv_set_sysparams_event(rdpRailOrder* railOrder, wMessage* event)
|
||||
{
|
||||
RAIL_SYSPARAM_ORDER* sysparam;
|
||||
|
||||
/* Send System Parameters */
|
||||
|
||||
sysparam = (RAIL_SYSPARAM_ORDER*) event->wParam;
|
||||
memmove(&rail_order->sysparam, sysparam, sizeof(RAIL_SYSPARAM_ORDER));
|
||||
memmove(&railOrder->sysparam, sysparam, sizeof(RAIL_SYSPARAM_ORDER));
|
||||
|
||||
rail_send_client_sysparams_order(rail_order);
|
||||
rail_send_client_sysparams_order((railPlugin*) railOrder->plugin, &railOrder->sysparam);
|
||||
|
||||
/* execute */
|
||||
|
||||
rail_order->exec.flags = RAIL_EXEC_FLAG_EXPAND_ARGUMENTS;
|
||||
railOrder->exec.flags = RAIL_EXEC_FLAG_EXPAND_ARGUMENTS;
|
||||
|
||||
rail_process_addin_args(rail_order, rail_order->settings);
|
||||
rail_process_addin_args(railOrder, railOrder->settings);
|
||||
}
|
||||
|
||||
static void rail_recv_exec_remote_app_event(rdpRailOrder* rail_order, wMessage* event)
|
||||
static void rail_recv_exec_remote_app_event(rdpRailOrder* railOrder, wMessage* event)
|
||||
{
|
||||
/**
|
||||
* TODO: replace event system by an API to allow the execution
|
||||
@ -137,63 +149,62 @@ static void rail_recv_exec_remote_app_event(rdpRailOrder* rail_order, wMessage*
|
||||
* always built-in, so clients can safely link to it.
|
||||
*/
|
||||
|
||||
//rail_process_addin_args(rail_order, data);
|
||||
//rail_process_addin_args((railPlugin*) railOrder->plugin, data);
|
||||
}
|
||||
|
||||
static void rail_recv_activate_event(rdpRailOrder* rail_order, wMessage* event)
|
||||
static void rail_recv_activate_event(rdpRailOrder* railOrder, wMessage* event)
|
||||
{
|
||||
RAIL_ACTIVATE_ORDER* activate = (RAIL_ACTIVATE_ORDER*) event->wParam;
|
||||
|
||||
CopyMemory(&rail_order->activate, activate, sizeof(RAIL_ACTIVATE_ORDER));
|
||||
rail_send_client_activate_order(rail_order);
|
||||
CopyMemory(&railOrder->activate, activate, sizeof(RAIL_ACTIVATE_ORDER));
|
||||
rail_send_client_activate_order((railPlugin*) railOrder->plugin, &railOrder->activate);
|
||||
}
|
||||
|
||||
static void rail_recv_sysmenu_event(rdpRailOrder* rail_order, wMessage* event)
|
||||
static void rail_recv_sysmenu_event(rdpRailOrder* railOrder, wMessage* event)
|
||||
{
|
||||
RAIL_SYSMENU_ORDER* sysmenu = (RAIL_SYSMENU_ORDER*) event->wParam;
|
||||
|
||||
CopyMemory(&rail_order->sysmenu, sysmenu, sizeof(RAIL_SYSMENU_ORDER));
|
||||
rail_send_client_sysmenu_order(rail_order);
|
||||
CopyMemory(&railOrder->sysmenu, sysmenu, sizeof(RAIL_SYSMENU_ORDER));
|
||||
rail_send_client_sysmenu_order((railPlugin*) railOrder->plugin, &railOrder->sysmenu);
|
||||
}
|
||||
|
||||
static void rail_recv_syscommand_event(rdpRailOrder* rail_order, wMessage* event)
|
||||
static void rail_recv_syscommand_event(rdpRailOrder* railOrder, wMessage* event)
|
||||
{
|
||||
RAIL_SYSCOMMAND_ORDER* syscommand = (RAIL_SYSCOMMAND_ORDER*) event->wParam;
|
||||
|
||||
CopyMemory(&rail_order->syscommand, syscommand, sizeof(RAIL_SYSCOMMAND_ORDER));
|
||||
rail_send_client_syscommand_order(rail_order);
|
||||
CopyMemory(&railOrder->syscommand, syscommand, sizeof(RAIL_SYSCOMMAND_ORDER));
|
||||
rail_send_client_syscommand_order((railPlugin*) railOrder->plugin, &railOrder->syscommand);
|
||||
}
|
||||
|
||||
static void rail_recv_notify_event(rdpRailOrder* rail_order, wMessage* event)
|
||||
static void rail_recv_notify_event(rdpRailOrder* railOrder, wMessage* event)
|
||||
{
|
||||
RAIL_NOTIFY_EVENT_ORDER* notify = (RAIL_NOTIFY_EVENT_ORDER*) event->wParam;
|
||||
|
||||
CopyMemory(&rail_order->notify_event, notify, sizeof(RAIL_NOTIFY_EVENT_ORDER));
|
||||
rail_send_client_notify_event_order(rail_order);
|
||||
CopyMemory(&railOrder->notify_event, notify, sizeof(RAIL_NOTIFY_EVENT_ORDER));
|
||||
rail_send_client_notify_event_order((railPlugin*) railOrder->plugin, &railOrder->notify_event);
|
||||
}
|
||||
|
||||
static void rail_recv_window_move_event(rdpRailOrder* rail_order, wMessage* event)
|
||||
static void rail_recv_window_move_event(rdpRailOrder* railOrder, wMessage* event)
|
||||
{
|
||||
RAIL_WINDOW_MOVE_ORDER* window_move = (RAIL_WINDOW_MOVE_ORDER*) event->wParam;
|
||||
|
||||
CopyMemory(&rail_order->window_move, window_move, sizeof(RAIL_WINDOW_MOVE_ORDER));
|
||||
rail_send_client_window_move_order(rail_order);
|
||||
CopyMemory(&railOrder->window_move, window_move, sizeof(RAIL_WINDOW_MOVE_ORDER));
|
||||
rail_send_client_window_move_order((railPlugin*) railOrder->plugin, &railOrder->window_move);
|
||||
}
|
||||
|
||||
static void rail_recv_app_req_event(rdpRailOrder* rail_order, wMessage* event)
|
||||
static void rail_recv_app_req_event(rdpRailOrder* railOrder, wMessage* event)
|
||||
{
|
||||
RAIL_GET_APPID_REQ_ORDER* get_appid_req = (RAIL_GET_APPID_REQ_ORDER*) event->wParam;
|
||||
|
||||
CopyMemory(&rail_order->get_appid_req, get_appid_req, sizeof(RAIL_GET_APPID_REQ_ORDER));
|
||||
rail_send_client_get_appid_req_order(rail_order);
|
||||
CopyMemory(&railOrder->get_appid_req, get_appid_req, sizeof(RAIL_GET_APPID_REQ_ORDER));
|
||||
rail_send_client_get_appid_req_order((railPlugin*) railOrder->plugin, &railOrder->get_appid_req);
|
||||
}
|
||||
|
||||
static void rail_recv_langbarinfo_event(rdpRailOrder* rail_order, wMessage* event)
|
||||
static void rail_recv_langbarinfo_event(rdpRailOrder* railOrder, wMessage* event)
|
||||
{
|
||||
RAIL_LANGBAR_INFO_ORDER* langbar_info = (RAIL_LANGBAR_INFO_ORDER*) event->wParam;
|
||||
|
||||
CopyMemory(&rail_order->langbar_info, langbar_info, sizeof(RAIL_LANGBAR_INFO_ORDER));
|
||||
rail_send_client_langbar_info_order(rail_order);
|
||||
CopyMemory(&railOrder->langbar_info, langbar_info, sizeof(RAIL_LANGBAR_INFO_ORDER));
|
||||
rail_send_client_langbar_info_order((railPlugin*) railOrder->plugin, &railOrder->langbar_info);
|
||||
}
|
||||
|
||||
static void rail_process_event(rdpSvcPlugin* plugin, wMessage* event)
|
||||
@ -246,12 +257,255 @@ static void rail_process_event(rdpSvcPlugin* plugin, wMessage* event)
|
||||
freerdp_event_free(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback Interface
|
||||
*/
|
||||
|
||||
int rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
char* exeOrFile;
|
||||
|
||||
exeOrFile = exec->RemoteApplicationProgram;
|
||||
|
||||
if (!exeOrFile)
|
||||
return -1;
|
||||
|
||||
if (strlen(exeOrFile) >= 2)
|
||||
{
|
||||
if (strncmp(exeOrFile, "||", 2) != 0)
|
||||
exec->flags |= RAIL_EXEC_FLAG_FILE;
|
||||
}
|
||||
|
||||
rail_string_to_unicode_string(exec->RemoteApplicationProgram, &exec->exeOrFile); /* RemoteApplicationProgram */
|
||||
rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir, &exec->workingDir); /* ShellWorkingDirectory */
|
||||
rail_string_to_unicode_string(exec->RemoteApplicationArguments, &exec->arguments); /* RemoteApplicationCmdLine */
|
||||
|
||||
rail_send_client_exec_order(rail, exec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_client_activate(RailClientContext* context, RAIL_ACTIVATE_ORDER* activate)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
rail_send_client_activate_order(rail, activate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
wStream* s;
|
||||
int length;
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
length = RAIL_SYSPARAM_ORDER_LENGTH;
|
||||
|
||||
switch (sysparam->param)
|
||||
{
|
||||
case SPI_SET_DRAG_FULL_WINDOWS:
|
||||
case SPI_SET_KEYBOARD_CUES:
|
||||
case SPI_SET_KEYBOARD_PREF:
|
||||
case SPI_SET_MOUSE_BUTTON_SWAP:
|
||||
length += 1;
|
||||
break;
|
||||
|
||||
case SPI_SET_WORK_AREA:
|
||||
case SPI_DISPLAY_CHANGE:
|
||||
case SPI_TASKBAR_POS:
|
||||
length += 8;
|
||||
break;
|
||||
|
||||
case SPI_SET_HIGH_CONTRAST:
|
||||
length += sysparam->highContrast.colorSchemeLength + 10;
|
||||
break;
|
||||
}
|
||||
|
||||
s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8);
|
||||
rail_write_client_sysparam_order(s, sysparam);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSPARAM);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
int rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
if (sysparam->params & SPI_MASK_SET_HIGH_CONTRAST)
|
||||
{
|
||||
sysparam->param = SPI_SET_HIGH_CONTRAST;
|
||||
rail_send_client_sysparam(context, sysparam);
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_TASKBAR_POS)
|
||||
{
|
||||
sysparam->param = SPI_TASKBAR_POS;
|
||||
rail_send_client_sysparam(context, sysparam);
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_MOUSE_BUTTON_SWAP)
|
||||
{
|
||||
sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP;
|
||||
rail_send_client_sysparam(context, sysparam);
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_KEYBOARD_PREF)
|
||||
{
|
||||
sysparam->param = SPI_SET_KEYBOARD_PREF;
|
||||
rail_send_client_sysparam(context, sysparam);
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_DRAG_FULL_WINDOWS)
|
||||
{
|
||||
sysparam->param = SPI_SET_DRAG_FULL_WINDOWS;
|
||||
rail_send_client_sysparam(context, sysparam);
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_KEYBOARD_CUES)
|
||||
{
|
||||
sysparam->param = SPI_SET_KEYBOARD_CUES;
|
||||
rail_send_client_sysparam(context, sysparam);
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_WORK_AREA)
|
||||
{
|
||||
sysparam->param = SPI_SET_WORK_AREA;
|
||||
rail_send_client_sysparam(context, sysparam);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
return 0; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
int rail_client_system_command(RailClientContext* context, RAIL_SYSCOMMAND_ORDER* syscommand)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
rail_send_client_syscommand_order(rail, syscommand);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_client_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
rail_send_handshake_order(rail, handshake);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake)
|
||||
{
|
||||
return 0; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
int rail_client_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
rail_send_handshake_ex_order(rail, handshakeEx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
||||
{
|
||||
return 0; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
int rail_client_notify_event(RailClientContext* context, RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
rail_send_client_notify_event_order(rail, notifyEvent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_client_window_move(RailClientContext* context, RAIL_WINDOW_MOVE_ORDER* windowMove)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
rail_send_client_window_move_order(rail, windowMove);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
|
||||
{
|
||||
return 0; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
int rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER* minMaxInfo)
|
||||
{
|
||||
return 0; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
int rail_client_information(RailClientContext* context, RAIL_CLIENT_STATUS_ORDER* clientStatus)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
rail_send_client_status_order(rail, clientStatus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_client_system_menu(RailClientContext* context, RAIL_SYSMENU_ORDER* sysmenu)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
rail_send_client_sysmenu_order(rail, sysmenu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_client_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
rail_send_client_langbar_info_order(rail, langBarInfo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo)
|
||||
{
|
||||
return 0; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
int rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORDER* execResult)
|
||||
{
|
||||
return 0; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
int rail_client_get_appid_request(RailClientContext* context, RAIL_GET_APPID_REQ_ORDER* getAppIdReq)
|
||||
{
|
||||
railPlugin* rail = (railPlugin*) context->handle;
|
||||
|
||||
rail_send_client_get_appid_req_order(rail, getAppIdReq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rail_server_get_appid_response(RailClientContext* context, RAIL_GET_APPID_RESP_ORDER* getAppIdResp)
|
||||
{
|
||||
return 0; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
/* rail is always built-in */
|
||||
#define VirtualChannelEntry rail_VirtualChannelEntry
|
||||
|
||||
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
railPlugin* _p;
|
||||
RailClientContext* context;
|
||||
CHANNEL_ENTRY_POINTS_EX* pEntryPointsEx;
|
||||
|
||||
_p = (railPlugin*) malloc(sizeof(railPlugin));
|
||||
ZeroMemory(_p, sizeof(railPlugin));
|
||||
@ -269,6 +523,44 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
_p->plugin.event_callback = rail_process_event;
|
||||
_p->plugin.terminate_callback = rail_process_terminate;
|
||||
|
||||
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_EX*) pEntryPoints;
|
||||
|
||||
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_EX)) &&
|
||||
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
|
||||
{
|
||||
context = (RailClientContext*) malloc(sizeof(RailClientContext));
|
||||
|
||||
context->handle = (void*) _p;
|
||||
|
||||
context->ClientExecute = rail_client_execute;
|
||||
context->ClientActivate = rail_client_activate;
|
||||
context->ClientSystemParam = rail_client_system_param;
|
||||
context->ServerSystemParam = rail_server_system_param;
|
||||
context->ClientSystemCommand = rail_client_system_command;
|
||||
context->ClientHandshake = rail_client_handshake;
|
||||
context->ServerHandshake = rail_server_handshake;
|
||||
context->ClientHandshakeEx = rail_client_handshake_ex;
|
||||
context->ServerHandshakeEx = rail_server_handshake_ex;
|
||||
context->ClientNotifyEvent = rail_client_notify_event;
|
||||
context->ClientWindowMove = rail_client_window_move;
|
||||
context->ServerLocalMoveSize = rail_server_local_move_size;
|
||||
context->ServerMinMaxInfo = rail_server_min_max_info;
|
||||
context->ClientInformation = rail_client_information;
|
||||
context->ClientSystemMenu = rail_client_system_menu;
|
||||
context->ClientLanguageBarInfo = rail_client_language_bar_info;
|
||||
context->ServerLanguageBarInfo = rail_server_language_bar_info;
|
||||
context->ServerExecuteResult = rail_server_execute_result;
|
||||
context->ClientGetAppIdRequest = rail_client_get_appid_request;
|
||||
context->ServerGetAppIdResponse = rail_server_get_appid_response;
|
||||
|
||||
*(pEntryPointsEx->ppInterface) = (void*) context;
|
||||
}
|
||||
|
||||
WLog_Init();
|
||||
_p->log = WLog_Get("com.freerdp.channels.rail.client");
|
||||
|
||||
WLog_Print(_p->log, WLOG_DEBUG, "VirtualChannelEntry");
|
||||
|
||||
svc_plugin_init((rdpSvcPlugin*) _p, pEntryPoints);
|
||||
|
||||
return 1;
|
||||
|
@ -24,9 +24,12 @@
|
||||
|
||||
#include <freerdp/rail.h>
|
||||
#include <freerdp/settings.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#include <freerdp/client/rail.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/wlog.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include "../rail_common.h"
|
||||
@ -34,13 +37,15 @@
|
||||
struct rail_plugin
|
||||
{
|
||||
rdpSvcPlugin plugin;
|
||||
|
||||
wLog* log;
|
||||
rdpRailOrder* rail_order;
|
||||
};
|
||||
typedef struct rail_plugin railPlugin;
|
||||
|
||||
RailClientContext* rail_get_client_interface(void* railObject);
|
||||
|
||||
void rail_send_channel_event(void* rail_object, UINT16 event_type, void* param);
|
||||
void rail_send_channel_data(void* rail_object, void* data, size_t length);
|
||||
|
||||
|
||||
|
||||
#endif /* FREERDP_CHANNEL_CLIENT_RAIL_MAIN_H */
|
||||
|
@ -31,9 +31,7 @@
|
||||
|
||||
#include "rail_orders.h"
|
||||
|
||||
|
||||
|
||||
void rail_send_pdu(rdpRailOrder* rail_order, wStream* s, UINT16 orderType)
|
||||
void rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType)
|
||||
{
|
||||
UINT16 orderLength;
|
||||
|
||||
@ -43,30 +41,31 @@ void rail_send_pdu(rdpRailOrder* rail_order, wStream* s, UINT16 orderType)
|
||||
rail_write_pdu_header(s, orderType, orderLength);
|
||||
Stream_SetPosition(s, orderLength);
|
||||
|
||||
/* send */
|
||||
DEBUG_RAIL("Sending %s PDU, length:%d",
|
||||
WLog_Print(rail->log, WLOG_DEBUG, "Sending %s PDU, length: %d",
|
||||
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength);
|
||||
|
||||
rail_send_channel_data(rail_order->plugin, Stream_Buffer(s), orderLength);
|
||||
rail_send_channel_data(rail, Stream_Buffer(s), orderLength);
|
||||
}
|
||||
|
||||
void rail_write_high_contrast(wStream* s, RAIL_HIGH_CONTRAST* high_contrast)
|
||||
void rail_write_high_contrast(wStream* s, RAIL_HIGH_CONTRAST* highContrast)
|
||||
{
|
||||
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) */
|
||||
rail_write_unicode_string(s, &high_contrast->colorScheme); /* colorScheme */
|
||||
highContrast->colorSchemeLength = highContrast->colorScheme.length + 2;
|
||||
Stream_Write_UINT32(s, highContrast->flags); /* flags (4 bytes) */
|
||||
Stream_Write_UINT32(s, highContrast->colorSchemeLength); /* colorSchemeLength (4 bytes) */
|
||||
rail_write_unicode_string(s, &highContrast->colorScheme); /* colorScheme */
|
||||
}
|
||||
|
||||
BOOL rail_read_server_exec_result_order(wStream* s, RAIL_EXEC_RESULT_ORDER* exec_result)
|
||||
BOOL rail_read_server_exec_result_order(wStream* s, RAIL_EXEC_RESULT_ORDER* execResult)
|
||||
{
|
||||
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_Read_UINT16(s, execResult->flags); /* flags (2 bytes) */
|
||||
Stream_Read_UINT16(s, execResult->execResult); /* execResult (2 bytes) */
|
||||
Stream_Read_UINT32(s, execResult->rawResult); /* rawResult (4 bytes) */
|
||||
Stream_Seek_UINT16(s); /* padding (2 bytes) */
|
||||
return rail_read_unicode_string(s, &exec_result->exeOrFile); /* exeOrFile */
|
||||
|
||||
return rail_read_unicode_string(s, &execResult->exeOrFile); /* exeOrFile */
|
||||
}
|
||||
|
||||
BOOL rail_read_server_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
@ -75,6 +74,7 @@ BOOL rail_read_server_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 5)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, sysparam->param); /* systemParam (4 bytes) */
|
||||
Stream_Read_UINT8(s, body); /* body (1 byte) */
|
||||
|
||||
@ -91,6 +91,7 @@ BOOL rail_read_server_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -98,6 +99,7 @@ BOOL rail_read_server_minmaxinfo_order(wStream* s, RAIL_MINMAXINFO_ORDER* minmax
|
||||
{
|
||||
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) */
|
||||
@ -107,49 +109,53 @@ BOOL rail_read_server_minmaxinfo_order(wStream* s, RAIL_MINMAXINFO_ORDER* minmax
|
||||
Stream_Read_UINT16(s, minmaxinfo->minTrackHeight); /* minTrackHeight (2 bytes) */
|
||||
Stream_Read_UINT16(s, minmaxinfo->maxTrackWidth); /* maxTrackWidth (2 bytes) */
|
||||
Stream_Read_UINT16(s, minmaxinfo->maxTrackHeight); /* maxTrackHeight (2 bytes) */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rail_read_server_localmovesize_order(wStream* s, RAIL_LOCALMOVESIZE_ORDER* localmovesize)
|
||||
BOOL rail_read_server_localmovesize_order(wStream* s, RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
|
||||
{
|
||||
UINT16 isMoveSizeStart;
|
||||
|
||||
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) */
|
||||
localmovesize->isMoveSizeStart = (isMoveSizeStart != 0) ? TRUE : FALSE;
|
||||
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)
|
||||
BOOL rail_read_server_get_appid_resp_order(wStream* s, RAIL_GET_APPID_RESP_ORDER* getAppidResp)
|
||||
{
|
||||
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) */
|
||||
|
||||
get_appid_resp->applicationId.length = 512;
|
||||
get_appid_resp->applicationId.string = &get_appid_resp->applicationIdBuffer[0];
|
||||
Stream_Read_UINT32(s, getAppidResp->windowId); /* windowId (4 bytes) */
|
||||
Stream_Read(s, (BYTE*) &(getAppidResp->applicationId), 512); /* applicationId (256 UNICODE chars) */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbar_info)
|
||||
BOOL rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbarInfo)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
Stream_Read_UINT32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */
|
||||
|
||||
Stream_Read_UINT32(s, langbarInfo->languageBarStatus); /* languageBarStatus (4 bytes) */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void rail_write_client_status_order(wStream* s, RAIL_CLIENT_STATUS_ORDER* client_status)
|
||||
void rail_write_client_status_order(wStream* s, RAIL_CLIENT_STATUS_ORDER* clientStatus)
|
||||
{
|
||||
Stream_Write_UINT32(s, client_status->flags); /* flags (4 bytes) */
|
||||
Stream_Write_UINT32(s, clientStatus->flags); /* flags (4 bytes) */
|
||||
}
|
||||
|
||||
void rail_write_client_exec_order(wStream* s, RAIL_EXEC_ORDER* exec)
|
||||
@ -166,6 +172,7 @@ 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) */
|
||||
|
||||
switch (sysparam->param)
|
||||
@ -240,143 +247,220 @@ void rail_write_client_syscommand_order(wStream* s, RAIL_SYSCOMMAND_ORDER* sysco
|
||||
Stream_Write_UINT16(s, syscommand->command); /* command (2 bytes) */
|
||||
}
|
||||
|
||||
void rail_write_client_notify_event_order(wStream* s, RAIL_NOTIFY_EVENT_ORDER* notify_event)
|
||||
void rail_write_client_notify_event_order(wStream* s, RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
|
||||
{
|
||||
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, notifyEvent->windowId); /* windowId (4 bytes) */
|
||||
Stream_Write_UINT32(s, notifyEvent->notifyIconId); /* notifyIconId (4 bytes) */
|
||||
Stream_Write_UINT32(s, notifyEvent->message); /* notifyIconId (4 bytes) */
|
||||
}
|
||||
|
||||
void rail_write_client_window_move_order(wStream* s, RAIL_WINDOW_MOVE_ORDER* window_move)
|
||||
void rail_write_client_window_move_order(wStream* s, RAIL_WINDOW_MOVE_ORDER* windowMove)
|
||||
{
|
||||
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, windowMove->windowId); /* windowId (4 bytes) */
|
||||
Stream_Write_UINT16(s, windowMove->left); /* left (2 bytes) */
|
||||
Stream_Write_UINT16(s, windowMove->top); /* top (2 bytes) */
|
||||
Stream_Write_UINT16(s, windowMove->right); /* right (2 bytes) */
|
||||
Stream_Write_UINT16(s, windowMove->bottom); /* bottom (2 bytes) */
|
||||
}
|
||||
|
||||
void rail_write_client_get_appid_req_order(wStream* s, RAIL_GET_APPID_REQ_ORDER* get_appid_req)
|
||||
void rail_write_client_get_appid_req_order(wStream* s, RAIL_GET_APPID_REQ_ORDER* getAppidReq)
|
||||
{
|
||||
Stream_Write_UINT32(s, get_appid_req->windowId); /* windowId (4 bytes) */
|
||||
Stream_Write_UINT32(s, getAppidReq->windowId); /* windowId (4 bytes) */
|
||||
}
|
||||
|
||||
void rail_write_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbar_info)
|
||||
void rail_write_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbarInfo)
|
||||
{
|
||||
Stream_Write_UINT32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */
|
||||
Stream_Write_UINT32(s, langbarInfo->languageBarStatus); /* languageBarStatus (4 bytes) */
|
||||
}
|
||||
|
||||
BOOL rail_recv_handshake_order(rdpRailOrder* rail_order, wStream* s)
|
||||
BOOL rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake, wStream* s)
|
||||
{
|
||||
if (!rail_read_handshake_order(s, &rail_order->handshake))
|
||||
RAIL_SYSPARAM_ORDER sysparam;
|
||||
RAIL_CLIENT_STATUS_ORDER clientStatus;
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
|
||||
if (!rail_read_handshake_order(s, handshake))
|
||||
return FALSE;
|
||||
|
||||
rail_order->handshake.buildNumber = 0x00001DB0;
|
||||
rail_send_handshake_order(rail_order);
|
||||
if (context->custom)
|
||||
{
|
||||
IFCALL(context->ServerHandshake, context, handshake);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
rail_order->client_status.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE;
|
||||
rail_send_client_status_order(rail_order);
|
||||
handshake->buildNumber = 0x00001DB0;
|
||||
rail_send_handshake_order(rail, handshake);
|
||||
|
||||
ZeroMemory(&clientStatus, sizeof(RAIL_CLIENT_STATUS_ORDER));
|
||||
clientStatus.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE;
|
||||
rail_send_client_status_order(rail, &clientStatus);
|
||||
|
||||
/* sysparam update */
|
||||
|
||||
rail_order->sysparam.params = 0;
|
||||
ZeroMemory(&sysparam, sizeof(RAIL_SYSPARAM_ORDER));
|
||||
|
||||
rail_order->sysparam.params |= SPI_MASK_SET_HIGH_CONTRAST;
|
||||
rail_order->sysparam.highContrast.colorScheme.string = NULL;
|
||||
rail_order->sysparam.highContrast.colorScheme.length = 0;
|
||||
rail_order->sysparam.highContrast.flags = 0x7E;
|
||||
sysparam.params = 0;
|
||||
|
||||
rail_order->sysparam.params |= SPI_MASK_SET_MOUSE_BUTTON_SWAP;
|
||||
rail_order->sysparam.mouseButtonSwap = FALSE;
|
||||
sysparam.params |= SPI_MASK_SET_HIGH_CONTRAST;
|
||||
sysparam.highContrast.colorScheme.string = NULL;
|
||||
sysparam.highContrast.colorScheme.length = 0;
|
||||
sysparam.highContrast.flags = 0x7E;
|
||||
|
||||
rail_order->sysparam.params |= SPI_MASK_SET_KEYBOARD_PREF;
|
||||
rail_order->sysparam.keyboardPref = FALSE;
|
||||
sysparam.params |= SPI_MASK_SET_MOUSE_BUTTON_SWAP;
|
||||
sysparam.mouseButtonSwap = FALSE;
|
||||
|
||||
rail_order->sysparam.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS;
|
||||
rail_order->sysparam.dragFullWindows = FALSE;
|
||||
sysparam.params |= SPI_MASK_SET_KEYBOARD_PREF;
|
||||
sysparam.keyboardPref = FALSE;
|
||||
|
||||
rail_order->sysparam.params |= SPI_MASK_SET_KEYBOARD_CUES;
|
||||
rail_order->sysparam.keyboardCues = FALSE;
|
||||
sysparam.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS;
|
||||
sysparam.dragFullWindows = FALSE;
|
||||
|
||||
rail_order->sysparam.params |= SPI_MASK_SET_WORK_AREA;
|
||||
rail_order->sysparam.workArea.left = 0;
|
||||
rail_order->sysparam.workArea.top = 0;
|
||||
rail_order->sysparam.workArea.right = 1024;
|
||||
rail_order->sysparam.workArea.bottom = 768;
|
||||
sysparam.params |= SPI_MASK_SET_KEYBOARD_CUES;
|
||||
sysparam.keyboardCues = FALSE;
|
||||
|
||||
rail_send_channel_event(rail_order->plugin,
|
||||
RailChannel_GetSystemParam, &rail_order->sysparam);
|
||||
sysparam.params |= SPI_MASK_SET_WORK_AREA;
|
||||
sysparam.workArea.left = 0;
|
||||
sysparam.workArea.top = 0;
|
||||
sysparam.workArea.right = 1024;
|
||||
sysparam.workArea.bottom = 768;
|
||||
|
||||
rail_send_channel_event(rail, RailChannel_GetSystemParam, &sysparam);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rail_recv_exec_result_order(rdpRailOrder* rail_order, wStream* s)
|
||||
BOOL rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* handshakeEx, wStream* s)
|
||||
{
|
||||
if (!rail_read_server_exec_result_order(s, &rail_order->exec_result))
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
|
||||
if (!rail_read_handshake_ex_order(s, handshakeEx))
|
||||
return FALSE;
|
||||
|
||||
rail_send_channel_event(rail_order->plugin,
|
||||
RailChannel_ServerExecuteResult, &rail_order->exec_result);
|
||||
if (context->custom)
|
||||
{
|
||||
IFCALL(context->ClientHandshakeEx, context, handshakeEx);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rail_recv_server_sysparam_order(rdpRailOrder* rail_order, wStream* s)
|
||||
BOOL rail_recv_exec_result_order(railPlugin* rail, RAIL_EXEC_RESULT_ORDER* execResult, wStream* s)
|
||||
{
|
||||
if (!rail_read_server_sysparam_order(s, &rail_order->sysparam))
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
|
||||
ZeroMemory(execResult, sizeof(RAIL_EXEC_RESULT_ORDER));
|
||||
|
||||
if (!rail_read_server_exec_result_order(s, execResult))
|
||||
return FALSE;
|
||||
|
||||
rail_send_channel_event(rail_order->plugin,
|
||||
RailChannel_ServerSystemParam, &rail_order->sysparam);
|
||||
if (context->custom)
|
||||
{
|
||||
IFCALL(context->ServerExecuteResult, context, execResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
rail_send_channel_event(rail, RailChannel_ServerExecuteResult, execResult);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rail_recv_server_minmaxinfo_order(rdpRailOrder* rail_order, wStream* s)
|
||||
BOOL rail_recv_server_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysparam, wStream* s)
|
||||
{
|
||||
if (!rail_read_server_minmaxinfo_order(s, &rail_order->minmaxinfo))
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
|
||||
if (!rail_read_server_sysparam_order(s, sysparam))
|
||||
return FALSE;
|
||||
|
||||
rail_send_channel_event(rail_order->plugin,
|
||||
RailChannel_ServerMinMaxInfo, &rail_order->minmaxinfo);
|
||||
if (context->custom)
|
||||
{
|
||||
IFCALL(context->ServerSystemParam, context, sysparam);
|
||||
}
|
||||
else
|
||||
{
|
||||
rail_send_channel_event(rail, RailChannel_ServerSystemParam, sysparam);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rail_recv_server_localmovesize_order(rdpRailOrder* rail_order, wStream* s)
|
||||
BOOL rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ORDER* minMaxInfo, wStream* s)
|
||||
{
|
||||
if (!rail_read_server_localmovesize_order(s, &rail_order->localmovesize))
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
|
||||
if (!rail_read_server_minmaxinfo_order(s, minMaxInfo))
|
||||
return FALSE;
|
||||
|
||||
rail_send_channel_event(rail_order->plugin,
|
||||
RailChannel_ServerLocalMoveSize, &rail_order->localmovesize);
|
||||
if (context->custom)
|
||||
{
|
||||
IFCALL(context->ServerMinMaxInfo, context, minMaxInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
rail_send_channel_event(rail, RailChannel_ServerMinMaxInfo, minMaxInfo);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rail_recv_server_get_appid_resp_order(rdpRailOrder* rail_order, wStream* s)
|
||||
BOOL rail_recv_server_localmovesize_order(railPlugin* rail, RAIL_LOCALMOVESIZE_ORDER* localMoveSize, wStream* s)
|
||||
{
|
||||
if (!rail_read_server_get_appid_resp_order(s, &rail_order->get_appid_resp))
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
|
||||
if (!rail_read_server_localmovesize_order(s, localMoveSize))
|
||||
return FALSE;
|
||||
|
||||
rail_send_channel_event(rail_order->plugin,
|
||||
RailChannel_ServerGetAppIdResponse, &rail_order->get_appid_resp);
|
||||
if (context->custom)
|
||||
{
|
||||
IFCALL(context->ServerLocalMoveSize, context, localMoveSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
rail_send_channel_event(rail, RailChannel_ServerLocalMoveSize, localMoveSize);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rail_recv_langbar_info_order(rdpRailOrder* rail_order, wStream* s)
|
||||
BOOL rail_recv_server_get_appid_resp_order(railPlugin* rail, RAIL_GET_APPID_RESP_ORDER* getAppIdResp, wStream* s)
|
||||
{
|
||||
if (!rail_read_langbar_info_order(s, &rail_order->langbar_info))
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
|
||||
if (!rail_read_server_get_appid_resp_order(s, getAppIdResp))
|
||||
return FALSE;
|
||||
|
||||
rail_send_channel_event(rail_order->plugin,
|
||||
RailChannel_ServerLanguageBarInfo, &rail_order->langbar_info);
|
||||
if (context->custom)
|
||||
{
|
||||
IFCALL(context->ServerGetAppIdResponse, context, getAppIdResp);
|
||||
}
|
||||
else
|
||||
{
|
||||
rail_send_channel_event(rail, RailChannel_ServerGetAppIdResponse, getAppIdResp);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rail_order_recv(rdpRailOrder* rail_order, wStream* s)
|
||||
BOOL rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* langBarInfo, wStream* s)
|
||||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
|
||||
if (!rail_read_langbar_info_order(s, langBarInfo))
|
||||
return FALSE;
|
||||
|
||||
if (context->custom)
|
||||
{
|
||||
IFCALL(context->ServerLanguageBarInfo, context, langBarInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
rail_send_channel_event(rail, RailChannel_ServerLanguageBarInfo, langBarInfo);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rail_order_recv(railPlugin* rail, wStream* s)
|
||||
{
|
||||
UINT16 orderType;
|
||||
UINT16 orderLength;
|
||||
@ -384,81 +468,118 @@ BOOL rail_order_recv(rdpRailOrder* rail_order, wStream* s)
|
||||
if (!rail_read_pdu_header(s, &orderType, &orderLength))
|
||||
return FALSE;
|
||||
|
||||
DEBUG_RAIL("Received %s PDU, length:%d",
|
||||
WLog_Print(rail->log, WLOG_DEBUG, "Received %s PDU, length: %d",
|
||||
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength);
|
||||
|
||||
switch (orderType)
|
||||
{
|
||||
case RDP_RAIL_ORDER_HANDSHAKE:
|
||||
return rail_recv_handshake_order(rail_order, s);
|
||||
{
|
||||
RAIL_HANDSHAKE_ORDER handshake;
|
||||
return rail_recv_handshake_order(rail, &handshake, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_HANDSHAKE_EX:
|
||||
{
|
||||
RAIL_HANDSHAKE_EX_ORDER handshakeEx;
|
||||
return rail_recv_handshake_ex_order(rail, &handshakeEx, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_EXEC_RESULT:
|
||||
return rail_recv_exec_result_order(rail_order, s);
|
||||
{
|
||||
RAIL_EXEC_RESULT_ORDER execResult;
|
||||
return rail_recv_exec_result_order(rail, &execResult, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_SYSPARAM:
|
||||
return rail_recv_server_sysparam_order(rail_order, s);
|
||||
{
|
||||
RAIL_SYSPARAM_ORDER sysparam;
|
||||
return rail_recv_server_sysparam_order(rail, &sysparam, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_MINMAXINFO:
|
||||
return rail_recv_server_minmaxinfo_order(rail_order, s);
|
||||
{
|
||||
RAIL_MINMAXINFO_ORDER minMaxInfo;
|
||||
return rail_recv_server_minmaxinfo_order(rail, &minMaxInfo, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_LOCALMOVESIZE:
|
||||
return rail_recv_server_localmovesize_order(rail_order, s);
|
||||
{
|
||||
RAIL_LOCALMOVESIZE_ORDER localMoveSize;
|
||||
return rail_recv_server_localmovesize_order(rail, &localMoveSize, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_GET_APPID_RESP:
|
||||
return rail_recv_server_get_appid_resp_order(rail_order, s);
|
||||
{
|
||||
RAIL_GET_APPID_RESP_ORDER getAppIdResp;
|
||||
return rail_recv_server_get_appid_resp_order(rail, &getAppIdResp, s);
|
||||
}
|
||||
|
||||
case RDP_RAIL_ORDER_LANGBARINFO:
|
||||
return rail_recv_langbar_info_order(rail_order, s);
|
||||
{
|
||||
RAIL_LANGBAR_INFO_ORDER langBarInfo;
|
||||
return rail_recv_langbar_info_order(rail, &langBarInfo, s);
|
||||
}
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unknown RAIL PDU order reveived.");
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void rail_send_handshake_order(rdpRailOrder* rail_order)
|
||||
void rail_send_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake)
|
||||
{
|
||||
wStream* s;
|
||||
s = rail_pdu_init(RAIL_HANDSHAKE_ORDER_LENGTH);
|
||||
rail_write_handshake_order(s, &rail_order->handshake);
|
||||
rail_send_pdu(rail_order, s, RDP_RAIL_ORDER_HANDSHAKE);
|
||||
rail_write_handshake_order(s, handshake);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_HANDSHAKE);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_status_order(rdpRailOrder* rail_order)
|
||||
void rail_send_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
||||
{
|
||||
wStream* s;
|
||||
s = rail_pdu_init(RAIL_HANDSHAKE_EX_ORDER_LENGTH);
|
||||
rail_write_handshake_ex_order(s, handshakeEx);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_HANDSHAKE_EX);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_status_order(railPlugin* rail, RAIL_CLIENT_STATUS_ORDER* clientStatus)
|
||||
{
|
||||
wStream* s;
|
||||
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, RDP_RAIL_ORDER_CLIENTSTATUS);
|
||||
rail_write_client_status_order(s, clientStatus);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_CLIENTSTATUS);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_exec_order(rdpRailOrder* rail_order)
|
||||
void rail_send_client_exec_order(railPlugin* rail, RAIL_EXEC_ORDER* exec)
|
||||
{
|
||||
wStream* s;
|
||||
int length;
|
||||
|
||||
length = RAIL_EXEC_ORDER_LENGTH +
|
||||
rail_order->exec.exeOrFile.length +
|
||||
rail_order->exec.workingDir.length +
|
||||
rail_order->exec.arguments.length;
|
||||
exec->exeOrFile.length +
|
||||
exec->workingDir.length +
|
||||
exec->arguments.length;
|
||||
|
||||
s = rail_pdu_init(RAIL_EXEC_ORDER_LENGTH);
|
||||
rail_write_client_exec_order(s, &rail_order->exec);
|
||||
rail_send_pdu(rail_order, s, RDP_RAIL_ORDER_EXEC);
|
||||
rail_write_client_exec_order(s, exec);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_EXEC);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_sysparam_order(rdpRailOrder* rail_order)
|
||||
void rail_send_client_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
wStream* s;
|
||||
int length;
|
||||
|
||||
length = RAIL_SYSPARAM_ORDER_LENGTH;
|
||||
|
||||
switch (rail_order->sysparam.param)
|
||||
switch (sysparam->param)
|
||||
{
|
||||
case SPI_SET_DRAG_FULL_WINDOWS:
|
||||
case SPI_SET_KEYBOARD_CUES:
|
||||
@ -474,139 +595,142 @@ void rail_send_client_sysparam_order(rdpRailOrder* rail_order)
|
||||
break;
|
||||
|
||||
case SPI_SET_HIGH_CONTRAST:
|
||||
length += rail_order->sysparam.highContrast.colorSchemeLength + 10;
|
||||
length += sysparam->highContrast.colorSchemeLength + 10;
|
||||
break;
|
||||
}
|
||||
|
||||
s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8);
|
||||
rail_write_client_sysparam_order(s, &rail_order->sysparam);
|
||||
rail_send_pdu(rail_order, s, RDP_RAIL_ORDER_SYSPARAM);
|
||||
rail_write_client_sysparam_order(s, sysparam);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSPARAM);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_sysparams_order(rdpRailOrder* rail_order)
|
||||
void rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
if (rail_order->sysparam.params & SPI_MASK_SET_HIGH_CONTRAST)
|
||||
if (sysparam->params & SPI_MASK_SET_HIGH_CONTRAST)
|
||||
{
|
||||
rail_order->sysparam.param = SPI_SET_HIGH_CONTRAST;
|
||||
rail_send_client_sysparam_order(rail_order);
|
||||
sysparam->param = SPI_SET_HIGH_CONTRAST;
|
||||
rail_send_client_sysparam_order(rail, sysparam);
|
||||
}
|
||||
|
||||
if (rail_order->sysparam.params & SPI_MASK_TASKBAR_POS)
|
||||
if (sysparam->params & SPI_MASK_TASKBAR_POS)
|
||||
{
|
||||
rail_order->sysparam.param = SPI_TASKBAR_POS;
|
||||
rail_send_client_sysparam_order(rail_order);
|
||||
sysparam->param = SPI_TASKBAR_POS;
|
||||
rail_send_client_sysparam_order(rail, sysparam);
|
||||
}
|
||||
|
||||
if (rail_order->sysparam.params & SPI_MASK_SET_MOUSE_BUTTON_SWAP)
|
||||
if (sysparam->params & SPI_MASK_SET_MOUSE_BUTTON_SWAP)
|
||||
{
|
||||
rail_order->sysparam.param = SPI_SET_MOUSE_BUTTON_SWAP;
|
||||
rail_send_client_sysparam_order(rail_order);
|
||||
sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP;
|
||||
rail_send_client_sysparam_order(rail, sysparam);
|
||||
}
|
||||
|
||||
if (rail_order->sysparam.params & SPI_MASK_SET_KEYBOARD_PREF)
|
||||
if (sysparam->params & SPI_MASK_SET_KEYBOARD_PREF)
|
||||
{
|
||||
rail_order->sysparam.param = SPI_SET_KEYBOARD_PREF;
|
||||
rail_send_client_sysparam_order(rail_order);
|
||||
sysparam->param = SPI_SET_KEYBOARD_PREF;
|
||||
rail_send_client_sysparam_order(rail, sysparam);
|
||||
}
|
||||
|
||||
if (rail_order->sysparam.params & SPI_MASK_SET_DRAG_FULL_WINDOWS)
|
||||
if (sysparam->params & SPI_MASK_SET_DRAG_FULL_WINDOWS)
|
||||
{
|
||||
rail_order->sysparam.param = SPI_SET_DRAG_FULL_WINDOWS;
|
||||
rail_send_client_sysparam_order(rail_order);
|
||||
sysparam->param = SPI_SET_DRAG_FULL_WINDOWS;
|
||||
rail_send_client_sysparam_order(rail, sysparam);
|
||||
}
|
||||
|
||||
if (rail_order->sysparam.params & SPI_MASK_SET_KEYBOARD_CUES)
|
||||
if (sysparam->params & SPI_MASK_SET_KEYBOARD_CUES)
|
||||
{
|
||||
rail_order->sysparam.param = SPI_SET_KEYBOARD_CUES;
|
||||
rail_send_client_sysparam_order(rail_order);
|
||||
sysparam->param = SPI_SET_KEYBOARD_CUES;
|
||||
rail_send_client_sysparam_order(rail, sysparam);
|
||||
}
|
||||
|
||||
if (rail_order->sysparam.params & SPI_MASK_SET_WORK_AREA)
|
||||
if (sysparam->params & SPI_MASK_SET_WORK_AREA)
|
||||
{
|
||||
rail_order->sysparam.param = SPI_SET_WORK_AREA;
|
||||
rail_send_client_sysparam_order(rail_order);
|
||||
sysparam->param = SPI_SET_WORK_AREA;
|
||||
rail_send_client_sysparam_order(rail, sysparam);
|
||||
}
|
||||
}
|
||||
|
||||
void rail_send_client_activate_order(rdpRailOrder* rail_order)
|
||||
void rail_send_client_activate_order(railPlugin* rail, RAIL_ACTIVATE_ORDER* activate)
|
||||
{
|
||||
wStream* s;
|
||||
s = rail_pdu_init(RAIL_ACTIVATE_ORDER_LENGTH);
|
||||
rail_write_client_activate_order(s, &rail_order->activate);
|
||||
rail_send_pdu(rail_order, s, RDP_RAIL_ORDER_ACTIVATE);
|
||||
rail_write_client_activate_order(s, activate);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_ACTIVATE);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_sysmenu_order(rdpRailOrder* rail_order)
|
||||
void rail_send_client_sysmenu_order(railPlugin* rail, RAIL_SYSMENU_ORDER* sysmenu)
|
||||
{
|
||||
wStream* s;
|
||||
s = rail_pdu_init(RAIL_SYSMENU_ORDER_LENGTH);
|
||||
rail_write_client_sysmenu_order(s, &rail_order->sysmenu);
|
||||
rail_send_pdu(rail_order, s, RDP_RAIL_ORDER_SYSMENU);
|
||||
rail_write_client_sysmenu_order(s, sysmenu);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSMENU);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_syscommand_order(rdpRailOrder* rail_order)
|
||||
void rail_send_client_syscommand_order(railPlugin* rail, RAIL_SYSCOMMAND_ORDER* syscommand)
|
||||
{
|
||||
wStream* s;
|
||||
s = rail_pdu_init(RAIL_SYSCOMMAND_ORDER_LENGTH);
|
||||
rail_write_client_syscommand_order(s, &rail_order->syscommand);
|
||||
rail_send_pdu(rail_order, s, RDP_RAIL_ORDER_SYSCOMMAND);
|
||||
rail_write_client_syscommand_order(s, syscommand);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSCOMMAND);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_notify_event_order(rdpRailOrder* rail_order)
|
||||
void rail_send_client_notify_event_order(railPlugin* rail, RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
|
||||
{
|
||||
wStream* s;
|
||||
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, RDP_RAIL_ORDER_NOTIFY_EVENT);
|
||||
rail_write_client_notify_event_order(s, notifyEvent);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_NOTIFY_EVENT);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_window_move_order(rdpRailOrder* rail_order)
|
||||
void rail_send_client_window_move_order(railPlugin* rail, RAIL_WINDOW_MOVE_ORDER* windowMove)
|
||||
{
|
||||
wStream* s;
|
||||
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, RDP_RAIL_ORDER_WINDOWMOVE);
|
||||
rail_write_client_window_move_order(s, windowMove);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_WINDOWMOVE);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_get_appid_req_order(rdpRailOrder* rail_order)
|
||||
void rail_send_client_get_appid_req_order(railPlugin* rail, RAIL_GET_APPID_REQ_ORDER* getAppIdReq)
|
||||
{
|
||||
wStream* s;
|
||||
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, RDP_RAIL_ORDER_GET_APPID_REQ);
|
||||
rail_write_client_get_appid_req_order(s, getAppIdReq);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_GET_APPID_REQ);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
void rail_send_client_langbar_info_order(rdpRailOrder* rail_order)
|
||||
void rail_send_client_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* langBarInfo)
|
||||
{
|
||||
wStream* s;
|
||||
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, RDP_RAIL_ORDER_LANGBARINFO);
|
||||
rail_write_langbar_info_order(s, langBarInfo);
|
||||
rail_send_pdu(rail, s, RDP_RAIL_ORDER_LANGBARINFO);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
rdpRailOrder* rail_order_new()
|
||||
{
|
||||
rdpRailOrder* rail_order;
|
||||
rdpRailOrder* railOrder;
|
||||
|
||||
rail_order = (rdpRailOrder*) malloc(sizeof(rdpRailOrder));
|
||||
ZeroMemory(rail_order, sizeof(rdpRailOrder));
|
||||
return rail_order;
|
||||
railOrder = (rdpRailOrder*) malloc(sizeof(rdpRailOrder));
|
||||
|
||||
if (railOrder)
|
||||
{
|
||||
ZeroMemory(railOrder, sizeof(rdpRailOrder));
|
||||
}
|
||||
|
||||
return railOrder;
|
||||
}
|
||||
|
||||
void rail_order_free(rdpRailOrder* rail_order)
|
||||
void rail_order_free(rdpRailOrder* railOrder)
|
||||
{
|
||||
if (rail_order != NULL)
|
||||
if (railOrder)
|
||||
{
|
||||
|
||||
free(rail_order);
|
||||
free(railOrder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,22 +41,25 @@ void rail_write_client_window_move_order(wStream* s, RAIL_WINDOW_MOVE_ORDER* win
|
||||
void rail_write_client_get_appid_req_order(wStream* s, RAIL_GET_APPID_REQ_ORDER* get_appid_req);
|
||||
void rail_write_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbar_info);
|
||||
|
||||
BOOL rail_order_recv(rdpRailOrder* rail_order, wStream* s);
|
||||
BOOL rail_order_recv(railPlugin* rail, wStream* s);
|
||||
|
||||
void rail_send_handshake_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_status_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_exec_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_sysparam_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_sysparams_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_activate_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_sysmenu_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_syscommand_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_notify_event_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_window_move_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_get_appid_req_order(rdpRailOrder* rail_order);
|
||||
void rail_send_client_langbar_info_order(rdpRailOrder* rail_order);
|
||||
void rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType);
|
||||
|
||||
void rail_send_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake);
|
||||
void rail_send_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* handshakeEx);
|
||||
void rail_send_client_status_order(railPlugin* rail, RAIL_CLIENT_STATUS_ORDER* clientStatus);
|
||||
void rail_send_client_exec_order(railPlugin* rail, RAIL_EXEC_ORDER* exec);
|
||||
void rail_send_client_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysparam);
|
||||
void rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysparam);
|
||||
void rail_send_client_activate_order(railPlugin* rail, RAIL_ACTIVATE_ORDER* activate);
|
||||
void rail_send_client_sysmenu_order(railPlugin* rail, RAIL_SYSMENU_ORDER* sysmenu);
|
||||
void rail_send_client_syscommand_order(railPlugin* rail, RAIL_SYSCOMMAND_ORDER* syscommand);
|
||||
void rail_send_client_notify_event_order(railPlugin* rail, RAIL_NOTIFY_EVENT_ORDER* notifyEvent);
|
||||
void rail_send_client_window_move_order(railPlugin* rail, RAIL_WINDOW_MOVE_ORDER* windowMove);
|
||||
void rail_send_client_get_appid_req_order(railPlugin* rail, RAIL_GET_APPID_REQ_ORDER* getAppIdReq);
|
||||
void rail_send_client_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* langBarInfo);
|
||||
|
||||
rdpRailOrder* rail_order_new(void);
|
||||
void rail_order_free(rdpRailOrder* rail_order);
|
||||
void rail_order_free(rdpRailOrder* railOrder);
|
||||
|
||||
#endif /* __RAIL_ORDERS_H */
|
||||
|
@ -40,10 +40,15 @@ const char* const RAIL_ORDER_TYPE_STRINGS[] =
|
||||
"Language Bar Info",
|
||||
"Get Application ID Request",
|
||||
"Get Application ID Response",
|
||||
"Execute Result"
|
||||
"Execute Result",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
};
|
||||
|
||||
|
||||
void rail_string_to_unicode_string(char* string, RAIL_UNICODE_STRING* unicode_string)
|
||||
{
|
||||
WCHAR* buffer = NULL;
|
||||
@ -55,7 +60,7 @@ void rail_string_to_unicode_string(char* string, RAIL_UNICODE_STRING* unicode_st
|
||||
unicode_string->string = NULL;
|
||||
unicode_string->length = 0;
|
||||
|
||||
if (string == NULL || strlen(string) < 1)
|
||||
if (!string || strlen(string) < 1)
|
||||
return;
|
||||
|
||||
length = ConvertToUnicode(CP_UTF8, 0, string, -1, &buffer, 0) * 2;
|
||||
@ -68,8 +73,10 @@ BOOL rail_read_pdu_header(wStream* s, UINT16* orderType, UINT16* orderLength)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, *orderType); /* orderType (2 bytes) */
|
||||
Stream_Read_UINT16(s, *orderLength); /* orderLength (2 bytes) */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -91,7 +98,9 @@ BOOL rail_read_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, handshake->buildNumber); /* buildNumber (4 bytes) */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -100,3 +109,19 @@ void rail_write_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake)
|
||||
Stream_Write_UINT32(s, handshake->buildNumber); /* buildNumber (4 bytes) */
|
||||
}
|
||||
|
||||
BOOL rail_read_handshake_ex_order(wStream* s, RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, handshakeEx->buildNumber); /* buildNumber (4 bytes) */
|
||||
Stream_Read_UINT32(s, handshakeEx->railHandshakeFlags); /* railHandshakeFlags (4 bytes) */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void rail_write_handshake_ex_order(wStream* s, RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
||||
{
|
||||
Stream_Write_UINT32(s, handshakeEx->buildNumber); /* buildNumber (4 bytes) */
|
||||
Stream_Write_UINT32(s, handshakeEx->railHandshakeFlags); /* railHandshakeFlags (4 bytes) */
|
||||
}
|
||||
|
@ -24,19 +24,13 @@
|
||||
|
||||
#include <freerdp/rail.h>
|
||||
|
||||
#ifdef WITH_DEBUG_RAIL
|
||||
#define DEBUG_RAIL(fmt, ...) DEBUG_CLASS(RAIL, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_RAIL(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
extern const char* const RAIL_ORDER_TYPE_STRINGS[];
|
||||
|
||||
|
||||
#define RAIL_PDU_HEADER_LENGTH 4
|
||||
|
||||
/* Fixed length of PDUs, excluding variable lengths */
|
||||
#define RAIL_HANDSHAKE_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_HANDSHAKE_EX_ORDER_LENGTH 8 /* fixed */
|
||||
#define RAIL_CLIENT_STATUS_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_EXEC_ORDER_LENGTH 8 /* variable */
|
||||
#define RAIL_SYSPARAM_ORDER_LENGTH 4 /* variable */
|
||||
@ -74,6 +68,8 @@ typedef struct rdp_rail_order rdpRailOrder;
|
||||
void rail_string_to_unicode_string(char* string, RAIL_UNICODE_STRING* unicode_string);
|
||||
BOOL rail_read_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake);
|
||||
void rail_write_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake);
|
||||
BOOL rail_read_handshake_ex_order(wStream* s, RAIL_HANDSHAKE_EX_ORDER* handshakeEx);
|
||||
void rail_write_handshake_ex_order(wStream* s, RAIL_HANDSHAKE_EX_ORDER* handshakeEx);
|
||||
|
||||
wStream* rail_pdu_init(int length);
|
||||
BOOL rail_read_pdu_header(wStream* s, UINT16* orderType, UINT16* orderLength);
|
||||
|
@ -43,4 +43,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
@ -27,50 +27,64 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
#include "devman.h"
|
||||
|
||||
DEVMAN* devman_new(rdpSvcPlugin* plugin)
|
||||
static void devman_device_free(DEVICE* device)
|
||||
{
|
||||
IFCALL(device->Free, device);
|
||||
}
|
||||
|
||||
DEVMAN* devman_new(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
DEVMAN* devman;
|
||||
|
||||
devman = (DEVMAN*) malloc(sizeof(DEVMAN));
|
||||
ZeroMemory(devman, sizeof(DEVMAN));
|
||||
|
||||
devman->plugin = plugin;
|
||||
devman->plugin = (void*) rdpdr;
|
||||
devman->id_sequence = 1;
|
||||
devman->devices = list_new();
|
||||
|
||||
devman->devices = ListDictionary_New(TRUE);
|
||||
|
||||
ListDictionary_Object(devman->devices)->fnObjectFree =
|
||||
(OBJECT_FREE_FN) devman_device_free;
|
||||
|
||||
return devman;
|
||||
}
|
||||
|
||||
void devman_free(DEVMAN* devman)
|
||||
{
|
||||
DEVICE* device;
|
||||
|
||||
while ((device = (DEVICE*) list_dequeue(devman->devices)) != NULL)
|
||||
IFCALL(device->Free, device);
|
||||
|
||||
list_free(devman->devices);
|
||||
|
||||
ListDictionary_Free(devman->devices);
|
||||
free(devman);
|
||||
}
|
||||
|
||||
static void devman_register_device(DEVMAN* devman, DEVICE* device)
|
||||
{
|
||||
device->id = devman->id_sequence++;
|
||||
list_add(devman->devices, device);
|
||||
void* key = NULL;
|
||||
|
||||
DEBUG_SVC("device %d.%s registered", device->id, device->name);
|
||||
device->id = devman->id_sequence++;
|
||||
key = (void*) (size_t) device->id;
|
||||
|
||||
ListDictionary_Add(devman->devices, key, device);
|
||||
}
|
||||
|
||||
DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id)
|
||||
{
|
||||
DEVICE* device = NULL;
|
||||
void* key = (void*) (size_t) id;
|
||||
|
||||
device = (DEVICE*) ListDictionary_GetItemValue(devman->devices, key);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static char DRIVE_SERVICE_NAME[] = "drive";
|
||||
@ -102,7 +116,7 @@ BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device)
|
||||
fprintf(stderr, "Loading device service %s (static)\n", ServiceName);
|
||||
entry = (PDEVICE_SERVICE_ENTRY) freerdp_load_channel_addin_entry(ServiceName, NULL, "DeviceServiceEntry", 0);
|
||||
|
||||
if (entry == NULL)
|
||||
if (!entry)
|
||||
return FALSE;
|
||||
|
||||
ep.devman = devman;
|
||||
@ -113,19 +127,3 @@ BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
DEVICE* device;
|
||||
|
||||
for (item = devman->devices->head; item; item = item->next)
|
||||
{
|
||||
device = (DEVICE*) item->data;
|
||||
|
||||
if (device->id == id)
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -21,10 +21,12 @@
|
||||
#ifndef FREERDP_CHANNEL_RDPDR_CLIENT_DEVMAN_H
|
||||
#define FREERDP_CHANNEL_RDPDR_CLIENT_DEVMAN_H
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device);
|
||||
DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id);
|
||||
|
||||
DEVMAN* devman_new(rdpSvcPlugin* plugin);
|
||||
DEVMAN* devman_new(rdpdrPlugin* rdpdr);
|
||||
void devman_free(DEVMAN* devman);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_DEVMAN_H */
|
||||
|
@ -27,9 +27,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
#include "devman.h"
|
||||
@ -37,8 +35,6 @@
|
||||
|
||||
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, TRUE);
|
||||
Stream_Free(irp->output, TRUE);
|
||||
|
||||
@ -49,31 +45,28 @@ static void irp_complete(IRP* irp)
|
||||
{
|
||||
int pos;
|
||||
|
||||
DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
|
||||
|
||||
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);
|
||||
rdpdr_send((rdpdrPlugin*) irp->devman->plugin, irp->output);
|
||||
irp->output = NULL;
|
||||
|
||||
irp_free(irp);
|
||||
}
|
||||
|
||||
IRP* irp_new(DEVMAN* devman, wStream* data_in)
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
{
|
||||
IRP* irp;
|
||||
UINT32 DeviceId;
|
||||
DEVICE* device;
|
||||
|
||||
Stream_Read_UINT32(data_in, DeviceId);
|
||||
Stream_Read_UINT32(s, DeviceId);
|
||||
device = devman_get_device_by_id(devman, DeviceId);
|
||||
|
||||
if (device == NULL)
|
||||
if (!device)
|
||||
{
|
||||
DEBUG_WARN("unknown DeviceId %d", DeviceId);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -82,11 +75,11 @@ 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);
|
||||
irp->input = data_in;
|
||||
Stream_Read_UINT32(s, irp->FileId);
|
||||
Stream_Read_UINT32(s, irp->CompletionId);
|
||||
Stream_Read_UINT32(s, irp->MajorFunction);
|
||||
Stream_Read_UINT32(s, irp->MinorFunction);
|
||||
irp->input = s;
|
||||
|
||||
irp->output = Stream_New(NULL, 256);
|
||||
Stream_Write_UINT16(irp->output, RDPDR_CTYP_CORE);
|
||||
@ -98,8 +91,5 @@ IRP* irp_new(DEVMAN* devman, wStream* data_in)
|
||||
irp->Complete = irp_complete;
|
||||
irp->Discard = irp_free;
|
||||
|
||||
DEBUG_SVC("DeviceId %d FileId %d CompletionId %d MajorFunction 0x%X MinorFunction 0x%x",
|
||||
irp->device->id, irp->FileId, irp->CompletionId, irp->MajorFunction, irp->MinorFunction);
|
||||
|
||||
return irp;
|
||||
}
|
||||
|
@ -23,6 +23,6 @@
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
IRP* irp_new(DEVMAN* devman, wStream* data_in);
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H */
|
||||
|
@ -26,8 +26,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
#include "rdpdr_capabilities.h"
|
||||
@ -162,7 +162,6 @@ void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("Unknown capabilityType %d", capabilityType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -186,5 +185,5 @@ void rdpdr_send_capability_response(rdpdrPlugin* rdpdr)
|
||||
rdpdr_write_drive_capset(rdpdr, s);
|
||||
rdpdr_write_smartcard_capset(rdpdr, s);
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*)rdpdr, s);
|
||||
rdpdr_send(rdpdr, s);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* data_in);
|
||||
void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s);
|
||||
void rdpdr_send_capability_response(rdpdrPlugin* rdpdr);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_CAPABILITIES_H */
|
||||
|
@ -27,12 +27,11 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@ -45,15 +44,14 @@
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
static void rdpdr_process_connect(rdpSvcPlugin* plugin)
|
||||
static void rdpdr_process_connect(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
int index;
|
||||
RDPDR_DEVICE* device;
|
||||
rdpSettings* settings;
|
||||
rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin;
|
||||
|
||||
rdpdr->devman = devman_new(plugin);
|
||||
settings = (rdpSettings*) plugin->channel_entry_points.pExtendedData;
|
||||
rdpdr->devman = devman_new(rdpdr);
|
||||
settings = (rdpSettings*) rdpdr->channelEntryPoints.pExtendedData;
|
||||
|
||||
strncpy(rdpdr->computerName, settings->ComputerName, sizeof(rdpdr->computerName) - 1);
|
||||
|
||||
@ -64,34 +62,32 @@ static void rdpdr_process_connect(rdpSvcPlugin* plugin)
|
||||
}
|
||||
}
|
||||
|
||||
static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* data_in)
|
||||
static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
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);
|
||||
Stream_Read_UINT16(s, rdpdr->versionMajor);
|
||||
Stream_Read_UINT16(s, rdpdr->versionMinor);
|
||||
Stream_Read_UINT32(s, rdpdr->clientID);
|
||||
}
|
||||
|
||||
static void rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
wStream* data_out;
|
||||
wStream* s;
|
||||
|
||||
data_out = Stream_New(NULL, 12);
|
||||
s = Stream_New(NULL, 12);
|
||||
|
||||
Stream_Write_UINT16(data_out, RDPDR_CTYP_CORE);
|
||||
Stream_Write_UINT16(data_out, PAKID_CORE_CLIENTID_CONFIRM);
|
||||
Stream_Write_UINT16(s, RDPDR_CTYP_CORE);
|
||||
Stream_Write_UINT16(s, 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(s, rdpdr->versionMajor);
|
||||
Stream_Write_UINT16(s, rdpdr->versionMinor);
|
||||
Stream_Write_UINT32(s, (UINT32) rdpdr->clientID);
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out);
|
||||
rdpdr_send(rdpdr, s);
|
||||
}
|
||||
|
||||
static void rdpdr_send_client_name_request(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
wStream* data_out;
|
||||
wStream* s;
|
||||
WCHAR* computerNameW = NULL;
|
||||
size_t computerNameLenW;
|
||||
|
||||
@ -100,70 +96,74 @@ static void rdpdr_send_client_name_request(rdpdrPlugin* rdpdr)
|
||||
|
||||
computerNameLenW = ConvertToUnicode(CP_UTF8, 0, rdpdr->computerName, -1, &computerNameW, 0) * 2;
|
||||
|
||||
data_out = Stream_New(NULL, 16 + computerNameLenW + 2);
|
||||
s = 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(s, RDPDR_CTYP_CORE);
|
||||
Stream_Write_UINT16(s, 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(s, 1); /* unicodeFlag, 0 for ASCII and 1 for Unicode */
|
||||
Stream_Write_UINT32(s, 0); /* codePage, must be set to zero */
|
||||
Stream_Write_UINT32(s, computerNameLenW + 2); /* computerNameLen, including null terminator */
|
||||
Stream_Write(s, computerNameW, computerNameLenW);
|
||||
Stream_Write_UINT16(s, 0); /* null terminator */
|
||||
|
||||
free(computerNameW);
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out);
|
||||
rdpdr_send(rdpdr, s);
|
||||
}
|
||||
|
||||
static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* data_in)
|
||||
static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 versionMajor;
|
||||
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(s, versionMajor);
|
||||
Stream_Read_UINT16(s, versionMinor);
|
||||
Stream_Read_UINT32(s, clientID);
|
||||
|
||||
if (versionMajor != rdpdr->versionMajor || versionMinor != rdpdr->versionMinor)
|
||||
{
|
||||
DEBUG_WARN("unmatched version %d.%d", versionMajor, versionMinor);
|
||||
rdpdr->versionMajor = versionMajor;
|
||||
rdpdr->versionMinor = versionMinor;
|
||||
}
|
||||
|
||||
if (clientID != rdpdr->clientID)
|
||||
{
|
||||
DEBUG_WARN("unmatched clientID %d", clientID);
|
||||
rdpdr->clientID = clientID;
|
||||
}
|
||||
}
|
||||
|
||||
static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL user_loggedon)
|
||||
static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL userLoggedOn)
|
||||
{
|
||||
int i;
|
||||
int pos;
|
||||
BYTE c;
|
||||
int pos;
|
||||
int index;
|
||||
wStream* s;
|
||||
UINT32 count;
|
||||
int data_len;
|
||||
int count_pos;
|
||||
wStream* data_out;
|
||||
DEVICE* device;
|
||||
LIST_ITEM* item;
|
||||
int keyCount;
|
||||
ULONG_PTR* pKeys;
|
||||
|
||||
data_out = Stream_New(NULL, 256);
|
||||
s = Stream_New(NULL, 256);
|
||||
|
||||
Stream_Write_UINT16(data_out, RDPDR_CTYP_CORE);
|
||||
Stream_Write_UINT16(data_out, PAKID_CORE_DEVICELIST_ANNOUNCE);
|
||||
Stream_Write_UINT16(s, RDPDR_CTYP_CORE);
|
||||
Stream_Write_UINT16(s, PAKID_CORE_DEVICELIST_ANNOUNCE);
|
||||
|
||||
count_pos = Stream_GetPosition(data_out);
|
||||
count_pos = Stream_GetPosition(s);
|
||||
count = 0;
|
||||
Stream_Seek_UINT32(data_out); /* deviceCount */
|
||||
|
||||
for (item = rdpdr->devman->devices->head; item; item = item->next)
|
||||
Stream_Seek_UINT32(s); /* deviceCount */
|
||||
|
||||
pKeys = NULL;
|
||||
keyCount = ListDictionary_GetKeys(rdpdr->devman->devices, &pKeys);
|
||||
|
||||
for (index = 0; index < keyCount; index++)
|
||||
{
|
||||
device = (DEVICE*) item->data;
|
||||
device = (DEVICE*) ListDictionary_GetItemValue(rdpdr->devman->devices, (void*) pKeys[index]);
|
||||
|
||||
/**
|
||||
* 1. versionMinor 0x0005 doesn't send PAKID_CORE_USER_LOGGEDON
|
||||
@ -173,29 +173,29 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
*/
|
||||
|
||||
if ((rdpdr->versionMinor == 0x0005) ||
|
||||
(device->type == RDPDR_DTYP_SMARTCARD) || user_loggedon)
|
||||
(device->type == RDPDR_DTYP_SMARTCARD) || userLoggedOn)
|
||||
{
|
||||
data_len = (device->data == NULL ? 0 : Stream_GetPosition(device->data));
|
||||
Stream_EnsureRemainingCapacity(data_out, 20 + data_len);
|
||||
Stream_EnsureRemainingCapacity(s, 20 + data_len);
|
||||
|
||||
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);
|
||||
Stream_Write_UINT32(s, device->type); /* deviceType */
|
||||
Stream_Write_UINT32(s, device->id); /* deviceID */
|
||||
strncpy((char*) Stream_Pointer(s), device->name, 8);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
Stream_Peek_UINT8(data_out, c);
|
||||
Stream_Peek_UINT8(s, c);
|
||||
|
||||
if (c > 0x7F)
|
||||
Stream_Write_UINT8(data_out, '_');
|
||||
Stream_Write_UINT8(s, '_');
|
||||
else
|
||||
Stream_Seek_UINT8(data_out);
|
||||
Stream_Seek_UINT8(s);
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(data_out, data_len);
|
||||
Stream_Write_UINT32(s, data_len);
|
||||
|
||||
if (data_len > 0)
|
||||
Stream_Write(data_out, Stream_Buffer(device->data), data_len);
|
||||
Stream_Write(s, Stream_Buffer(device->data), data_len);
|
||||
|
||||
count++;
|
||||
|
||||
@ -204,22 +204,25 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (pKeys)
|
||||
free(pKeys);
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out);
|
||||
pos = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, count_pos);
|
||||
Stream_Write_UINT32(s, count);
|
||||
Stream_SetPosition(s, pos);
|
||||
Stream_SealLength(s);
|
||||
|
||||
rdpdr_send(rdpdr, s);
|
||||
}
|
||||
|
||||
static BOOL rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* data_in)
|
||||
static BOOL rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
IRP* irp;
|
||||
|
||||
irp = irp_new(rdpdr->devman, data_in);
|
||||
irp = irp_new(rdpdr->devman, s);
|
||||
|
||||
if (irp == NULL)
|
||||
if (!irp)
|
||||
return FALSE;
|
||||
|
||||
IFCALL(irp->device->IRPRequest, irp->device, irp);
|
||||
@ -227,87 +230,312 @@ static BOOL rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* data_in)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void rdpdr_process_receive(rdpSvcPlugin* plugin, wStream* data_in)
|
||||
static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 component;
|
||||
UINT16 packetID;
|
||||
UINT32 deviceID;
|
||||
UINT32 status;
|
||||
rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin;
|
||||
|
||||
Stream_Read_UINT16(data_in, component);
|
||||
Stream_Read_UINT16(data_in, packetID);
|
||||
Stream_Read_UINT16(s, component);
|
||||
Stream_Read_UINT16(s, packetID);
|
||||
|
||||
if (component == RDPDR_CTYP_CORE)
|
||||
{
|
||||
switch (packetID)
|
||||
{
|
||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||
DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_SERVER_ANNOUNCE");
|
||||
rdpdr_process_server_announce_request(rdpdr, data_in);
|
||||
rdpdr_process_server_announce_request(rdpdr, s);
|
||||
rdpdr_send_client_announce_reply(rdpdr);
|
||||
rdpdr_send_client_name_request(rdpdr);
|
||||
break;
|
||||
|
||||
case PAKID_CORE_SERVER_CAPABILITY:
|
||||
DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_SERVER_CAPABILITY");
|
||||
rdpdr_process_capability_request(rdpdr, data_in);
|
||||
rdpdr_process_capability_request(rdpdr, s);
|
||||
rdpdr_send_capability_response(rdpdr);
|
||||
break;
|
||||
|
||||
case PAKID_CORE_CLIENTID_CONFIRM:
|
||||
DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_CLIENTID_CONFIRM");
|
||||
rdpdr_process_server_clientid_confirm(rdpdr, data_in);
|
||||
rdpdr_process_server_clientid_confirm(rdpdr, s);
|
||||
rdpdr_send_device_list_announce_request(rdpdr, FALSE);
|
||||
break;
|
||||
|
||||
case PAKID_CORE_USER_LOGGEDON:
|
||||
DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_USER_LOGGEDON");
|
||||
rdpdr_send_device_list_announce_request(rdpdr, TRUE);
|
||||
break;
|
||||
|
||||
case PAKID_CORE_DEVICE_REPLY:
|
||||
/* connect to a specific resource */
|
||||
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);
|
||||
Stream_Read_UINT32(s, deviceID);
|
||||
Stream_Read_UINT32(s, status);
|
||||
break;
|
||||
|
||||
case PAKID_CORE_DEVICE_IOREQUEST:
|
||||
DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_DEVICE_IOREQUEST");
|
||||
if (rdpdr_process_irp(rdpdr, data_in))
|
||||
data_in = NULL;
|
||||
if (rdpdr_process_irp(rdpdr, s))
|
||||
s = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("RDPDR_CTYP_CORE / unknown packetID: 0x%02X", packetID);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else if (component == RDPDR_CTYP_PRN)
|
||||
{
|
||||
DEBUG_SVC("RDPDR_CTYP_PRN");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_WARN("RDPDR component: 0x%02X packetID: 0x%02X", component, packetID);
|
||||
|
||||
}
|
||||
|
||||
Stream_Free(data_in, TRUE);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
static void rdpdr_process_event(rdpSvcPlugin* plugin, wMessage* event)
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
|
||||
static wListDictionary* g_InitHandles;
|
||||
static wListDictionary* g_OpenHandles;
|
||||
|
||||
void rdpdr_add_init_handle_data(void* pInitHandle, void* pUserData)
|
||||
{
|
||||
freerdp_event_free(event);
|
||||
if (!g_InitHandles)
|
||||
g_InitHandles = ListDictionary_New(TRUE);
|
||||
|
||||
ListDictionary_Add(g_InitHandles, pInitHandle, pUserData);
|
||||
}
|
||||
|
||||
static void rdpdr_process_terminate(rdpSvcPlugin* plugin)
|
||||
void* rdpdr_get_init_handle_data(void* pInitHandle)
|
||||
{
|
||||
rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin;
|
||||
void* pUserData = NULL;
|
||||
pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle);
|
||||
return pUserData;
|
||||
}
|
||||
|
||||
devman_free(rdpdr->devman);
|
||||
free(plugin);
|
||||
void rdpdr_remove_init_handle_data(void* pInitHandle)
|
||||
{
|
||||
ListDictionary_Remove(g_InitHandles, pInitHandle);
|
||||
}
|
||||
|
||||
void rdpdr_add_open_handle_data(DWORD openHandle, void* pUserData)
|
||||
{
|
||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
||||
|
||||
if (!g_OpenHandles)
|
||||
g_OpenHandles = ListDictionary_New(TRUE);
|
||||
|
||||
ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData);
|
||||
}
|
||||
|
||||
void* rdpdr_get_open_handle_data(DWORD openHandle)
|
||||
{
|
||||
void* pUserData = NULL;
|
||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
||||
pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle);
|
||||
return pUserData;
|
||||
}
|
||||
|
||||
void rdpdr_remove_open_handle_data(DWORD openHandle)
|
||||
{
|
||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
||||
ListDictionary_Remove(g_OpenHandles, pOpenHandle);
|
||||
}
|
||||
|
||||
int rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT32 status = 0;
|
||||
rdpdrPlugin* plugin = (rdpdrPlugin*) rdpdr;
|
||||
|
||||
if (!plugin)
|
||||
status = CHANNEL_RC_BAD_INIT_HANDLE;
|
||||
else
|
||||
status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle,
|
||||
Stream_Buffer(s), Stream_GetPosition(s), s);
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
Stream_Free(s, TRUE);
|
||||
fprintf(stderr, "rdpdr_send: VirtualChannelWrite failed %d\n", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
{
|
||||
wStream* data_in;
|
||||
|
||||
if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
|
||||
{
|
||||
/*
|
||||
* According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended.
|
||||
* This flag is only valid in server-to-client virtual channel traffic. It MUST be
|
||||
* ignored in client-to-server data." Thus it would be best practice to cease data
|
||||
* transmission. However, simply returning here avoids a crash.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataFlags & CHANNEL_FLAG_FIRST)
|
||||
{
|
||||
if (rdpdr->data_in != NULL)
|
||||
Stream_Free(rdpdr->data_in, TRUE);
|
||||
|
||||
rdpdr->data_in = Stream_New(NULL, totalLength);
|
||||
}
|
||||
|
||||
data_in = rdpdr->data_in;
|
||||
Stream_EnsureRemainingCapacity(data_in, (int) dataLength);
|
||||
Stream_Write(data_in, pData, dataLength);
|
||||
|
||||
if (dataFlags & CHANNEL_FLAG_LAST)
|
||||
{
|
||||
if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
|
||||
{
|
||||
fprintf(stderr, "svc_plugin_process_received: read error\n");
|
||||
}
|
||||
|
||||
rdpdr->data_in = NULL;
|
||||
Stream_SealLength(data_in);
|
||||
Stream_SetPosition(data_in, 0);
|
||||
|
||||
MessageQueue_Post(rdpdr->MsgPipe->In, NULL, 0, (void*) data_in, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void rdpdr_virtual_channel_open_event(UINT32 openHandle, UINT32 event,
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
{
|
||||
rdpdrPlugin* rdpdr;
|
||||
|
||||
rdpdr = (rdpdrPlugin*) rdpdr_get_open_handle_data(openHandle);
|
||||
|
||||
if (!rdpdr)
|
||||
{
|
||||
fprintf(stderr, "rdpdr_virtual_channel_open_event: error no match\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case CHANNEL_EVENT_DATA_RECEIVED:
|
||||
rdpdr_virtual_channel_event_data_received(rdpdr, pData, dataLength, totalLength, dataFlags);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_WRITE_COMPLETE:
|
||||
Stream_Free((wStream*) pData, TRUE);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_USER:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void* rdpdr_virtual_channel_client_thread(void* arg)
|
||||
{
|
||||
wStream* data;
|
||||
wMessage message;
|
||||
rdpdrPlugin* rdpdr = (rdpdrPlugin*) arg;
|
||||
|
||||
rdpdr_process_connect(rdpdr);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!MessageQueue_Wait(rdpdr->MsgPipe->In))
|
||||
break;
|
||||
|
||||
if (MessageQueue_Peek(rdpdr->MsgPipe->In, &message, TRUE))
|
||||
{
|
||||
if (message.id == WMQ_QUIT)
|
||||
break;
|
||||
|
||||
if (message.id == 0)
|
||||
{
|
||||
data = (wStream*) message.wParam;
|
||||
rdpdr_process_receive(rdpdr, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, void* pData, UINT32 dataLength)
|
||||
{
|
||||
UINT32 status;
|
||||
|
||||
status = rdpdr->channelEntryPoints.pVirtualChannelOpen(rdpdr->InitHandle,
|
||||
&rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event);
|
||||
|
||||
rdpdr_add_open_handle_data(rdpdr->OpenHandle, rdpdr);
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
fprintf(stderr, "rdpdr_virtual_channel_event_connected: open failed: status: %d\n", status);
|
||||
return;
|
||||
}
|
||||
|
||||
rdpdr->MsgPipe = MessagePipe_New();
|
||||
|
||||
rdpdr->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) rdpdr_virtual_channel_client_thread, (void*) rdpdr, 0, NULL);
|
||||
}
|
||||
|
||||
static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
MessagePipe_PostQuit(rdpdr->MsgPipe, 0);
|
||||
WaitForSingleObject(rdpdr->thread, INFINITE);
|
||||
|
||||
MessagePipe_Free(rdpdr->MsgPipe);
|
||||
CloseHandle(rdpdr->thread);
|
||||
|
||||
rdpdr->channelEntryPoints.pVirtualChannelClose(rdpdr->OpenHandle);
|
||||
|
||||
if (rdpdr->data_in)
|
||||
{
|
||||
Stream_Free(rdpdr->data_in, TRUE);
|
||||
rdpdr->data_in = NULL;
|
||||
}
|
||||
|
||||
if (rdpdr->devman)
|
||||
{
|
||||
devman_free(rdpdr->devman);
|
||||
rdpdr->devman = NULL;
|
||||
}
|
||||
|
||||
rdpdr_remove_open_handle_data(rdpdr->OpenHandle);
|
||||
rdpdr_remove_init_handle_data(rdpdr->InitHandle);
|
||||
}
|
||||
|
||||
static void rdpdr_virtual_channel_init_event(void* pInitHandle, UINT32 event, void* pData, UINT32 dataLength)
|
||||
{
|
||||
rdpdrPlugin* rdpdr;
|
||||
|
||||
rdpdr = (rdpdrPlugin*) rdpdr_get_init_handle_data(pInitHandle);
|
||||
|
||||
if (!rdpdr)
|
||||
{
|
||||
fprintf(stderr, "rdpdr_virtual_channel_init_event: error no match\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case CHANNEL_EVENT_CONNECTED:
|
||||
rdpdr_virtual_channel_event_connected(rdpdr, pData, dataLength);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_DISCONNECTED:
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_TERMINATED:
|
||||
rdpdr_virtual_channel_event_terminated(rdpdr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* rdpdr is always built-in */
|
||||
@ -315,24 +543,24 @@ static void rdpdr_process_terminate(rdpSvcPlugin* plugin)
|
||||
|
||||
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
rdpdrPlugin* _p;
|
||||
rdpdrPlugin* rdpdr;
|
||||
|
||||
_p = (rdpdrPlugin*) malloc(sizeof(rdpdrPlugin));
|
||||
ZeroMemory(_p, sizeof(rdpdrPlugin));
|
||||
rdpdr = (rdpdrPlugin*) malloc(sizeof(rdpdrPlugin));
|
||||
ZeroMemory(rdpdr, sizeof(rdpdrPlugin));
|
||||
|
||||
_p->plugin.channel_def.options =
|
||||
rdpdr->channelDef.options =
|
||||
CHANNEL_OPTION_INITIALIZED |
|
||||
CHANNEL_OPTION_ENCRYPT_RDP |
|
||||
CHANNEL_OPTION_COMPRESS_RDP;
|
||||
|
||||
strcpy(_p->plugin.channel_def.name, "rdpdr");
|
||||
strcpy(rdpdr->channelDef.name, "rdpdr");
|
||||
|
||||
_p->plugin.connect_callback = rdpdr_process_connect;
|
||||
_p->plugin.receive_callback = rdpdr_process_receive;
|
||||
_p->plugin.event_callback = rdpdr_process_event;
|
||||
_p->plugin.terminate_callback = rdpdr_process_terminate;
|
||||
CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, pEntryPoints->cbSize);
|
||||
|
||||
svc_plugin_init((rdpSvcPlugin*) _p, pEntryPoints);
|
||||
rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle,
|
||||
&rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpdr_virtual_channel_init_event);
|
||||
|
||||
rdpdr_add_init_handle_data(rdpdr->InitHandle, (void*) rdpdr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -21,14 +21,30 @@
|
||||
#ifndef FREERDP_CHANNEL_RDPDR_CLIENT_MAIN_H
|
||||
#define FREERDP_CHANNEL_RDPDR_CLIENT_MAIN_H
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/svc.h>
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
typedef struct rdpdr_plugin rdpdrPlugin;
|
||||
|
||||
struct rdpdr_plugin
|
||||
{
|
||||
rdpSvcPlugin plugin;
|
||||
CHANNEL_DEF channelDef;
|
||||
CHANNEL_ENTRY_POINTS_EX channelEntryPoints;
|
||||
|
||||
HANDLE thread;
|
||||
wStream* data_in;
|
||||
void* InitHandle;
|
||||
UINT32 OpenHandle;
|
||||
wMessagePipe* MsgPipe;
|
||||
|
||||
DEVMAN* devman;
|
||||
|
||||
@ -38,4 +54,6 @@ struct rdpdr_plugin
|
||||
char computerName[256];
|
||||
};
|
||||
|
||||
int rdpdr_send(rdpdrPlugin* rdpdr, wStream* s);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_MAIN_H */
|
||||
|
@ -32,4 +32,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server")
|
||||
|
@ -41,9 +41,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
|
23
channels/rdpgfx/CMakeLists.txt
Normal file
23
channels/rdpgfx/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Implementation
|
||||
# FreeRDP cmake build script
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
define_channel("rdpgfx")
|
||||
|
||||
if(WITH_CLIENT_CHANNELS)
|
||||
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
|
||||
endif()
|
||||
|
13
channels/rdpgfx/ChannelOptions.cmake
Normal file
13
channels/rdpgfx/ChannelOptions.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
set(OPTION_DEFAULT OFF)
|
||||
set(OPTION_CLIENT_DEFAULT ON)
|
||||
set(OPTION_SERVER_DEFAULT OFF)
|
||||
|
||||
define_channel_options(NAME "rdpgfx" TYPE "dynamic"
|
||||
DESCRIPTION "Graphics Pipeline Extension"
|
||||
SPECIFICATIONS "[MS-RDPEGFX]"
|
||||
DEFAULT ${OPTION_DEFAULT})
|
||||
|
||||
define_channel_client_options(${OPTION_CLIENT_DEFAULT})
|
||||
define_channel_server_options(${OPTION_SERVER_DEFAULT})
|
||||
|
47
channels/rdpgfx/client/CMakeLists.txt
Normal file
47
channels/rdpgfx/client/CMakeLists.txt
Normal file
@ -0,0 +1,47 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Implementation
|
||||
# FreeRDP cmake build script
|
||||
#
|
||||
# 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.
|
||||
|
||||
define_channel_client("rdpgfx")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
rdpgfx_main.c
|
||||
rdpgfx_main.h
|
||||
rdpgfx_common.c
|
||||
rdpgfx_common.h)
|
||||
|
||||
include_directories(..)
|
||||
|
||||
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
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})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
101
channels/rdpgfx/client/rdpgfx_common.c
Normal file
101
channels/rdpgfx/client/rdpgfx_common.c
Normal file
@ -0,0 +1,101 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Graphics Pipeline 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 "rdpgfx_common.h"
|
||||
|
||||
int rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* point16)
|
||||
{
|
||||
Stream_Read_UINT16(s, point16->x); /* x (2 bytes) */
|
||||
Stream_Read_UINT16(s, point16->y); /* y (2 bytes) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16)
|
||||
{
|
||||
Stream_Write_UINT16(s, point16->x); /* x (2 bytes) */
|
||||
Stream_Write_UINT16(s, point16->y); /* y (2 bytes) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rdpgfx_read_rect16(wStream* s, RDPGFX_RECT16* rect16)
|
||||
{
|
||||
Stream_Read_UINT16(s, rect16->left); /* left (2 bytes) */
|
||||
Stream_Read_UINT16(s, rect16->top); /* top (2 bytes) */
|
||||
Stream_Read_UINT16(s, rect16->right); /* right (2 bytes) */
|
||||
Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rdpgfx_write_rect16(wStream* s, RDPGFX_RECT16* rect16)
|
||||
{
|
||||
Stream_Write_UINT16(s, rect16->left); /* left (2 bytes) */
|
||||
Stream_Write_UINT16(s, rect16->top); /* top (2 bytes) */
|
||||
Stream_Write_UINT16(s, rect16->right); /* right (2 bytes) */
|
||||
Stream_Write_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32)
|
||||
{
|
||||
Stream_Read_UINT8(s, color32->B); /* B (1 byte) */
|
||||
Stream_Read_UINT8(s, color32->G); /* G (1 byte) */
|
||||
Stream_Read_UINT8(s, color32->R); /* R (1 byte) */
|
||||
Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32)
|
||||
{
|
||||
Stream_Write_UINT8(s, color32->B); /* B (1 byte) */
|
||||
Stream_Write_UINT8(s, color32->G); /* G (1 byte) */
|
||||
Stream_Write_UINT8(s, color32->R); /* R (1 byte) */
|
||||
Stream_Write_UINT8(s, color32->XA); /* XA (1 byte) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header)
|
||||
{
|
||||
Stream_Read_UINT16(s, header->cmdId); /* cmdId (2 bytes) */
|
||||
Stream_Read_UINT16(s, header->flags); /* flags (2 bytes) */
|
||||
Stream_Read_UINT16(s, header->pduLength); /* pduLength (4 bytes) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header)
|
||||
{
|
||||
Stream_Write_UINT16(s, header->cmdId); /* cmdId (2 bytes) */
|
||||
Stream_Write_UINT16(s, header->flags); /* flags (2 bytes) */
|
||||
Stream_Write_UINT16(s, header->pduLength); /* pduLength (4 bytes) */
|
||||
|
||||
return 0;
|
||||
}
|
38
channels/rdpgfx/client/rdpgfx_common.h
Normal file
38
channels/rdpgfx/client/rdpgfx_common.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Graphics Pipeline 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_RDPGFX_CLIENT_COMMON_H
|
||||
#define FREERDP_CHANNEL_RDPGFX_CLIENT_COMMON_H
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/channels/rdpgfx.h>
|
||||
|
||||
int rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* point16);
|
||||
int rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16);
|
||||
int rdpgfx_read_rect16(wStream* s, RDPGFX_RECT16* rect16);
|
||||
int rdpgfx_write_rect16(wStream* s, RDPGFX_RECT16* rect16);
|
||||
int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32);
|
||||
int rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32);
|
||||
int rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header);
|
||||
int rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_COMMON_H */
|
||||
|
207
channels/rdpgfx/client/rdpgfx_main.c
Normal file
207
channels/rdpgfx/client/rdpgfx_main.c
Normal file
@ -0,0 +1,207 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Graphics Pipeline 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 <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/wlog.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/cmdline.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include "rdpgfx_common.h"
|
||||
|
||||
#include "rdpgfx_main.h"
|
||||
|
||||
struct _RDPGFX_CHANNEL_CALLBACK
|
||||
{
|
||||
IWTSVirtualChannelCallback iface;
|
||||
|
||||
IWTSPlugin* plugin;
|
||||
IWTSVirtualChannelManager* channel_mgr;
|
||||
IWTSVirtualChannel* channel;
|
||||
};
|
||||
typedef struct _RDPGFX_CHANNEL_CALLBACK RDPGFX_CHANNEL_CALLBACK;
|
||||
|
||||
struct _RDPGFX_LISTENER_CALLBACK
|
||||
{
|
||||
IWTSListenerCallback iface;
|
||||
|
||||
IWTSPlugin* plugin;
|
||||
IWTSVirtualChannelManager* channel_mgr;
|
||||
RDPGFX_CHANNEL_CALLBACK* channel_callback;
|
||||
};
|
||||
typedef struct _RDPGFX_LISTENER_CALLBACK RDPGFX_LISTENER_CALLBACK;
|
||||
|
||||
struct _RDPGFX_PLUGIN
|
||||
{
|
||||
IWTSPlugin iface;
|
||||
|
||||
IWTSListener* listener;
|
||||
RDPGFX_LISTENER_CALLBACK* listener_callback;
|
||||
};
|
||||
typedef struct _RDPGFX_PLUGIN RDPGFX_PLUGIN;
|
||||
|
||||
int rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, UINT32 cbSize, BYTE* pBuffer)
|
||||
{
|
||||
wStream* s;
|
||||
int status = 0;
|
||||
RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
|
||||
fprintf(stderr, "RdpGfxOnDataReceived\n");
|
||||
|
||||
s = Stream_New(pBuffer, cbSize);
|
||||
|
||||
status = rdpgfx_recv_pdu(callback, s);
|
||||
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int rdpgfx_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
||||
{
|
||||
RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
|
||||
free(callback);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rdpgfx_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
|
||||
IWTSVirtualChannel* pChannel, BYTE* Data, int* pbAccept,
|
||||
IWTSVirtualChannelCallback** ppCallback)
|
||||
{
|
||||
RDPGFX_CHANNEL_CALLBACK* callback;
|
||||
RDPGFX_LISTENER_CALLBACK* listener_callback = (RDPGFX_LISTENER_CALLBACK*) pListenerCallback;
|
||||
|
||||
callback = (RDPGFX_CHANNEL_CALLBACK*) malloc(sizeof(RDPGFX_CHANNEL_CALLBACK));
|
||||
ZeroMemory(callback, sizeof(RDPGFX_CHANNEL_CALLBACK));
|
||||
|
||||
callback->iface.OnDataReceived = rdpgfx_on_data_received;
|
||||
callback->iface.OnClose = rdpgfx_on_close;
|
||||
callback->plugin = listener_callback->plugin;
|
||||
callback->channel_mgr = listener_callback->channel_mgr;
|
||||
callback->channel = pChannel;
|
||||
listener_callback->channel_callback = callback;
|
||||
|
||||
*ppCallback = (IWTSVirtualChannelCallback*) callback;
|
||||
|
||||
fprintf(stderr, "RdpGfxOnNewChannelConnection\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
|
||||
{
|
||||
int status;
|
||||
RDPGFX_PLUGIN* rdpgfx = (RDPGFX_PLUGIN*) pPlugin;
|
||||
|
||||
rdpgfx->listener_callback = (RDPGFX_LISTENER_CALLBACK*) malloc(sizeof(RDPGFX_LISTENER_CALLBACK));
|
||||
ZeroMemory(rdpgfx->listener_callback, sizeof(RDPGFX_LISTENER_CALLBACK));
|
||||
|
||||
rdpgfx->listener_callback->iface.OnNewChannelConnection = rdpgfx_on_new_channel_connection;
|
||||
rdpgfx->listener_callback->plugin = pPlugin;
|
||||
rdpgfx->listener_callback->channel_mgr = pChannelMgr;
|
||||
|
||||
status = pChannelMgr->CreateListener(pChannelMgr, RDPGFX_DVC_CHANNEL_NAME, 0,
|
||||
(IWTSListenerCallback*) rdpgfx->listener_callback, &(rdpgfx->listener));
|
||||
|
||||
rdpgfx->listener->pInterface = rdpgfx->iface.pInterface;
|
||||
|
||||
fprintf(stderr, "RdpGfxInitialize\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int rdpgfx_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
{
|
||||
RDPGFX_PLUGIN* rdpgfx = (RDPGFX_PLUGIN*) pPlugin;
|
||||
|
||||
if (rdpgfx->listener_callback)
|
||||
free(rdpgfx->listener_callback);
|
||||
|
||||
free(rdpgfx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel Client Interface
|
||||
*/
|
||||
|
||||
UINT32 rdpgfx_get_version(RdpgfxClientContext* context)
|
||||
{
|
||||
//RDPGFX_PLUGIN* rdpgfx = (RDPGFX_PLUGIN*) context->handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry rdpgfx_DVCPluginEntry
|
||||
#endif
|
||||
|
||||
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
{
|
||||
int error = 0;
|
||||
RDPGFX_PLUGIN* rdpgfx;
|
||||
RdpgfxClientContext* context;
|
||||
|
||||
rdpgfx = (RDPGFX_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "rdpgfx");
|
||||
|
||||
if (!rdpgfx)
|
||||
{
|
||||
rdpgfx = (RDPGFX_PLUGIN*) malloc(sizeof(RDPGFX_PLUGIN));
|
||||
ZeroMemory(rdpgfx, sizeof(RDPGFX_PLUGIN));
|
||||
|
||||
rdpgfx->iface.Initialize = rdpgfx_plugin_initialize;
|
||||
rdpgfx->iface.Connected = NULL;
|
||||
rdpgfx->iface.Disconnected = NULL;
|
||||
rdpgfx->iface.Terminated = rdpgfx_plugin_terminated;
|
||||
|
||||
context = (RdpgfxClientContext*) malloc(sizeof(RdpgfxClientContext));
|
||||
|
||||
context->handle = (void*) rdpgfx;
|
||||
context->GetVersion = rdpgfx_get_version;
|
||||
|
||||
rdpgfx->iface.pInterface = (void*) context;
|
||||
|
||||
fprintf(stderr, "RdpGfxDVCPluginEntry\n");
|
||||
|
||||
error = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpgfx", (IWTSPlugin*) rdpgfx);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
36
channels/rdpgfx/client/rdpgfx_main.h
Normal file
36
channels/rdpgfx/client/rdpgfx_main.h
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Graphics Pipeline 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_RDPGFX_CLIENT_MAIN_H
|
||||
#define FREERDP_CHANNEL_RDPGFX_CLIENT_MAIN_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <freerdp/dvc.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include <freerdp/client/rdpgfx.h>
|
||||
|
||||
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_MAIN_H */
|
||||
|
@ -37,6 +37,8 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
if(WITH_ALSA)
|
||||
@ -44,7 +46,7 @@ if(WITH_ALSA)
|
||||
endif()
|
||||
|
||||
if(WITH_IOSAUDIO)
|
||||
add_channel_client_subsystem($(MODULE_PREFIX) $(CHANNEL_NAME) "ios" "")
|
||||
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "ios" "")
|
||||
endif()
|
||||
|
||||
if(WITH_PULSE)
|
||||
|
@ -41,8 +41,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${ALSA_LIBRARIES})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client/ALSA")
|
||||
|
@ -45,8 +45,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client/ios")
|
||||
|
@ -45,8 +45,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client/Mac")
|
||||
|
@ -38,6 +38,4 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${OPENSLES_LIBRARIES})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
@ -36,8 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PULSE_LIBRARY})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client/Pulse")
|
||||
|
@ -4,6 +4,7 @@
|
||||
*
|
||||
* Copyright 2009-2011 Jay Sorg
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2012-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.
|
||||
@ -34,6 +35,8 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/cmdline.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/collections.h>
|
||||
@ -41,9 +44,8 @@
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/utils/signal.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#include "rdpsnd_main.h"
|
||||
|
||||
@ -51,10 +53,16 @@
|
||||
|
||||
struct rdpsnd_plugin
|
||||
{
|
||||
rdpSvcPlugin plugin;
|
||||
CHANNEL_DEF channelDef;
|
||||
CHANNEL_ENTRY_POINTS_EX channelEntryPoints;
|
||||
|
||||
HANDLE thread;
|
||||
wMessageQueue* queue;
|
||||
wStream* data_in;
|
||||
void* InitHandle;
|
||||
UINT32 OpenHandle;
|
||||
wMessagePipe* MsgPipe;
|
||||
|
||||
HANDLE ScheduleThread;
|
||||
|
||||
BYTE cBlockNo;
|
||||
int wCurrentFormatNo;
|
||||
@ -96,10 +104,10 @@ static void* rdpsnd_schedule_thread(void* arg)
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!MessageQueue_Wait(rdpsnd->queue))
|
||||
if (!MessageQueue_Wait(rdpsnd->MsgPipe->Out))
|
||||
break;
|
||||
|
||||
if (!MessageQueue_Peek(rdpsnd->queue, &message, TRUE))
|
||||
if (!MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, TRUE))
|
||||
break;
|
||||
|
||||
if (message.id == WMQ_QUIT)
|
||||
@ -134,7 +142,7 @@ void rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd)
|
||||
Stream_Write_UINT16(pdu, HIGH_QUALITY); /* wQualityMode */
|
||||
Stream_Write_UINT16(pdu, 0); /* Reserved */
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu);
|
||||
rdpsnd_virtual_channel_write(rdpsnd, pdu);
|
||||
}
|
||||
|
||||
void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd)
|
||||
@ -250,7 +258,7 @@ void rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd)
|
||||
Stream_Write(pdu, clientFormat->data, clientFormat->cbSize);
|
||||
}
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu);
|
||||
rdpsnd_virtual_channel_write(rdpsnd, pdu);
|
||||
}
|
||||
|
||||
void rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
@ -289,8 +297,15 @@ void rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
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);
|
||||
if (format->cbSize > 0)
|
||||
{
|
||||
format->data = (BYTE*) malloc(format->cbSize);
|
||||
Stream_Read(s, format->data, format->cbSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
format->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
rdpsnd_select_supported_audio_formats(rdpsnd);
|
||||
@ -315,7 +330,7 @@ void rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, U
|
||||
Stream_Write_UINT16(pdu, wTimeStamp);
|
||||
Stream_Write_UINT16(pdu, wPackSize);
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu);
|
||||
rdpsnd_virtual_channel_write(rdpsnd, pdu);
|
||||
}
|
||||
|
||||
static void rdpsnd_recv_training_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
@ -381,12 +396,12 @@ void rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE
|
||||
Stream_Write_UINT8(pdu, cConfirmedBlockNo); /* cConfirmedBlockNo */
|
||||
Stream_Write_UINT8(pdu, 0); /* bPad */
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu);
|
||||
rdpsnd_virtual_channel_write(rdpsnd, pdu);
|
||||
}
|
||||
|
||||
static void rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
|
||||
{
|
||||
MessageQueue_Post(device->rdpsnd->queue, NULL, 0, (void*) wave, NULL);
|
||||
MessageQueue_Post(device->rdpsnd->MsgPipe->Out, NULL, 0, (void*) wave, NULL);
|
||||
}
|
||||
|
||||
static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
@ -453,8 +468,6 @@ static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
|
||||
static void rdpsnd_recv_close_pdu(rdpsndPlugin* rdpsnd)
|
||||
{
|
||||
DEBUG_SVC("server closes.");
|
||||
|
||||
if (rdpsnd->device)
|
||||
{
|
||||
IFCALL(rdpsnd->device->Close, rdpsnd->device);
|
||||
@ -468,7 +481,6 @@ static void rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
UINT32 dwVolume;
|
||||
|
||||
Stream_Read_UINT32(s, dwVolume);
|
||||
DEBUG_SVC("dwVolume 0x%X", dwVolume);
|
||||
|
||||
if (rdpsnd->device)
|
||||
{
|
||||
@ -476,11 +488,10 @@ static void rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
}
|
||||
}
|
||||
|
||||
static void rdpsnd_recv_pdu(rdpSvcPlugin* plugin, wStream* s)
|
||||
static void rdpsnd_recv_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
{
|
||||
BYTE msgType;
|
||||
UINT16 BodySize;
|
||||
rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
|
||||
|
||||
if (rdpsnd->expectingWave)
|
||||
{
|
||||
@ -645,20 +656,17 @@ static void rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args)
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
}
|
||||
|
||||
static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
|
||||
static void rdpsnd_process_connect(rdpsndPlugin* rdpsnd)
|
||||
{
|
||||
ADDIN_ARGV* args;
|
||||
rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
|
||||
|
||||
DEBUG_SVC("connecting");
|
||||
|
||||
rdpsnd->latency = -1;
|
||||
rdpsnd->queue = MessageQueue_New();
|
||||
rdpsnd->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread,
|
||||
(void*) plugin, 0, NULL);
|
||||
|
||||
args = (ADDIN_ARGV*) plugin->channel_entry_points.pExtendedData;
|
||||
rdpsnd->ScheduleThread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread,
|
||||
(void*) rdpsnd, 0, NULL);
|
||||
|
||||
args = (ADDIN_ARGV*) rdpsnd->channelEntryPoints.pExtendedData;
|
||||
|
||||
if (args)
|
||||
rdpsnd_process_addin_args(rdpsnd, args);
|
||||
@ -732,24 +740,211 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
|
||||
}
|
||||
}
|
||||
|
||||
static void rdpsnd_process_event(rdpSvcPlugin* plugin, wMessage* event)
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
|
||||
static wListDictionary* g_InitHandles;
|
||||
static wListDictionary* g_OpenHandles;
|
||||
|
||||
void rdpsnd_add_init_handle_data(void* pInitHandle, void* pUserData)
|
||||
{
|
||||
freerdp_event_free(event);
|
||||
if (!g_InitHandles)
|
||||
g_InitHandles = ListDictionary_New(TRUE);
|
||||
|
||||
ListDictionary_Add(g_InitHandles, pInitHandle, pUserData);
|
||||
}
|
||||
|
||||
static void rdpsnd_process_terminate(rdpSvcPlugin* plugin)
|
||||
void* rdpsnd_get_init_handle_data(void* pInitHandle)
|
||||
{
|
||||
rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
|
||||
void* pUserData = NULL;
|
||||
pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle);
|
||||
return pUserData;
|
||||
}
|
||||
|
||||
void rdpsnd_remove_init_handle_data(void* pInitHandle)
|
||||
{
|
||||
ListDictionary_Remove(g_InitHandles, pInitHandle);
|
||||
}
|
||||
|
||||
void rdpsnd_add_open_handle_data(DWORD openHandle, void* pUserData)
|
||||
{
|
||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
||||
|
||||
if (!g_OpenHandles)
|
||||
g_OpenHandles = ListDictionary_New(TRUE);
|
||||
|
||||
ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData);
|
||||
}
|
||||
|
||||
void* rdpsnd_get_open_handle_data(DWORD openHandle)
|
||||
{
|
||||
void* pUserData = NULL;
|
||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
||||
pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle);
|
||||
return pUserData;
|
||||
}
|
||||
|
||||
void rdpsnd_remove_open_handle_data(DWORD openHandle)
|
||||
{
|
||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
||||
ListDictionary_Remove(g_OpenHandles, pOpenHandle);
|
||||
}
|
||||
|
||||
int rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
{
|
||||
UINT32 status = 0;
|
||||
|
||||
if (!rdpsnd)
|
||||
status = CHANNEL_RC_BAD_INIT_HANDLE;
|
||||
else
|
||||
status = rdpsnd->channelEntryPoints.pVirtualChannelWrite(rdpsnd->OpenHandle,
|
||||
Stream_Buffer(s), Stream_GetPosition(s), s);
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
Stream_Free(s, TRUE);
|
||||
fprintf(stderr, "rdpdr_virtual_channel_write: VirtualChannelWrite failed %d\n", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin,
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataFlags & CHANNEL_FLAG_FIRST)
|
||||
{
|
||||
if (plugin->data_in != NULL)
|
||||
Stream_Free(plugin->data_in, TRUE);
|
||||
|
||||
plugin->data_in = Stream_New(NULL, totalLength);
|
||||
}
|
||||
|
||||
s = plugin->data_in;
|
||||
Stream_EnsureRemainingCapacity(s, (int) dataLength);
|
||||
Stream_Write(s, pData, dataLength);
|
||||
|
||||
if (dataFlags & CHANNEL_FLAG_LAST)
|
||||
{
|
||||
if (Stream_Capacity(s) != Stream_GetPosition(s))
|
||||
{
|
||||
fprintf(stderr, "rdpsnd_virtual_channel_event_data_received: read error\n");
|
||||
}
|
||||
|
||||
plugin->data_in = NULL;
|
||||
Stream_SealLength(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
|
||||
MessageQueue_Post(plugin->MsgPipe->In, NULL, 0, (void*) s, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void rdpsnd_virtual_channel_open_event(UINT32 openHandle, UINT32 event,
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
{
|
||||
rdpsndPlugin* plugin;
|
||||
|
||||
plugin = (rdpsndPlugin*) rdpsnd_get_open_handle_data(openHandle);
|
||||
|
||||
if (!plugin)
|
||||
{
|
||||
fprintf(stderr, "rdpsnd_virtual_channel_open_event: error no match\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case CHANNEL_EVENT_DATA_RECEIVED:
|
||||
rdpsnd_virtual_channel_event_data_received(plugin, pData, dataLength, totalLength, dataFlags);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_WRITE_COMPLETE:
|
||||
Stream_Free((wStream*) pData, TRUE);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_USER:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void* rdpsnd_virtual_channel_client_thread(void* arg)
|
||||
{
|
||||
wStream* data;
|
||||
wMessage message;
|
||||
rdpsndPlugin* plugin = (rdpsndPlugin*) arg;
|
||||
|
||||
rdpsnd_process_connect(plugin);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!MessageQueue_Wait(plugin->MsgPipe->In))
|
||||
break;
|
||||
|
||||
if (MessageQueue_Peek(plugin->MsgPipe->In, &message, TRUE))
|
||||
{
|
||||
if (message.id == WMQ_QUIT)
|
||||
break;
|
||||
|
||||
if (message.id == 0)
|
||||
{
|
||||
data = (wStream*) message.wParam;
|
||||
rdpsnd_recv_pdu(plugin, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, void* pData, UINT32 dataLength)
|
||||
{
|
||||
UINT32 status;
|
||||
|
||||
status = plugin->channelEntryPoints.pVirtualChannelOpen(plugin->InitHandle,
|
||||
&plugin->OpenHandle, plugin->channelDef.name, rdpsnd_virtual_channel_open_event);
|
||||
|
||||
rdpsnd_add_open_handle_data(plugin->OpenHandle, plugin);
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
fprintf(stderr, "rdpsnd_virtual_channel_event_connected: open failed: status: %d\n", status);
|
||||
return;
|
||||
}
|
||||
|
||||
plugin->MsgPipe = MessagePipe_New();
|
||||
|
||||
plugin->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) rdpsnd_virtual_channel_client_thread, (void*) plugin, 0, NULL);
|
||||
}
|
||||
|
||||
static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd)
|
||||
{
|
||||
MessagePipe_PostQuit(rdpsnd->MsgPipe, 0);
|
||||
WaitForSingleObject(rdpsnd->thread, INFINITE);
|
||||
|
||||
MessagePipe_Free(rdpsnd->MsgPipe);
|
||||
CloseHandle(rdpsnd->thread);
|
||||
|
||||
rdpsnd->channelEntryPoints.pVirtualChannelClose(rdpsnd->OpenHandle);
|
||||
|
||||
if (rdpsnd->data_in)
|
||||
{
|
||||
Stream_Free(rdpsnd->data_in, TRUE);
|
||||
rdpsnd->data_in = NULL;
|
||||
}
|
||||
|
||||
if (rdpsnd->device)
|
||||
IFCALL(rdpsnd->device->Free, rdpsnd->device);
|
||||
|
||||
MessageQueue_PostQuit(rdpsnd->queue, 0);
|
||||
WaitForSingleObject(rdpsnd->thread, INFINITE);
|
||||
|
||||
MessageQueue_Free(rdpsnd->queue);
|
||||
CloseHandle(rdpsnd->thread);
|
||||
|
||||
if (rdpsnd->subsystem)
|
||||
free(rdpsnd->subsystem);
|
||||
|
||||
@ -763,6 +958,36 @@ static void rdpsnd_process_terminate(rdpSvcPlugin* plugin)
|
||||
rdpsnd_free_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats);
|
||||
rdpsnd->NumberOfClientFormats = 0;
|
||||
rdpsnd->ClientFormats = NULL;
|
||||
|
||||
rdpsnd_remove_open_handle_data(rdpsnd->OpenHandle);
|
||||
rdpsnd_remove_init_handle_data(rdpsnd->InitHandle);
|
||||
}
|
||||
|
||||
static void rdpsnd_virtual_channel_init_event(void* pInitHandle, UINT32 event, void* pData, UINT32 dataLength)
|
||||
{
|
||||
rdpsndPlugin* plugin;
|
||||
|
||||
plugin = (rdpsndPlugin*) rdpsnd_get_init_handle_data(pInitHandle);
|
||||
|
||||
if (!plugin)
|
||||
{
|
||||
fprintf(stderr, "rdpsnd_virtual_channel_init_event: error no match\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case CHANNEL_EVENT_CONNECTED:
|
||||
rdpsnd_virtual_channel_event_connected(plugin, pData, dataLength);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_DISCONNECTED:
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_TERMINATED:
|
||||
rdpsnd_virtual_channel_event_terminated(plugin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* rdpsnd is always built-in */
|
||||
@ -770,32 +995,36 @@ static void rdpsnd_process_terminate(rdpSvcPlugin* plugin)
|
||||
|
||||
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
rdpsndPlugin* _p;
|
||||
rdpsndPlugin* rdpsnd;
|
||||
|
||||
_p = (rdpsndPlugin*) malloc(sizeof(rdpsndPlugin));
|
||||
ZeroMemory(_p, sizeof(rdpsndPlugin));
|
||||
rdpsnd = (rdpsndPlugin*) malloc(sizeof(rdpsndPlugin));
|
||||
|
||||
_p->plugin.channel_def.options =
|
||||
CHANNEL_OPTION_INITIALIZED |
|
||||
CHANNEL_OPTION_ENCRYPT_RDP;
|
||||
|
||||
strcpy(_p->plugin.channel_def.name, "rdpsnd");
|
||||
|
||||
_p->plugin.connect_callback = rdpsnd_process_connect;
|
||||
_p->plugin.receive_callback = rdpsnd_recv_pdu;
|
||||
_p->plugin.event_callback = rdpsnd_process_event;
|
||||
_p->plugin.terminate_callback = rdpsnd_process_terminate;
|
||||
if (rdpsnd)
|
||||
{
|
||||
ZeroMemory(rdpsnd, sizeof(rdpsndPlugin));
|
||||
|
||||
#if !defined(_WIN32) && !defined(ANDROID)
|
||||
{
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGIO);
|
||||
pthread_sigmask(SIG_BLOCK, &mask, NULL);
|
||||
}
|
||||
{
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGIO);
|
||||
pthread_sigmask(SIG_BLOCK, &mask, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
svc_plugin_init((rdpSvcPlugin*) _p, pEntryPoints);
|
||||
rdpsnd->channelDef.options =
|
||||
CHANNEL_OPTION_INITIALIZED |
|
||||
CHANNEL_OPTION_ENCRYPT_RDP;
|
||||
|
||||
strcpy(rdpsnd->channelDef.name, "rdpsnd");
|
||||
|
||||
CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints, pEntryPoints->cbSize);
|
||||
|
||||
rdpsnd->channelEntryPoints.pVirtualChannelInit(&rdpsnd->InitHandle,
|
||||
&rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpsnd_virtual_channel_init_event);
|
||||
|
||||
rdpsnd_add_init_handle_data(rdpsnd->InitHandle, (void*) rdpsnd);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Audio Output Virtual Channel
|
||||
*
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2012-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.
|
||||
@ -20,7 +21,10 @@
|
||||
#ifndef __RDPSND_MAIN_H
|
||||
#define __RDPSND_MAIN_H
|
||||
|
||||
#include <freerdp/channels/rdpsnd.h>
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/svc.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/client/rdpsnd.h>
|
||||
|
||||
#if defined(WITH_DEBUG_SND)
|
||||
#define DEBUG_SND(fmt, ...) DEBUG_CLASS("rdpsnd", fmt, ## __VA_ARGS__)
|
||||
@ -28,75 +32,6 @@
|
||||
#define DEBUG_SND(fmt, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
struct _RDPSND_WAVE
|
||||
{
|
||||
BYTE* data;
|
||||
int length;
|
||||
|
||||
BYTE cBlockNo;
|
||||
UINT16 wFormatNo;
|
||||
UINT16 wTimeStampA;
|
||||
UINT16 wTimeStampB;
|
||||
|
||||
UINT16 wLatency;
|
||||
UINT16 wAudioLength;
|
||||
UINT16 wPlaybackDelay;
|
||||
|
||||
UINT32 wLocalTimeA;
|
||||
UINT32 wLocalTimeB;
|
||||
};
|
||||
typedef struct _RDPSND_WAVE RDPSND_WAVE;
|
||||
|
||||
typedef struct rdpsnd_plugin rdpsndPlugin;
|
||||
|
||||
typedef struct rdpsnd_device_plugin rdpsndDevicePlugin;
|
||||
|
||||
typedef BOOL (*pcFormatSupported) (rdpsndDevicePlugin* device, AUDIO_FORMAT* format);
|
||||
typedef void (*pcOpen) (rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency);
|
||||
typedef void (*pcSetFormat) (rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency);
|
||||
typedef UINT32 (*pcGetVolume) (rdpsndDevicePlugin* device);
|
||||
typedef void (*pcSetVolume) (rdpsndDevicePlugin* device, UINT32 value);
|
||||
typedef void (*pcPlay) (rdpsndDevicePlugin* device, BYTE* data, int size);
|
||||
typedef void (*pcStart) (rdpsndDevicePlugin* device);
|
||||
typedef void (*pcClose) (rdpsndDevicePlugin* device);
|
||||
typedef void (*pcFree) (rdpsndDevicePlugin* device);
|
||||
|
||||
typedef void (*pcWaveDecode) (rdpsndDevicePlugin* device, RDPSND_WAVE* wave);
|
||||
typedef void (*pcWavePlay) (rdpsndDevicePlugin* device, RDPSND_WAVE* wave);
|
||||
typedef void (*pcWaveConfirm) (rdpsndDevicePlugin* device, RDPSND_WAVE* wave);
|
||||
|
||||
struct rdpsnd_device_plugin
|
||||
{
|
||||
rdpsndPlugin* rdpsnd;
|
||||
|
||||
pcFormatSupported FormatSupported;
|
||||
pcOpen Open;
|
||||
pcSetFormat SetFormat;
|
||||
pcGetVolume GetVolume;
|
||||
pcSetVolume SetVolume;
|
||||
pcPlay Play;
|
||||
pcStart Start;
|
||||
pcClose Close;
|
||||
pcFree Free;
|
||||
|
||||
pcWaveDecode WaveDecode;
|
||||
pcWavePlay WavePlay;
|
||||
pcWaveConfirm WaveConfirm;
|
||||
};
|
||||
|
||||
#define RDPSND_DEVICE_EXPORT_FUNC_NAME "freerdp_rdpsnd_client_subsystem_entry"
|
||||
|
||||
typedef void (*PREGISTERRDPSNDDEVICE)(rdpsndPlugin* rdpsnd, rdpsndDevicePlugin* device);
|
||||
|
||||
struct _FREERDP_RDPSND_DEVICE_ENTRY_POINTS
|
||||
{
|
||||
rdpsndPlugin* rdpsnd;
|
||||
PREGISTERRDPSNDDEVICE pRegisterRdpsndDevice;
|
||||
ADDIN_ARGV* args;
|
||||
};
|
||||
typedef struct _FREERDP_RDPSND_DEVICE_ENTRY_POINTS FREERDP_RDPSND_DEVICE_ENTRY_POINTS;
|
||||
typedef FREERDP_RDPSND_DEVICE_ENTRY_POINTS* PFREERDP_RDPSND_DEVICE_ENTRY_POINTS;
|
||||
|
||||
typedef int (*PFREERDP_RDPSND_DEVICE_ENTRY)(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints);
|
||||
int rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s);
|
||||
|
||||
#endif /* __RDPSND_MAIN_H */
|
||||
|
@ -40,8 +40,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winmm.lib)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client/WinMM")
|
||||
|
@ -32,4 +32,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server")
|
||||
|
@ -30,8 +30,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MODULE freerdp
|
||||
MODULES freerdp-utils)
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
@ -34,9 +34,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
|
@ -47,12 +47,13 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
typedef struct _SERIAL_DEVICE SERIAL_DEVICE;
|
||||
|
||||
|
@ -42,9 +42,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PCSC_LIBRARIES})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
|
||||
@ -229,7 +228,7 @@ static void smartcard_irp_complete(IRP* irp)
|
||||
* to be in this file so that "smartcard_irp_request()" can reference it.
|
||||
*/
|
||||
|
||||
DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
|
||||
DEBUG_SCARD("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
|
||||
|
||||
pos = Stream_GetPosition(irp->output);
|
||||
Stream_SetPosition(irp->output, 12);
|
||||
@ -246,8 +245,7 @@ static void smartcard_irp_complete(IRP* irp)
|
||||
|
||||
if (!duplicate)
|
||||
{
|
||||
svc_plugin_send(irp->devman->plugin, irp->output);
|
||||
irp->output = NULL;
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
/* End TS Client defect workaround. */
|
||||
|
@ -47,9 +47,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
|
@ -36,6 +36,4 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${ALSA_LIBRARIES})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
@ -31,20 +31,17 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE freerdp
|
||||
MODULES freerdp-utils)
|
||||
|
||||
|
||||
if(APPLE)
|
||||
# For this to work on apple, we need to add some frameworks
|
||||
FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation )
|
||||
FIND_LIBRARY(COREVIDEO_LIBRARY CoreVideo )
|
||||
FIND_LIBRARY(COREVIDEODECODE_LIBRARY VideoDecodeAcceleration )
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES} ${COREFOUNDATION_LIBRARY} ${COREVIDEO_LIBRARY} ${COREVIDEODECODE_LIBRARY} )
|
||||
FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||
FIND_LIBRARY(COREVIDEO_LIBRARY CoreVideo)
|
||||
FIND_LIBRARY(COREVIDEODECODE_LIBRARY VideoDecodeAcceleration)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES} ${COREFOUNDATION_LIBRARY} ${COREVIDEO_LIBRARY} ${COREVIDEODECODE_LIBRARY})
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
else()
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES})
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
endif()
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
@ -40,6 +40,4 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
@ -36,7 +36,4 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PULSE_LIBRARY})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
@ -58,9 +58,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
|
@ -464,7 +464,7 @@ int main(int argc, char* argv[])
|
||||
instance->context->argc = argc;
|
||||
instance->context->argv = argv;
|
||||
|
||||
status = freerdp_client_parse_command_line_arguments(argc, argv, instance->settings);
|
||||
status = freerdp_client_settings_parse_command_line(instance->settings, argc, argv);
|
||||
|
||||
if (status < 0)
|
||||
exit(0);
|
||||
|
@ -41,43 +41,27 @@
|
||||
|
||||
@interface MRDPView : NSView
|
||||
{
|
||||
mfContext* mfc;
|
||||
NSBitmapImageRep* bmiRep;
|
||||
NSMutableArray* cursors;
|
||||
NSMutableArray* windows;
|
||||
NSTimer* pasteboard_timer;
|
||||
NSCursor* currentCursor;
|
||||
NSCursor* currentCursor;
|
||||
NSRect prevWinPosition;
|
||||
int titleBarHeight;
|
||||
freerdp* instance;
|
||||
rdpContext* context;
|
||||
CGContextRef bitmap_context;
|
||||
char* pixel_data;
|
||||
int width;
|
||||
int height;
|
||||
int argc;
|
||||
char** argv;
|
||||
|
||||
DWORD kbdModFlags;
|
||||
BOOL initialized;
|
||||
NSPoint savedDragLocation;
|
||||
BOOL firstCreateWindow;
|
||||
BOOL isMoveSizeInProgress;
|
||||
BOOL skipResizeOnce;
|
||||
BOOL saveInitialDragLoc;
|
||||
BOOL skipMoveWindowOnce;
|
||||
|
||||
/* store state info for some keys */
|
||||
int kdlshift;
|
||||
int kdrshift;
|
||||
int kdlctrl;
|
||||
int kdrctrl;
|
||||
int kdlalt;
|
||||
int kdralt;
|
||||
int kdlmeta;
|
||||
int kdrmeta;
|
||||
int kdcapslock;
|
||||
|
||||
BOOL initialized;
|
||||
|
||||
NSImageView* imageView;
|
||||
|
||||
@public
|
||||
NSPasteboard* pasteboard_rd; /* for reading from clipboard */
|
||||
@ -89,10 +73,10 @@
|
||||
|
||||
- (int) rdpStart :(rdpContext*) rdp_context;
|
||||
- (void) setCursor: (NSCursor*) cursor;
|
||||
- (void) setScrollOffset:(int)xOffset y:(int)yOffset w:(int)width h:(int)height;
|
||||
|
||||
- (void) onPasteboardTimerFired :(NSTimer *) timer;
|
||||
- (void) releaseResources;
|
||||
- (void) setViewSize : (int) w : (int) h;
|
||||
|
||||
@property (assign) int is_connected;
|
||||
|
||||
|
@ -123,11 +123,10 @@ struct rgba_data
|
||||
|
||||
- (int) rdpStart:(rdpContext*) rdp_context
|
||||
{
|
||||
mfContext* mfc;
|
||||
rdpSettings* settings;
|
||||
EmbedWindowEventArgs e;
|
||||
|
||||
[self initializeView];
|
||||
[self initializeView];
|
||||
|
||||
context = rdp_context;
|
||||
mfc = (mfContext*) rdp_context;
|
||||
@ -148,13 +147,10 @@ struct rgba_data
|
||||
instance->settings->DesktopHeight = screenFrame.size.height;
|
||||
}
|
||||
|
||||
[self setViewSize :instance->settings->DesktopWidth :instance->settings->DesktopHeight];
|
||||
mfc->client_height = instance->settings->DesktopHeight;
|
||||
mfc->client_width = instance->settings->DesktopWidth;
|
||||
|
||||
|
||||
if(instance->settings->Fullscreen)
|
||||
[[self window] toggleFullScreen:nil];
|
||||
|
||||
mfc->thread = CreateThread(NULL, 0, mac_client_thread, (void*) context, 0, &mfc->mainThreadId);
|
||||
mfc->thread = CreateThread(NULL, 0, mac_client_thread, (void*) context, 0, &mfc->mainThreadId);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -174,6 +170,7 @@ DWORD mac_client_thread(void* param)
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
freerdp* instance = context->instance;
|
||||
MRDPView* view = mfc->view;
|
||||
rdpSettings* settings = context->settings;
|
||||
|
||||
status = freerdp_connect(context->instance);
|
||||
|
||||
@ -189,17 +186,17 @@ DWORD mac_client_thread(void* param)
|
||||
|
||||
events[nCount++] = mfc->stopEvent;
|
||||
|
||||
if (instance->settings->AsyncUpdate)
|
||||
if (settings->AsyncUpdate)
|
||||
{
|
||||
events[nCount++] = update_event = freerdp_get_message_queue_event_handle(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
}
|
||||
|
||||
if (instance->settings->AsyncInput)
|
||||
if (settings->AsyncInput)
|
||||
{
|
||||
events[nCount++] = input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
}
|
||||
|
||||
if (instance->settings->AsyncChannels)
|
||||
if (settings->AsyncChannels)
|
||||
{
|
||||
events[nCount++] = channels_event = freerdp_channels_get_event_handle(instance);
|
||||
}
|
||||
@ -210,10 +207,11 @@ DWORD mac_client_thread(void* param)
|
||||
|
||||
if (WaitForSingleObject(mfc->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
freerdp_disconnect(instance);
|
||||
break;
|
||||
}
|
||||
|
||||
if (instance->settings->AsyncUpdate)
|
||||
if (settings->AsyncUpdate)
|
||||
{
|
||||
if (WaitForSingleObject(update_event, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
@ -221,7 +219,7 @@ DWORD mac_client_thread(void* param)
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->settings->AsyncInput)
|
||||
if (settings->AsyncInput)
|
||||
{
|
||||
if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
@ -229,7 +227,7 @@ DWORD mac_client_thread(void* param)
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->settings->AsyncChannels)
|
||||
if (settings->AsyncChannels)
|
||||
{
|
||||
if (WaitForSingleObject(channels_event, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
@ -253,7 +251,7 @@ DWORD mac_client_thread(void* param)
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
self = [super initWithFrame:frame];
|
||||
|
||||
if (self)
|
||||
{
|
||||
@ -271,48 +269,38 @@ DWORD mac_client_thread(void* param)
|
||||
// won't be called if the view is created dynamically
|
||||
- (void) viewDidLoad
|
||||
{
|
||||
[self initializeView];
|
||||
[self initializeView];
|
||||
}
|
||||
|
||||
- (void) initializeView
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
// store our window dimensions
|
||||
width = [self frame].size.width;
|
||||
height = [self frame].size.height;
|
||||
titleBarHeight = 22;
|
||||
if (!initialized)
|
||||
{
|
||||
cursors = [[NSMutableArray alloc] initWithCapacity:10];
|
||||
|
||||
[[self window] becomeFirstResponder];
|
||||
[[self window] setAcceptsMouseMovedEvents:YES];
|
||||
// setup a mouse tracking area
|
||||
NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil];
|
||||
|
||||
cursors = [[NSMutableArray alloc] initWithCapacity:10];
|
||||
[self addTrackingArea:trackingArea];
|
||||
|
||||
// setup a mouse tracking area
|
||||
NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil];
|
||||
// Set the default cursor
|
||||
currentCursor = [NSCursor arrowCursor];
|
||||
|
||||
[self addTrackingArea:trackingArea];
|
||||
|
||||
// Set the default cursor
|
||||
currentCursor = [NSCursor arrowCursor];
|
||||
|
||||
initialized = YES;
|
||||
}
|
||||
initialized = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setCursor: (NSCursor*) cursor
|
||||
{
|
||||
self->currentCursor = cursor;
|
||||
[[self window] invalidateCursorRectsForView:self];
|
||||
|
||||
[imageView setImage:[currentCursor image]];
|
||||
self->currentCursor = cursor;
|
||||
[[self window] invalidateCursorRectsForView:self];
|
||||
}
|
||||
|
||||
|
||||
// Set the current cursor
|
||||
- (void) resetCursorRects
|
||||
{
|
||||
[self addCursorRect:[self visibleRect] cursor:currentCursor];
|
||||
[self addCursorRect:[self visibleRect] cursor:currentCursor];
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -347,11 +335,8 @@ DWORD mac_client_thread(void* param)
|
||||
NSPoint loc = [event locationInWindow];
|
||||
int x = (int) loc.x;
|
||||
int y = (int) loc.y;
|
||||
|
||||
y = height - y;
|
||||
|
||||
// send mouse motion event to RDP server
|
||||
instance->input->MouseEvent(instance->input, PTR_FLAGS_MOVE, x, y);
|
||||
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_MOVE, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -369,9 +354,7 @@ DWORD mac_client_thread(void* param)
|
||||
int x = (int) loc.x;
|
||||
int y = (int) loc.y;
|
||||
|
||||
y = height - y;
|
||||
|
||||
instance->input->MouseEvent(instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y);
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -389,9 +372,7 @@ DWORD mac_client_thread(void* param)
|
||||
int x = (int) loc.x;
|
||||
int y = (int) loc.y;
|
||||
|
||||
y = height - y;
|
||||
|
||||
instance->input->MouseEvent(instance->input, PTR_FLAGS_BUTTON1, x, y);
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON1, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -409,9 +390,7 @@ DWORD mac_client_thread(void* param)
|
||||
int x = (int) loc.x;
|
||||
int y = (int) loc.y;
|
||||
|
||||
y = height - y;
|
||||
|
||||
instance->input->MouseEvent(instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y);
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -429,9 +408,7 @@ DWORD mac_client_thread(void* param)
|
||||
int x = (int) loc.x;
|
||||
int y = (int) loc.y;
|
||||
|
||||
y = height - y;
|
||||
|
||||
instance->input->MouseEvent(instance->input, PTR_FLAGS_BUTTON2, x, y);
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON2, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -449,9 +426,7 @@ DWORD mac_client_thread(void* param)
|
||||
int x = (int) loc.x;
|
||||
int y = (int) loc.y;
|
||||
|
||||
y = height - y;
|
||||
|
||||
instance->input->MouseEvent(instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y);
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -469,9 +444,7 @@ DWORD mac_client_thread(void* param)
|
||||
int x = (int) loc.x;
|
||||
int y = (int) loc.y;
|
||||
|
||||
y = height - y;
|
||||
|
||||
instance->input->MouseEvent(instance->input, PTR_FLAGS_BUTTON3, x, y);
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON3, x, y);
|
||||
}
|
||||
|
||||
- (void) scrollWheel:(NSEvent *)event
|
||||
@ -486,8 +459,6 @@ DWORD mac_client_thread(void* param)
|
||||
NSPoint loc = [event locationInWindow];
|
||||
int x = (int) loc.x;
|
||||
int y = (int) loc.y;
|
||||
|
||||
y = height - y;
|
||||
|
||||
flags = PTR_FLAGS_WHEEL;
|
||||
|
||||
@ -500,7 +471,7 @@ DWORD mac_client_thread(void* param)
|
||||
/* limit to maximum value in WheelRotationMask (9bit signed value) */
|
||||
int step = MIN(MAX(-256, units), 255);
|
||||
|
||||
instance->input->MouseEvent(instance->input, flags | ((UINT16)step & WheelRotationMask), x, y);
|
||||
mf_scale_mouse_event(context, instance->input, flags | ((UINT16)step & WheelRotationMask), x, y);
|
||||
units -= step;
|
||||
}
|
||||
}
|
||||
@ -521,10 +492,8 @@ DWORD mac_client_thread(void* param)
|
||||
int x = (int) loc.x;
|
||||
int y = (int) loc.y;
|
||||
|
||||
y = height - y;
|
||||
|
||||
// send mouse motion event to RDP server
|
||||
instance->input->MouseEvent(instance->input, PTR_FLAGS_MOVE, x, y);
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_MOVE, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -534,20 +503,28 @@ DWORD mac_client_thread(void* param)
|
||||
- (void) keyDown:(NSEvent *) event
|
||||
{
|
||||
int key;
|
||||
USHORT extended;
|
||||
DWORD keyFlags;
|
||||
DWORD vkcode;
|
||||
DWORD scancode;
|
||||
|
||||
if (!is_connected)
|
||||
return;
|
||||
|
||||
keyFlags = KBD_FLAGS_DOWN;
|
||||
key = [event keyCode] + 8;
|
||||
|
||||
vkcode = GetVirtualKeyCodeFromKeycode(key, KEYCODE_TYPE_APPLE);
|
||||
scancode = GetVirtualScanCodeFromVirtualKeyCode(vkcode, 4);
|
||||
extended = (scancode & KBDEXT) ? KBDEXT : 0;
|
||||
keyFlags |= (scancode & KBDEXT) ? KBDEXT : 0;
|
||||
scancode &= 0xFF;
|
||||
vkcode &= 0xFF;
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "keyDown: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n",
|
||||
key - 8, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode));
|
||||
#endif
|
||||
|
||||
instance->input->KeyboardEvent(instance->input, extended | KBD_FLAGS_DOWN, scancode & 0xFF);
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags, scancode);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -557,20 +534,28 @@ DWORD mac_client_thread(void* param)
|
||||
- (void) keyUp:(NSEvent *) event
|
||||
{
|
||||
int key;
|
||||
USHORT extended;
|
||||
DWORD keyFlags;
|
||||
DWORD vkcode;
|
||||
DWORD scancode;
|
||||
|
||||
|
||||
if (!is_connected)
|
||||
return;
|
||||
|
||||
|
||||
key = [event keyCode] + 8;
|
||||
|
||||
keyFlags = KBD_FLAGS_RELEASE;
|
||||
|
||||
vkcode = GetVirtualKeyCodeFromKeycode(key, KEYCODE_TYPE_APPLE);
|
||||
scancode = GetVirtualScanCodeFromVirtualKeyCode(vkcode, 4);
|
||||
extended = (scancode & KBDEXT) ? KBDEXT : 0;
|
||||
|
||||
instance->input->KeyboardEvent(instance->input, extended | KBD_FLAGS_RELEASE, scancode & 0xFF);
|
||||
keyFlags |= (scancode & KBDEXT) ? KBDEXT : 0;
|
||||
scancode &= 0xFF;
|
||||
vkcode &= 0xFF;
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "keyUp: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n",
|
||||
key - 8, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode));
|
||||
#endif
|
||||
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags, scancode);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -579,122 +564,93 @@ DWORD mac_client_thread(void* param)
|
||||
|
||||
- (void) flagsChanged:(NSEvent*) event
|
||||
{
|
||||
NSUInteger mf = [event modifierFlags];
|
||||
|
||||
int key;
|
||||
DWORD keyFlags;
|
||||
DWORD vkcode;
|
||||
DWORD scancode;
|
||||
DWORD modFlags;
|
||||
|
||||
if (!is_connected)
|
||||
return;
|
||||
|
||||
// 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
|
||||
instance->input->KeyboardEvent(instance->input, KBD_FLAGS_DOWN, 0x2a);
|
||||
kdlshift = 1;
|
||||
}
|
||||
if ((kdlshift != 0) && ((mf & 2) == 0)) {
|
||||
// left shift went up
|
||||
instance->input->KeyboardEvent(instance->input, KBD_FLAGS_RELEASE, 0x2a);
|
||||
kdlshift = 0;
|
||||
}
|
||||
|
||||
// right shift
|
||||
if ((kdrshift == 0) && ((mf & 4) != 0)) {
|
||||
// right shift went down
|
||||
instance->input->KeyboardEvent(instance->input, KBD_FLAGS_DOWN, 0x36);
|
||||
kdrshift = 1;
|
||||
}
|
||||
if ((kdrshift != 0) && ((mf & 4) == 0)) {
|
||||
// right shift went up
|
||||
instance->input->KeyboardEvent(instance->input, KBD_FLAGS_RELEASE, 0x36);
|
||||
kdrshift = 0;
|
||||
}
|
||||
|
||||
// left ctrl
|
||||
if ((kdlctrl == 0) && ((mf & 1) != 0)) {
|
||||
// left ctrl went down
|
||||
instance->input->KeyboardEvent(instance->input, KBD_FLAGS_DOWN, 0x1d);
|
||||
kdlctrl = 1;
|
||||
}
|
||||
if ((kdlctrl != 0) && ((mf & 1) == 0)) {
|
||||
// left ctrl went up
|
||||
instance->input->KeyboardEvent(instance->input, KBD_FLAGS_RELEASE, 0x1d);
|
||||
kdlctrl = 0;
|
||||
}
|
||||
|
||||
// right ctrl
|
||||
if ((kdrctrl == 0) && ((mf & 0x2000) != 0)) {
|
||||
// right ctrl went down
|
||||
instance->input->KeyboardEvent(instance->input, 1 | KBD_FLAGS_DOWN, 0x1d);
|
||||
kdrctrl = 1;
|
||||
}
|
||||
if ((kdrctrl != 0) && ((mf & 0x2000) == 0)) {
|
||||
// right ctrl went up
|
||||
instance->input->KeyboardEvent(instance->input, 1 | KBD_FLAGS_RELEASE, 0x1d);
|
||||
kdrctrl = 0;
|
||||
}
|
||||
|
||||
// left alt
|
||||
if ((kdlalt == 0) && ((mf & 0x20) != 0)) {
|
||||
// left alt went down
|
||||
instance->input->KeyboardEvent(instance->input, KBD_FLAGS_DOWN, 0x38);
|
||||
kdlalt = 1;
|
||||
}
|
||||
if ((kdlalt != 0) && ((mf & 0x20) == 0)) {
|
||||
// left alt went up
|
||||
instance->input->KeyboardEvent(instance->input, KBD_FLAGS_RELEASE, 0x38);
|
||||
kdlalt = 0;
|
||||
}
|
||||
|
||||
// right alt
|
||||
if ((kdralt == 0) && ((mf & 0x40) != 0)) {
|
||||
// right alt went down
|
||||
instance->input->KeyboardEvent(instance->input, 1 | KBD_FLAGS_DOWN, 0x38);
|
||||
kdralt = 1;
|
||||
}
|
||||
if ((kdralt != 0) && ((mf & 0x40) == 0)) {
|
||||
// right alt went up
|
||||
instance->input->KeyboardEvent(instance->input, 1 | KBD_FLAGS_RELEASE, 0x38);
|
||||
kdralt = 0;
|
||||
}
|
||||
|
||||
// left meta
|
||||
if ((kdlmeta == 0) && ((mf & 0x08) != 0)) {
|
||||
// left meta went down
|
||||
instance->input->KeyboardEvent(instance->input, 1 | KBD_FLAGS_DOWN, 0x5b);
|
||||
kdlmeta = 1;
|
||||
}
|
||||
if ((kdlmeta != 0) && ((mf & 0x08) == 0)) {
|
||||
// left meta went up
|
||||
instance->input->KeyboardEvent(instance->input, 1 | KBD_FLAGS_RELEASE, 0x5b);
|
||||
kdlmeta = 0;
|
||||
}
|
||||
|
||||
// right meta
|
||||
if ((kdrmeta == 0) && ((mf & 0x10) != 0)) {
|
||||
// right meta went down
|
||||
instance->input->KeyboardEvent(instance->input, 1 | KBD_FLAGS_DOWN, 0x5c);
|
||||
kdrmeta = 1;
|
||||
}
|
||||
if ((kdrmeta != 0) && ((mf & 0x10) == 0)) {
|
||||
// right meta went up
|
||||
instance->input->KeyboardEvent(instance->input, 1 | KBD_FLAGS_RELEASE, 0x5c);
|
||||
kdrmeta = 0;
|
||||
}
|
||||
|
||||
keyFlags = 0;
|
||||
key = [event keyCode] + 8;
|
||||
modFlags = [event modifierFlags] & NSDeviceIndependentModifierFlagsMask;
|
||||
|
||||
vkcode = GetVirtualKeyCodeFromKeycode(key, KEYCODE_TYPE_APPLE);
|
||||
scancode = GetVirtualScanCodeFromVirtualKeyCode(vkcode, 4);
|
||||
keyFlags |= (scancode & KBDEXT) ? KBDEXT : 0;
|
||||
scancode &= 0xFF;
|
||||
vkcode &= 0xFF;
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "flagsChanged: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X extended: %d name: %s modFlags: 0x%04X\n",
|
||||
key - 8, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode), modFlags);
|
||||
|
||||
if (modFlags & NSAlphaShiftKeyMask)
|
||||
fprintf(stderr, "NSAlphaShiftKeyMask\n");
|
||||
|
||||
if (modFlags & NSShiftKeyMask)
|
||||
fprintf(stderr, "NSShiftKeyMask\n");
|
||||
|
||||
if (modFlags & NSControlKeyMask)
|
||||
fprintf(stderr, "NSControlKeyMask\n");
|
||||
|
||||
if (modFlags & NSAlternateKeyMask)
|
||||
fprintf(stderr, "NSAlternateKeyMask\n");
|
||||
|
||||
if (modFlags & NSCommandKeyMask)
|
||||
fprintf(stderr, "NSCommandKeyMask\n");
|
||||
|
||||
if (modFlags & NSNumericPadKeyMask)
|
||||
fprintf(stderr, "NSNumericPadKeyMask\n");
|
||||
|
||||
if (modFlags & NSHelpKeyMask)
|
||||
fprintf(stderr, "NSHelpKeyMask\n");
|
||||
#endif
|
||||
|
||||
if ((modFlags & NSAlphaShiftKeyMask) && !(kbdModFlags & NSAlphaShiftKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_DOWN, scancode);
|
||||
else if (!(modFlags & NSAlphaShiftKeyMask) && (kbdModFlags & NSAlphaShiftKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_RELEASE, scancode);
|
||||
|
||||
if ((modFlags & NSShiftKeyMask) && !(kbdModFlags & NSShiftKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_DOWN, scancode);
|
||||
else if (!(modFlags & NSShiftKeyMask) && (kbdModFlags & NSShiftKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_RELEASE, scancode);
|
||||
|
||||
if ((modFlags & NSControlKeyMask) && !(kbdModFlags & NSControlKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_DOWN, scancode);
|
||||
else if (!(modFlags & NSControlKeyMask) && (kbdModFlags & NSControlKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_RELEASE, scancode);
|
||||
|
||||
if ((modFlags & NSAlternateKeyMask) && !(kbdModFlags & NSAlternateKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_DOWN, scancode);
|
||||
else if (!(modFlags & NSAlternateKeyMask) && (kbdModFlags & NSAlternateKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_RELEASE, scancode);
|
||||
|
||||
if ((modFlags & NSCommandKeyMask) && !(kbdModFlags & NSCommandKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_DOWN, scancode);
|
||||
else if (!(modFlags & NSCommandKeyMask) && (kbdModFlags & NSCommandKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_RELEASE, scancode);
|
||||
|
||||
if ((modFlags & NSNumericPadKeyMask) && !(kbdModFlags & NSNumericPadKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_DOWN, scancode);
|
||||
else if (!(modFlags & NSNumericPadKeyMask) && (kbdModFlags & NSNumericPadKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_RELEASE, scancode);
|
||||
|
||||
if ((modFlags & NSHelpKeyMask) && !(kbdModFlags & NSHelpKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_DOWN, scancode);
|
||||
else if (!(modFlags & NSHelpKeyMask) && (kbdModFlags & NSHelpKeyMask))
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags | KBD_FLAGS_RELEASE, scancode);
|
||||
|
||||
kbdModFlags = modFlags;
|
||||
}
|
||||
|
||||
- (void) releaseResources
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (argv[i])
|
||||
@ -725,14 +681,15 @@ DWORD mac_client_thread(void* param)
|
||||
CGImageRef cgImage = CGBitmapContextCreateImage(self->bitmap_context);
|
||||
|
||||
CGContextClipToRect(cgContext, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height));
|
||||
CGContextDrawImage(cgContext, CGRectMake(0, 0, [self bounds].size.width, [self bounds].size.height), cgImage);
|
||||
CGContextDrawImage(cgContext, CGRectMake(0,
|
||||
0, [self bounds].size.width, [self bounds].size.height), cgImage);
|
||||
|
||||
CGImageRelease(cgImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just clear the screen with black
|
||||
[[NSColor redColor] set];
|
||||
[[NSColor blackColor] set];
|
||||
NSRectFill([self bounds]);
|
||||
}
|
||||
}
|
||||
@ -760,30 +717,12 @@ DWORD mac_client_thread(void* param)
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setViewSize : (int) w : (int) h
|
||||
- (void) setScrollOffset:(int)xOffset y:(int)yOffset w:(int)width h:(int)height
|
||||
{
|
||||
// store current dimensions
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
|
||||
// set client area to specified dimensions
|
||||
NSRect innerRect;
|
||||
innerRect.origin.x = 0;
|
||||
innerRect.origin.y = 0;
|
||||
innerRect.size.width = w;
|
||||
innerRect.size.height = h;
|
||||
[self setFrame:innerRect];
|
||||
|
||||
// calculate window of same size, but keep position
|
||||
NSRect outerRect = [[self window] frame];
|
||||
outerRect.size = [[self window] frameRectForContentRect:innerRect].size;
|
||||
|
||||
// we are not in RemoteApp mode, disable larger than resolution
|
||||
[[self window] setContentMaxSize:innerRect.size];
|
||||
|
||||
// set window to given area
|
||||
[[self window] setFrame:outerRect display:YES];
|
||||
mfc->yCurrentScroll = yOffset;
|
||||
mfc->xCurrentScroll = xOffset;
|
||||
mfc->client_height = height;
|
||||
mfc->client_width = width;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
@ -974,11 +913,11 @@ void mf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
cursor_data = (BYTE*) malloc(rect.size.width * rect.size.height * 4);
|
||||
mrdpCursor->cursor_data = cursor_data;
|
||||
|
||||
if (pointer->xorBpp > 24)
|
||||
{
|
||||
freerdp_image_swap_color_order(pointer->xorMaskData, pointer->width, pointer->height);
|
||||
if (pointer->xorBpp > 24)
|
||||
{
|
||||
freerdp_image_swap_color_order(pointer->xorMaskData, pointer->width, pointer->height);
|
||||
}
|
||||
|
||||
|
||||
freerdp_alpha_cursor_convert(cursor_data, pointer->xorMaskData, pointer->andMaskData,
|
||||
pointer->width, pointer->height, pointer->xorBpp, context->gdi->clrconv);
|
||||
|
||||
@ -1057,12 +996,12 @@ void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
if (cursor->pointer == pointer)
|
||||
{
|
||||
[view setCursor:cursor->nsCursor];
|
||||
[view setCursor:cursor->nsCursor];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NSLog(@"Cursor not found");
|
||||
|
||||
NSLog(@"Cursor not found");
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -1082,7 +1021,7 @@ void mf_Pointer_SetDefault(rdpContext* context)
|
||||
{
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
[view setCursor:[NSCursor arrowCursor]];
|
||||
[view setCursor:[NSCursor arrowCursor]];
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -1125,6 +1064,13 @@ void mac_end_paint(rdpContext* context)
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
|
||||
int ww, wh, dw, dh;
|
||||
|
||||
ww = mfc->client_width;
|
||||
wh = mfc->client_height;
|
||||
dw = mfc->context.settings->DesktopWidth;
|
||||
dh = mfc->context.settings->DesktopHeight;
|
||||
|
||||
if ((context == 0) || (context->gdi == 0))
|
||||
return;
|
||||
|
||||
@ -1138,11 +1084,31 @@ void mac_end_paint(rdpContext* context)
|
||||
|
||||
for (i = 0; i < gdi->primary->hdc->hwnd->ninvalid; i++)
|
||||
{
|
||||
drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x - 1;
|
||||
drawRect.origin.y = gdi->primary->hdc->hwnd->cinvalid[i].y - 1;
|
||||
drawRect.size.width = gdi->primary->hdc->hwnd->cinvalid[i].w + 1;
|
||||
drawRect.size.height = gdi->primary->hdc->hwnd->cinvalid[i].h + 1;
|
||||
drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x;
|
||||
drawRect.origin.y = gdi->primary->hdc->hwnd->cinvalid[i].y;
|
||||
drawRect.size.width = gdi->primary->hdc->hwnd->cinvalid[i].w;
|
||||
drawRect.size.height = gdi->primary->hdc->hwnd->cinvalid[i].h;
|
||||
|
||||
if (mfc->context.settings->SmartSizing && (ww != dw || wh != dh))
|
||||
{
|
||||
drawRect.origin.y = drawRect.origin.y * wh / dh - 1;
|
||||
drawRect.size.height = drawRect.size.height * wh / dh + 1;
|
||||
drawRect.origin.x = drawRect.origin.x * ww / dw - 1;
|
||||
drawRect.size.width = drawRect.size.width * ww / dw + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawRect.origin.y = drawRect.origin.y - 1;
|
||||
drawRect.size.height = drawRect.size.height + 1;
|
||||
drawRect.origin.x = drawRect.origin.x - 1;
|
||||
drawRect.size.width = drawRect.size.width + 1;
|
||||
}
|
||||
|
||||
windows_to_apple_cords(mfc->view, &drawRect);
|
||||
|
||||
// Note: The xCurrentScroll and yCurrentScroll values do not need to be taken into account
|
||||
// because the current frame is always at full size, since the scrolling is handled by the external container.
|
||||
|
||||
[view setNeedsDisplayInRect:drawRect];
|
||||
}
|
||||
|
||||
@ -1175,7 +1141,7 @@ static void update_activity_cb(freerdp* instance)
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "update_activity_cb: No queue!\n");
|
||||
fprintf(stderr, "update_activity_cb: No queue!\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1187,7 +1153,7 @@ static void input_activity_cb(freerdp* instance)
|
||||
{
|
||||
int status;
|
||||
wMessage message;
|
||||
wMessageQueue* queue;
|
||||
wMessageQueue* queue;
|
||||
|
||||
status = 1;
|
||||
queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
@ -1202,10 +1168,10 @@ static void input_activity_cb(freerdp* instance)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "input_activity_cb: No queue!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "input_activity_cb: No queue!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -1214,14 +1180,16 @@ static void input_activity_cb(freerdp* instance)
|
||||
|
||||
static void channel_activity_cb(freerdp* instance)
|
||||
{
|
||||
wMessage* event;
|
||||
wMessage* event;
|
||||
|
||||
freerdp_channels_process_pending_messages(instance);
|
||||
event = freerdp_channels_pop_event(instance->context->channels);
|
||||
|
||||
if (event)
|
||||
{
|
||||
fprintf(stderr, "channel_activity_cb: message %d\n", event->id);
|
||||
switch (GetMessageClass(event->id))
|
||||
fprintf(stderr, "channel_activity_cb: message %d\n", event->id);
|
||||
|
||||
switch (GetMessageClass(event->id))
|
||||
{
|
||||
case CliprdrChannel_Class:
|
||||
process_cliprdr_event(instance, event);
|
||||
@ -1477,7 +1445,8 @@ void cliprdr_send_supported_format_list(freerdp* instance)
|
||||
|
||||
void windows_to_apple_cords(MRDPView* view, NSRect* r)
|
||||
{
|
||||
r->origin.y = view->height - (r->origin.y + r->size.height);
|
||||
r->origin.y = [view frame].size.height - (r->origin.y + r->size.height);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
@ -9,12 +9,15 @@
|
||||
#import "AppDelegate.h"
|
||||
#import "MacFreeRDP/mfreerdp.h"
|
||||
#import "MacFreeRDP/mf_client.h"
|
||||
#import "MacFreeRDP/MRDPView.h"
|
||||
#import <freerdp/client/cmdline.h>
|
||||
|
||||
static AppDelegate* _singleDelegate = nil;
|
||||
void AppDelegate_EmbedWindowEventHandler(void* context, EmbedWindowEventArgs* e);
|
||||
void AppDelegate_ConnectionResultEventHandler(void* context, ConnectionResultEventArgs* e);
|
||||
void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e);
|
||||
int mac_client_start(rdpContext* context);
|
||||
void mac_set_view_size(rdpContext* context, MRDPView* view);
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
@ -33,7 +36,7 @@ void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e);
|
||||
int status;
|
||||
mfContext* mfc;
|
||||
|
||||
_singleDelegate = self;
|
||||
_singleDelegate = self;
|
||||
[self CreateContext];
|
||||
|
||||
status = [self ParseCommandLineArguments];
|
||||
@ -90,8 +93,8 @@ void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e);
|
||||
argv[i++] = cptr;
|
||||
}
|
||||
|
||||
status = freerdp_client_parse_command_line(context, argc, argv);
|
||||
status = freerdp_client_command_line_status_print(context->argc, context->argv, context->settings, status);
|
||||
status = freerdp_client_settings_parse_command_line(context->settings, argc, argv);
|
||||
status = freerdp_client_settings_command_line_status_print(context->settings, status, context->argc, context->argv);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -105,12 +108,24 @@ void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e);
|
||||
clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
|
||||
|
||||
RdpClientEntry(&clientEntryPoints);
|
||||
|
||||
clientEntryPoints.ClientStart = mac_client_start;
|
||||
|
||||
context = freerdp_client_context_new(&clientEntryPoints);
|
||||
}
|
||||
|
||||
- (void) ReleaseContext
|
||||
{
|
||||
mfContext* mfc;
|
||||
MRDPView* view;
|
||||
|
||||
mfc = (mfContext*) context;
|
||||
view = (MRDPView*) mfc->view;
|
||||
|
||||
[view releaseResources];
|
||||
[view release];
|
||||
mfc->view = nil;
|
||||
|
||||
freerdp_client_context_free(context);
|
||||
context = nil;
|
||||
}
|
||||
@ -158,6 +173,9 @@ void AppDelegate_EmbedWindowEventHandler(void* ctx, EmbedWindowEventArgs* e)
|
||||
{
|
||||
[[_singleDelegate->window contentView] addSubview:mfc->view];
|
||||
}
|
||||
|
||||
|
||||
mac_set_view_size(context, mfc->view);
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,4 +221,45 @@ void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e)
|
||||
[_singleDelegate performSelectorOnMainThread:@selector(rdpConnectError:) withObject:message waitUntilDone:TRUE];
|
||||
[message release];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mac_set_view_size(rdpContext* context, MRDPView* view)
|
||||
{
|
||||
// set client area to specified dimensions
|
||||
NSRect innerRect;
|
||||
innerRect.origin.x = 0;
|
||||
innerRect.origin.y = 0;
|
||||
innerRect.size.width = context->settings->DesktopWidth;
|
||||
innerRect.size.height = context->settings->DesktopHeight;
|
||||
[view setFrame:innerRect];
|
||||
|
||||
// calculate window of same size, but keep position
|
||||
NSRect outerRect = [[view window] frame];
|
||||
outerRect.size = [[view window] frameRectForContentRect:innerRect].size;
|
||||
|
||||
// we are not in RemoteApp mode, disable larger than resolution
|
||||
[[view window] setContentMaxSize:innerRect.size];
|
||||
|
||||
// set window to given area
|
||||
[[view window] setFrame:outerRect display:YES];
|
||||
|
||||
|
||||
if(context->settings->Fullscreen)
|
||||
[[view window] toggleFullScreen:nil];
|
||||
}
|
||||
|
||||
int mac_client_start(rdpContext* context)
|
||||
{
|
||||
mfContext* mfc;
|
||||
MRDPView* view;
|
||||
|
||||
mfc = (mfContext*) context;
|
||||
view = [[MRDPView alloc] initWithFrame : NSMakeRect(0, 0, context->settings->DesktopWidth, context->settings->DesktopHeight)];
|
||||
mfc->view = view;
|
||||
|
||||
[view rdpStart:context];
|
||||
mac_set_view_size(context, view);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,6 +28,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API void mf_scale_mouse_event(void* context, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
|
||||
|
||||
/**
|
||||
* Client Interface
|
||||
*/
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/signal.h>
|
||||
#include <freerdp/client/cmdline.h>
|
||||
#import "MRDPView.h"
|
||||
|
||||
/**
|
||||
* Client Interface
|
||||
@ -47,12 +46,12 @@ int mfreerdp_client_start(rdpContext* context)
|
||||
MRDPView* view;
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
|
||||
if (mfc->view == NULL)
|
||||
{
|
||||
// view not specified beforehand. Create view dynamically
|
||||
mfc->view = [[MRDPView alloc] initWithFrame : NSMakeRect(0, 0, context->settings->DesktopWidth, context->settings->DesktopHeight)];
|
||||
mfc->view_ownership = TRUE;
|
||||
}
|
||||
if (mfc->view == NULL)
|
||||
{
|
||||
// view not specified beforehand. Create view dynamically
|
||||
mfc->view = [[MRDPView alloc] initWithFrame : NSMakeRect(0, 0, context->settings->DesktopWidth, context->settings->DesktopHeight)];
|
||||
mfc->view_ownership = TRUE;
|
||||
}
|
||||
|
||||
view = (MRDPView*) mfc->view;
|
||||
[view rdpStart:context];
|
||||
@ -63,45 +62,22 @@ int mfreerdp_client_start(rdpContext* context)
|
||||
int mfreerdp_client_stop(rdpContext* context)
|
||||
{
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
|
||||
if (context->settings->AsyncUpdate)
|
||||
|
||||
if (mfc->thread)
|
||||
{
|
||||
wMessageQueue* queue;
|
||||
queue = freerdp_get_message_queue(context->instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
if (queue)
|
||||
{
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
}
|
||||
}
|
||||
else if (context->settings->AsyncInput)
|
||||
{
|
||||
wMessageQueue* queue;
|
||||
queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
if (queue)
|
||||
{
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mfc->disconnect = TRUE;
|
||||
SetEvent(mfc->stopEvent);
|
||||
WaitForSingleObject(mfc->thread, INFINITE);
|
||||
CloseHandle(mfc->thread);
|
||||
mfc->thread = NULL;
|
||||
}
|
||||
|
||||
if (mfc->thread)
|
||||
{
|
||||
SetEvent(mfc->stopEvent);
|
||||
WaitForSingleObject(mfc->thread, INFINITE);
|
||||
CloseHandle(mfc->thread);
|
||||
mfc->thread = NULL;
|
||||
}
|
||||
|
||||
if (mfc->view_ownership)
|
||||
{
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
[view releaseResources];
|
||||
[view release];
|
||||
mfc->view = nil;
|
||||
}
|
||||
if (mfc->view_ownership)
|
||||
{
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
[view releaseResources];
|
||||
[view release];
|
||||
mfc->view = nil;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -113,22 +89,21 @@ int mfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
|
||||
mfc = (mfContext*) instance->context;
|
||||
|
||||
mfc->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
mfc->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
context->instance->PreConnect = mac_pre_connect;
|
||||
context->instance->PostConnect = mac_post_connect;
|
||||
context->instance->ReceiveChannelData = mac_receive_channel_data;
|
||||
context->instance->Authenticate = mac_authenticate;
|
||||
context->instance->PreConnect = mac_pre_connect;
|
||||
context->instance->PostConnect = mac_post_connect;
|
||||
context->instance->ReceiveChannelData = mac_receive_channel_data;
|
||||
context->instance->Authenticate = mac_authenticate;
|
||||
|
||||
context->channels = freerdp_channels_new();
|
||||
context->channels = freerdp_channels_new();
|
||||
|
||||
settings = instance->settings;
|
||||
|
||||
settings->AsyncUpdate = TRUE;
|
||||
settings->AsyncInput = TRUE;
|
||||
settings->AsyncUpdate = TRUE;
|
||||
settings->AsyncInput = TRUE;
|
||||
settings->AsyncChannels = TRUE;
|
||||
settings->AsyncTransport = TRUE;
|
||||
settings->RedirectClipboard = TRUE;
|
||||
|
||||
settings->OsMajorType = OSMAJORTYPE_MACINTOSH;
|
||||
settings->OsMinorType = OSMINORTYPE_MACINTOSH;
|
||||
@ -193,6 +168,40 @@ void freerdp_client_mouse_event(rdpContext* cfc, DWORD flags, int x, int y)
|
||||
input->MouseEvent(input, flags, x, y);
|
||||
}
|
||||
|
||||
|
||||
void mf_scale_mouse_event(void* context, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
|
||||
{
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
|
||||
int ww, wh, dw, dh;
|
||||
|
||||
ww = mfc->client_width;
|
||||
wh = mfc->client_height;
|
||||
dw = mfc->context.settings->DesktopWidth;
|
||||
dh = mfc->context.settings->DesktopHeight;
|
||||
|
||||
// Convert to windows coordinates
|
||||
y = [view frame].size.height - y;
|
||||
|
||||
if (!mfc->context.settings->SmartSizing || ((ww == dw) && (wh == dh)))
|
||||
{
|
||||
y = y + mfc->yCurrentScroll;
|
||||
|
||||
if (wh != dh)
|
||||
{
|
||||
y -= (dh - wh);
|
||||
}
|
||||
|
||||
input->MouseEvent(input, flags, x + mfc->xCurrentScroll, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
y = y * dh / wh + mfc->yCurrentScroll;
|
||||
input->MouseEvent(input, flags, x * dw / ww + mfc->xCurrentScroll, y);
|
||||
}
|
||||
}
|
||||
|
||||
int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
|
||||
{
|
||||
pEntryPoints->Version = 1;
|
||||
|
@ -321,7 +321,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
channels = instance->context->channels;
|
||||
|
||||
status = freerdp_client_parse_command_line_arguments(argc, argv, instance->settings);
|
||||
status = freerdp_client_settings_parse_command_line(instance->settings, argc, argv);
|
||||
|
||||
if (status < 0)
|
||||
exit(0);
|
||||
|
@ -63,7 +63,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(WITH_CLIENT_INTERFACE)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT WinPRTargets)
|
||||
add_subdirectory(cli)
|
||||
else()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client)
|
||||
|
@ -70,9 +70,9 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
for (index = 0; index < context->argc; index++)
|
||||
context->argv[index] = _strdup(__argv[index]);
|
||||
|
||||
status = freerdp_client_parse_command_line(context, context->argc, context->argv);
|
||||
status = freerdp_client_settings_parse_command_line(settings, context->argc, context->argv);
|
||||
|
||||
status = freerdp_client_command_line_status_print(context->argc, context->argv, settings, status);
|
||||
status = freerdp_client_settings_command_line_status_print(settings, status, context->argc, context->argv);
|
||||
|
||||
if (status)
|
||||
{
|
||||
|
@ -588,7 +588,7 @@ void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16
|
||||
dw = wfc->instance->settings->DesktopWidth;
|
||||
dh = wfc->instance->settings->DesktopHeight;
|
||||
|
||||
if (!wfc->instance->settings->SmartSizing || (ww == dw) && (wh == dh))
|
||||
if (!wfc->instance->settings->SmartSizing || ((ww == dw) && (wh == dh)))
|
||||
input->MouseEvent(input, flags, x + wfc->xCurrentScroll, y + wfc->yCurrentScroll);
|
||||
else
|
||||
input->MouseEvent(input, flags, x * dw / ww + wfc->xCurrentScroll, y * dh / wh + wfc->yCurrentScroll);
|
||||
|
@ -10,7 +10,7 @@
|
||||
* 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
|
||||
* 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,
|
||||
@ -49,6 +49,7 @@
|
||||
#include <freerdp/client/cmdline.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
#include <freerdp/channels/channels.h>
|
||||
#include <freerdp/event.h>
|
||||
|
||||
#include "wf_gdi.h"
|
||||
#include "wf_graphics.h"
|
||||
@ -331,6 +332,7 @@ BOOL wf_post_connect(freerdp* instance)
|
||||
rdpContext* context;
|
||||
WCHAR lpWindowName[64];
|
||||
rdpSettings* settings;
|
||||
EmbedWindowEventArgs e;
|
||||
|
||||
settings = instance->settings;
|
||||
context = instance->context;
|
||||
@ -388,6 +390,9 @@ BOOL wf_post_connect(freerdp* instance)
|
||||
else
|
||||
_snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"FreeRDP: %S:%d", settings->ServerHostname, settings->ServerPort);
|
||||
|
||||
if (settings->EmbeddedWindow)
|
||||
settings->Decorations = FALSE;
|
||||
|
||||
if (!settings->Decorations)
|
||||
dwStyle = WS_CHILD | WS_BORDER;
|
||||
else
|
||||
@ -398,7 +403,7 @@ BOOL wf_post_connect(freerdp* instance)
|
||||
wfc->hwnd = CreateWindowEx((DWORD) NULL, wfc->wndClassName, lpWindowName, dwStyle,
|
||||
0, 0, 0, 0, wfc->hWndParent, NULL, wfc->hInstance, NULL);
|
||||
|
||||
SetWindowLongPtr(wfc->hwnd, GWLP_USERDATA, (LONG_PTR) wfc);
|
||||
SetWindowLongPtr(wfc->hwnd, GWLP_USERDATA, (LONG_PTR) wfc);
|
||||
}
|
||||
|
||||
wf_resize_window(wfc);
|
||||
@ -408,6 +413,11 @@ BOOL wf_post_connect(freerdp* instance)
|
||||
BitBlt(wfc->primary->hdc, 0, 0, wfc->width, wfc->height, NULL, 0, 0, BLACKNESS);
|
||||
wfc->drawing = wfc->primary;
|
||||
|
||||
EventArgsInit(&e, "wfreerdp");
|
||||
e.embed = FALSE;
|
||||
e.handle = (void*) wfc->hwnd;
|
||||
PubSub_OnEmbedWindow(context->pubSub, context, &e);
|
||||
|
||||
ShowWindow(wfc->hwnd, SW_SHOWNORMAL);
|
||||
UpdateWindow(wfc->hwnd);
|
||||
|
||||
@ -778,6 +788,8 @@ int freerdp_client_focus_out(wfContext* wfc)
|
||||
|
||||
int freerdp_client_set_window_size(wfContext* wfc, int width, int height)
|
||||
{
|
||||
fprintf(stderr, "freerdp_client_set_window_size %d, %d", width, height);
|
||||
|
||||
if ((width != wfc->client_width) || (height != wfc->client_height))
|
||||
{
|
||||
PostThreadMessage(wfc->mainThreadId, WM_SIZE, SIZE_RESTORED, ((UINT) height << 16) | (UINT) width);
|
||||
@ -786,19 +798,19 @@ int freerdp_client_set_window_size(wfContext* wfc, int width, int height)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wf_on_param_change(freerdp* instance, int id)
|
||||
void wf_ParamChangeEventHandler(rdpContext* context, ParamChangeEventArgs* e)
|
||||
{
|
||||
RECT rect;
|
||||
HMENU hMenu;
|
||||
wfContext* wfc = (wfContext*) instance->context;
|
||||
wfContext* wfc = (wfContext*) context;
|
||||
|
||||
// specific processing here
|
||||
switch (id)
|
||||
switch (e->id)
|
||||
{
|
||||
case FreeRDP_SmartSizing:
|
||||
fprintf(stderr, "SmartSizing changed.\n");
|
||||
|
||||
if (!instance->settings->SmartSizing && (wfc->client_width > instance->settings->DesktopWidth || wfc->client_height > instance->settings->DesktopHeight))
|
||||
if (!context->settings->SmartSizing && (wfc->client_width > context->settings->DesktopWidth || wfc->client_height > context->settings->DesktopHeight))
|
||||
{
|
||||
GetWindowRect(wfc->hwnd, &rect);
|
||||
SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, MIN(wfc->client_width + wfc->offset_x, rect.right - rect.left), MIN(wfc->client_height + wfc->offset_y, rect.bottom - rect.top), SWP_NOMOVE | SWP_FRAMECHANGED);
|
||||
@ -806,7 +818,7 @@ void wf_on_param_change(freerdp* instance, int id)
|
||||
}
|
||||
|
||||
hMenu = GetSystemMenu(wfc->hwnd, FALSE);
|
||||
CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, instance->settings->SmartSizing);
|
||||
CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, context->settings->SmartSizing);
|
||||
wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height);
|
||||
GetClientRect(wfc->hwnd, &rect);
|
||||
InvalidateRect(wfc->hwnd, &rect, TRUE);
|
||||
@ -1036,6 +1048,8 @@ int wfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
wfc->instance = instance;
|
||||
context->channels = freerdp_channels_new();
|
||||
|
||||
PubSub_SubscribeParamChange(context->pubSub, wf_ParamChangeEventHandler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -140,6 +140,8 @@ typedef struct wf_context wfContext;
|
||||
*/
|
||||
|
||||
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
|
||||
FREERDP_API int freerdp_client_set_window_size(wfContext* wfc, int width, int height);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ if(WITH_IPP)
|
||||
endif()
|
||||
|
||||
if(WITH_CLIENT_INTERFACE)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT FreeRDPTargets)
|
||||
add_subdirectory(cli)
|
||||
else()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client)
|
||||
|
@ -53,9 +53,9 @@ int main(int argc, char* argv[])
|
||||
settings = context->settings;
|
||||
xfc = (xfContext*) context;
|
||||
|
||||
status = freerdp_client_parse_command_line(context, argc, argv);
|
||||
status = freerdp_client_settings_parse_command_line(context->settings, argc, argv);
|
||||
|
||||
status = freerdp_client_command_line_status_print(argc, argv, settings, status);
|
||||
status = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
|
||||
if (status)
|
||||
{
|
||||
|
@ -728,8 +728,12 @@ static void xf_post_disconnect(freerdp *instance)
|
||||
assert(NULL != xfc);
|
||||
assert(NULL != instance->settings);
|
||||
|
||||
WaitForSingleObject(xfc->mutex, INFINITE);
|
||||
CloseHandle(xfc->mutex);
|
||||
if (xfc->mutex)
|
||||
{
|
||||
WaitForSingleObject(xfc->mutex, INFINITE);
|
||||
CloseHandle(xfc->mutex);
|
||||
xfc->mutex = NULL;
|
||||
}
|
||||
|
||||
xf_monitors_free(xfc, instance->settings);
|
||||
}
|
||||
@ -750,13 +754,41 @@ BOOL xf_pre_connect(freerdp* instance)
|
||||
rdpSettings* settings;
|
||||
xfContext* xfc = (xfContext*) instance->context;
|
||||
|
||||
xfc->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
xfc->settings = instance->settings;
|
||||
xfc->instance = instance;
|
||||
|
||||
settings = instance->settings;
|
||||
channels = instance->context->channels;
|
||||
|
||||
xfc->UseXThreads = TRUE;
|
||||
|
||||
if (xfc->UseXThreads)
|
||||
{
|
||||
if (!XInitThreads())
|
||||
{
|
||||
fprintf(stderr, "warning: XInitThreads() failure\n");
|
||||
xfc->UseXThreads = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
xfc->display = XOpenDisplay(NULL);
|
||||
|
||||
if (!xfc->display)
|
||||
{
|
||||
fprintf(stderr, "xf_pre_connect: failed to open display: %s\n", XDisplayName(NULL));
|
||||
fprintf(stderr, "Please check that the $DISPLAY environment variable is properly set.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (xfc->debug)
|
||||
{
|
||||
fprintf(stderr, "Enabling X11 debug mode.\n");
|
||||
XSynchronize(xfc->display, TRUE);
|
||||
_def_error_handler = XSetErrorHandler(_xf_error_handler);
|
||||
}
|
||||
|
||||
xfc->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
PubSub_SubscribeChannelConnected(instance->context->pubSub,
|
||||
(pChannelConnectedEventHandler) xf_OnChannelConnectedEventHandler);
|
||||
|
||||
@ -785,33 +817,6 @@ BOOL xf_pre_connect(freerdp* instance)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
xfc->UseXThreads = TRUE;
|
||||
|
||||
if (xfc->UseXThreads)
|
||||
{
|
||||
if (!XInitThreads())
|
||||
{
|
||||
fprintf(stderr, "warning: XInitThreads() failure\n");
|
||||
xfc->UseXThreads = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
xfc->display = XOpenDisplay(NULL);
|
||||
|
||||
if (!xfc->display)
|
||||
{
|
||||
fprintf(stderr, "xf_pre_connect: failed to open display: %s\n", XDisplayName(NULL));
|
||||
fprintf(stderr, "Please check that the $DISPLAY environment variable is properly set.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (xfc->debug)
|
||||
{
|
||||
fprintf(stderr, "Enabling X11 debug mode.\n");
|
||||
XSynchronize(xfc->display, TRUE);
|
||||
_def_error_handler = XSetErrorHandler(_xf_error_handler);
|
||||
}
|
||||
|
||||
xfc->_NET_WM_ICON = XInternAtom(xfc->display, "_NET_WM_ICON", False);
|
||||
xfc->_MOTIF_WM_HINTS = XInternAtom(xfc->display, "_MOTIF_WM_HINTS", False);
|
||||
xfc->_NET_CURRENT_DESKTOP = XInternAtom(xfc->display, "_NET_CURRENT_DESKTOP", False);
|
||||
@ -937,6 +942,10 @@ BOOL xf_post_connect(freerdp* instance)
|
||||
xf_create_window(xfc);
|
||||
|
||||
ZeroMemory(&gcv, sizeof(gcv));
|
||||
|
||||
if (xfc->modifier_map)
|
||||
XFreeModifiermap(xfc->modifier_map);
|
||||
|
||||
xfc->modifier_map = XGetModifierMapping(xfc->display);
|
||||
|
||||
xfc->gc = XCreateGC(xfc->display, xfc->drawable, GCGraphicsExposures, &gcv);
|
||||
@ -1388,6 +1397,15 @@ void* xf_thread(void* param)
|
||||
|
||||
if (!status)
|
||||
{
|
||||
if (xfc->mutex)
|
||||
{
|
||||
WaitForSingleObject(xfc->mutex, INFINITE);
|
||||
CloseHandle(xfc->mutex);
|
||||
xfc->mutex = NULL;
|
||||
}
|
||||
|
||||
xf_monitors_free(xfc, instance->settings);
|
||||
|
||||
exit_code = XF_EXIT_CONN_FAILED;
|
||||
ExitThread(exit_code);
|
||||
}
|
||||
@ -1754,6 +1772,7 @@ static int xfreerdp_client_stop(rdpContext* context)
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
assert(NULL != context);
|
||||
|
||||
if (context->settings->AsyncInput)
|
||||
{
|
||||
wMessageQueue* queue;
|
||||
@ -1828,7 +1847,6 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
PubSub_SubscribeParamChange(context->pubSub, (pParamChangeEventHandler) xf_ParamChangeEventHandler);
|
||||
PubSub_SubscribeScalingFactorChange(context->pubSub, (pScalingFactorChangeEventHandler) xf_ScalingFactorChangeEventHandler);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -475,7 +475,9 @@ static BOOL xf_event_MappingNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
if (event->xmapping.request == MappingModifier)
|
||||
{
|
||||
XFreeModifiermap(xfc->modifier_map);
|
||||
if (xfc->modifier_map)
|
||||
XFreeModifiermap(xfc->modifier_map);
|
||||
|
||||
xfc->modifier_map = XGetModifierMapping(xfc->display);
|
||||
}
|
||||
|
||||
|
@ -38,9 +38,14 @@
|
||||
void xf_kbd_init(xfContext* xfc)
|
||||
{
|
||||
xf_kbd_clear(xfc);
|
||||
|
||||
xfc->keyboard_layout_id = xfc->instance->settings->KeyboardLayout;
|
||||
xfc->keyboard_layout_id = freerdp_keyboard_init(xfc->keyboard_layout_id);
|
||||
xfc->instance->settings->KeyboardLayout = xfc->keyboard_layout_id;
|
||||
|
||||
if (xfc->modifier_map)
|
||||
XFreeModifiermap(xfc->modifier_map);
|
||||
|
||||
xfc->modifier_map = XGetModifierMapping(xfc->display);
|
||||
}
|
||||
|
||||
|
@ -261,10 +261,16 @@ BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings)
|
||||
void xf_monitors_free(xfContext *xfc, rdpSettings *settings)
|
||||
{
|
||||
#ifdef WITH_XINERAMA
|
||||
if(xfc->vscreen.monitors)
|
||||
if (xfc->vscreen.monitors)
|
||||
{
|
||||
free(xfc->vscreen.monitors);
|
||||
xfc->vscreen.monitors = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(settings->MonitorIds)
|
||||
if (settings->MonitorIds)
|
||||
{
|
||||
free(settings->MonitorIds);
|
||||
settings->MonitorIds = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -662,9 +662,9 @@ void xf_process_rail_appid_resp_event(xfContext* xfc, rdpChannels* channels, wMe
|
||||
|
||||
fprintf(stderr, "Server Application ID Response PDU: windowId=0x%X "
|
||||
"applicationId=(length=%d dump)\n",
|
||||
appid_resp->windowId, appid_resp->applicationId.length);
|
||||
appid_resp->windowId, 512);
|
||||
|
||||
winpr_HexDump(appid_resp->applicationId.string, appid_resp->applicationId.length);
|
||||
winpr_HexDump((BYTE*) &appid_resp->applicationId, 512);
|
||||
}
|
||||
|
||||
void xf_process_rail_langbarinfo_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
|
||||
|
@ -18,6 +18,9 @@
|
||||
set(MODULE_NAME "freerdp-client")
|
||||
set(MODULE_PREFIX "FREERDP_CLIENT")
|
||||
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
client.c
|
||||
cmdline.c
|
||||
@ -50,9 +53,11 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHI
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-utils)
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "")
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Common")
|
||||
|
||||
|
@ -50,6 +50,7 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
|
||||
pEntryPoints->GlobalInit();
|
||||
|
||||
instance = freerdp_new();
|
||||
instance->settings = pEntryPoints->settings;
|
||||
instance->ContextSize = pEntryPoints->ContextSize;
|
||||
instance->ContextNew = freerdp_client_common_new;
|
||||
instance->ContextFree = freerdp_client_common_free;
|
||||
@ -70,9 +71,12 @@ void freerdp_client_context_free(rdpContext* context)
|
||||
{
|
||||
freerdp* instance = context->instance;
|
||||
|
||||
free(instance->pClientEntryPoints);
|
||||
freerdp_context_free(instance);
|
||||
freerdp_free(instance);
|
||||
if (instance)
|
||||
{
|
||||
freerdp_context_free(instance);
|
||||
free(instance->pClientEntryPoints);
|
||||
freerdp_free(instance);
|
||||
}
|
||||
}
|
||||
|
||||
int freerdp_client_start(rdpContext* context)
|
||||
@ -97,45 +101,39 @@ HANDLE freerdp_client_get_thread(rdpContext* context)
|
||||
return ((rdpClientContext*) context)->thread;
|
||||
}
|
||||
|
||||
int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv)
|
||||
int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, char** argv)
|
||||
{
|
||||
int status;
|
||||
rdpSettings* settings;
|
||||
|
||||
context->argc = argc;
|
||||
context->argv = argv;
|
||||
|
||||
if (context->argc < 1)
|
||||
if (argc < 1)
|
||||
return 0;
|
||||
|
||||
if (!context->argv)
|
||||
if (!argv)
|
||||
return -1;
|
||||
|
||||
settings = context->settings;
|
||||
|
||||
status = freerdp_client_parse_command_line_arguments(context->argc, context->argv, settings);
|
||||
status = freerdp_client_settings_parse_command_line_arguments(settings, argc, argv);
|
||||
|
||||
if (settings->ConnectionFile)
|
||||
{
|
||||
status = freerdp_client_parse_connection_file(context, settings->ConnectionFile);
|
||||
status = freerdp_client_settings_parse_connection_file(settings, settings->ConnectionFile);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int freerdp_client_parse_connection_file(rdpContext* context, const char* filename)
|
||||
int freerdp_client_settings_parse_connection_file(rdpSettings* settings, const char* filename)
|
||||
{
|
||||
rdpFile* file;
|
||||
|
||||
file = freerdp_client_rdp_file_new();
|
||||
freerdp_client_parse_rdp_file(file, filename);
|
||||
freerdp_client_populate_settings_from_rdp_file(file, context->settings);
|
||||
freerdp_client_populate_settings_from_rdp_file(file, settings);
|
||||
freerdp_client_rdp_file_free(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size)
|
||||
int freerdp_client_settings_parse_connection_file_buffer(rdpSettings* settings, BYTE* buffer, size_t size)
|
||||
{
|
||||
rdpFile* file;
|
||||
int status = -1;
|
||||
@ -143,7 +141,7 @@ int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffe
|
||||
file = freerdp_client_rdp_file_new();
|
||||
|
||||
if (freerdp_client_parse_rdp_file_buffer(file, buffer, size)
|
||||
&& freerdp_client_populate_settings_from_rdp_file(file, context->settings))
|
||||
&& freerdp_client_populate_settings_from_rdp_file(file, settings))
|
||||
{
|
||||
status = 0;
|
||||
}
|
||||
@ -153,14 +151,14 @@ int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffe
|
||||
return status;
|
||||
}
|
||||
|
||||
int freerdp_client_write_connection_file(rdpContext* context, const char* filename, BOOL unicode)
|
||||
int freerdp_client_settings_write_connection_file(rdpSettings* settings, const char* filename, BOOL unicode)
|
||||
{
|
||||
rdpFile* file;
|
||||
int status = -1;
|
||||
|
||||
file = freerdp_client_rdp_file_new();
|
||||
|
||||
if (freerdp_client_populate_rdp_file_from_settings(file, context->settings))
|
||||
if (freerdp_client_populate_rdp_file_from_settings(file, settings))
|
||||
{
|
||||
if (freerdp_client_write_rdp_file(file, filename, unicode))
|
||||
{
|
||||
|
@ -52,6 +52,8 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "kbd-subtype", COMMAND_LINE_VALUE_REQUIRED, "<subtype id>", NULL, NULL, -1, NULL, "Keyboard subtype" },
|
||||
{ "kbd-fn-key", COMMAND_LINE_VALUE_REQUIRED, "<function key count>", NULL, NULL, -1, NULL, "Keyboard function key count" },
|
||||
{ "admin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "console", "Admin (or console) session" },
|
||||
{ "restricted-admin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "restrictedAdmin", "Restricted admin mode" },
|
||||
{ "pth", COMMAND_LINE_VALUE_REQUIRED, "<password hash>", NULL, NULL, -1, "pass-the-hash", "Pass the hash (restricted admin mode)" },
|
||||
{ "multimon", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Use multiple monitors" },
|
||||
{ "workarea", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Use available work area" },
|
||||
{ "monitors", COMMAND_LINE_VALUE_REQUIRED, "<0,1,2...>", NULL, NULL, -1, NULL, "Select monitors to use" },
|
||||
@ -104,6 +106,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "themes", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Themes" },
|
||||
{ "wallpaper", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Wallpaper" },
|
||||
{ "gdi", COMMAND_LINE_VALUE_REQUIRED, "<sw|hw>", NULL, NULL, -1, NULL, "GDI rendering" },
|
||||
{ "gfx", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "RDP8 graphics pipeline (experimental)" },
|
||||
{ "rfx", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "RemoteFX" },
|
||||
{ "rfx-mode", COMMAND_LINE_VALUE_REQUIRED, "<image|video>", NULL, NULL, -1, NULL, "RemoteFX mode" },
|
||||
{ "frame-ack", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL, "Frame acknowledgement" },
|
||||
@ -1010,7 +1013,7 @@ BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags)
|
||||
return compatibility;
|
||||
}
|
||||
|
||||
int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* settings, int status)
|
||||
int freerdp_client_settings_command_line_status_print(rdpSettings* settings, int status, int argc, char** argv)
|
||||
{
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
|
||||
@ -1067,7 +1070,7 @@ int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings*
|
||||
return 0;
|
||||
}
|
||||
|
||||
int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings)
|
||||
int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, int argc, char** argv)
|
||||
{
|
||||
char* p;
|
||||
char* str;
|
||||
@ -1231,6 +1234,17 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
{
|
||||
settings->ConsoleSession = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "restricted-admin")
|
||||
{
|
||||
settings->ConsoleSession = TRUE;
|
||||
settings->RestrictedAdminModeRequired = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "pth")
|
||||
{
|
||||
settings->ConsoleSession = TRUE;
|
||||
settings->RestrictedAdminModeRequired = TRUE;
|
||||
settings->PasswordHash = _strdup(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "kbd")
|
||||
{
|
||||
int id;
|
||||
@ -1470,6 +1484,10 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
else if (strcmp(arg->Value, "hw") == 0)
|
||||
settings->SoftwareGdi = FALSE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "gfx")
|
||||
{
|
||||
settings->SupportGraphicsPipeline = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "rfx")
|
||||
{
|
||||
settings->RemoteFxCodec = TRUE;
|
||||
@ -1492,7 +1510,10 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
CommandLineSwitchCase(arg, "nsc")
|
||||
{
|
||||
settings->NSCodec = TRUE;
|
||||
settings->FastPathOutput = TRUE;
|
||||
settings->ColorDepth = 32;
|
||||
settings->LargePointerFlag = TRUE;
|
||||
settings->FrameMarkerCommandEnabled = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "jpeg")
|
||||
{
|
||||
@ -1740,7 +1761,7 @@ int freerdp_client_load_static_channel_addin(rdpChannels* channels, rdpSettings*
|
||||
{
|
||||
void* entry;
|
||||
|
||||
entry = freerdp_load_channel_addin_entry(name, NULL, NULL, 0);
|
||||
entry = freerdp_load_channel_addin_entry(name, NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
@ -1841,6 +1862,17 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
|
||||
freerdp_client_load_static_channel_addin(channels, settings, "rail", settings);
|
||||
}
|
||||
|
||||
if (settings->SupportGraphicsPipeline)
|
||||
{
|
||||
char* p[1];
|
||||
int count;
|
||||
|
||||
count = 1;
|
||||
p[0] = "rdpgfx";
|
||||
|
||||
freerdp_client_add_dynamic_channel(settings, count, p);
|
||||
}
|
||||
|
||||
if (settings->DynamicChannelCount)
|
||||
{
|
||||
freerdp_client_load_static_channel_addin(channels, settings, "drdynvc", settings);
|
||||
|
@ -321,10 +321,15 @@ int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count)
|
||||
ZeroMemory(settings, sizeof(rdpSettings));
|
||||
|
||||
CommandLineClearArgumentsA(old_args);
|
||||
|
||||
status = CommandLineParseArgumentsA(argc, (const char**) argv, old_args, flags, settings,
|
||||
freerdp_client_old_command_line_pre_filter, NULL);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
free(settings);
|
||||
return status;
|
||||
}
|
||||
|
||||
arg = old_args;
|
||||
|
||||
|
@ -481,6 +481,7 @@ BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t si
|
||||
|
||||
BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name)
|
||||
{
|
||||
BOOL status;
|
||||
BYTE* buffer;
|
||||
FILE* fp = NULL;
|
||||
size_t read_size;
|
||||
@ -521,11 +522,15 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name)
|
||||
buffer[file_size] = '\0';
|
||||
buffer[file_size + 1] = '\0';
|
||||
|
||||
return freerdp_client_parse_rdp_file_buffer(file, buffer, file_size);
|
||||
status = freerdp_client_parse_rdp_file_buffer(file, buffer, file_size);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#define WRITE_ALL_SETTINGS FALSE
|
||||
#define SETTING_MODIFIED(_settings, _field) (WRITE_ALL_SETTINGS || _settings->settings_modified[FreeRDP_##_field])
|
||||
#define WRITE_ALL_SETTINGS TRUE
|
||||
#define SETTING_MODIFIED(_settings, _field) (WRITE_ALL_SETTINGS || _settings->SettingsModified[FreeRDP_##_field])
|
||||
#define SETTING_MODIFIED_SET(_target, _settings, _field) if SETTING_MODIFIED(_settings, _field) _target = _settings->_field
|
||||
|
||||
BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings)
|
||||
@ -960,12 +965,18 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
|
||||
|
||||
if (file->argc > 1)
|
||||
{
|
||||
freerdp_client_parse_command_line_arguments(file->argc, file->argv, settings);
|
||||
freerdp_client_settings_parse_command_line(settings, file->argc, file->argv);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void freerdp_client_file_string_check_free(LPSTR str)
|
||||
{
|
||||
if (~((size_t) str))
|
||||
free(str);
|
||||
}
|
||||
|
||||
rdpFile* freerdp_client_rdp_file_new()
|
||||
{
|
||||
rdpFile* file;
|
||||
@ -1000,6 +1011,26 @@ void freerdp_client_rdp_file_free(rdpFile* file)
|
||||
free(file->argv);
|
||||
}
|
||||
|
||||
freerdp_client_file_string_check_free(file->Username);
|
||||
freerdp_client_file_string_check_free(file->Domain);
|
||||
freerdp_client_file_string_check_free(file->FullAddress);
|
||||
freerdp_client_file_string_check_free(file->AlternateFullAddress);
|
||||
freerdp_client_file_string_check_free(file->UsbDevicesToRedirect);
|
||||
freerdp_client_file_string_check_free(file->LoadBalanceInfo);
|
||||
freerdp_client_file_string_check_free(file->RemoteApplicationName);
|
||||
freerdp_client_file_string_check_free(file->RemoteApplicationIcon);
|
||||
freerdp_client_file_string_check_free(file->RemoteApplicationProgram);
|
||||
freerdp_client_file_string_check_free(file->RemoteApplicationFile);
|
||||
freerdp_client_file_string_check_free(file->RemoteApplicationGuid);
|
||||
freerdp_client_file_string_check_free(file->RemoteApplicationCmdLine);
|
||||
freerdp_client_file_string_check_free(file->AlternateShell);
|
||||
freerdp_client_file_string_check_free(file->ShellWorkingDirectory);
|
||||
freerdp_client_file_string_check_free(file->GatewayHostname);
|
||||
freerdp_client_file_string_check_free(file->KdcProxyName);
|
||||
freerdp_client_file_string_check_free(file->DrivesToRedirect);
|
||||
freerdp_client_file_string_check_free(file->DevicesToRedirect);
|
||||
freerdp_client_file_string_check_free(file->WinPosStr);
|
||||
|
||||
free(file);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,8 @@ macro(enable_cmake_compat CMVERSION)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Compatibility includes - oder does matter!
|
||||
# Compatibility includes - order does matter!
|
||||
enable_cmake_compat(2.8.11)
|
||||
enable_cmake_compat(2.8.6)
|
||||
enable_cmake_compat(2.8.3)
|
||||
enable_cmake_compat(2.8.2)
|
||||
|
@ -0,0 +1,31 @@
|
||||
# This is a basic version file for the Config-mode of find_package().
|
||||
# It is used by write_basic_package_version_file() as input file for configure_file()
|
||||
# to create a version-file which can be installed along a config.cmake file.
|
||||
#
|
||||
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
|
||||
# the requested version string are exactly the same and it sets
|
||||
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
|
||||
# The variable CVF_VERSION must be set before calling configure_file().
|
||||
|
||||
set(PACKAGE_VERSION "@CVF_VERSION@")
|
||||
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
|
||||
if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@")
|
||||
math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
|
||||
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
endif()
|
47
cmake/compat_2.8.11/BasicConfigVersion-ExactVersion.cmake.in
Normal file
47
cmake/compat_2.8.11/BasicConfigVersion-ExactVersion.cmake.in
Normal file
@ -0,0 +1,47 @@
|
||||
# This is a basic version file for the Config-mode of find_package().
|
||||
# It is used by write_basic_package_version_file() as input file for configure_file()
|
||||
# to create a version-file which can be installed along a config.cmake file.
|
||||
#
|
||||
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
|
||||
# the requested version string are exactly the same and it sets
|
||||
# PACKAGE_VERSION_COMPATIBLE if the current version is equal to the requested version.
|
||||
# The tweak version component is ignored.
|
||||
# The variable CVF_VERSION must be set before calling configure_file().
|
||||
|
||||
|
||||
set(PACKAGE_VERSION "@CVF_VERSION@")
|
||||
|
||||
if("@CVF_VERSION@" MATCHES "^([0-9]+\\.[0-9]+\\.[0-9]+)\\..*") # strip the tweak version
|
||||
set(CVF_VERSION_NO_TWEAK "${CMAKE_MATCH_1}")
|
||||
else()
|
||||
set(CVF_VERSION_NO_TWEAK "@CVF_VERSION@")
|
||||
endif()
|
||||
|
||||
if("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+\\.[0-9]+\\.[0-9]+)\\..*") # strip the tweak version
|
||||
set(REQUESTED_VERSION_NO_TWEAK "${CMAKE_MATCH_1}")
|
||||
else()
|
||||
set(REQUESTED_VERSION_NO_TWEAK "${PACKAGE_FIND_VERSION}")
|
||||
endif()
|
||||
|
||||
if("${REQUESTED_VERSION_NO_TWEAK}" STREQUAL "${CVF_VERSION_NO_TWEAK}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
endif()
|
||||
|
||||
if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
|
||||
if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@")
|
||||
math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
|
||||
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
endif()
|
@ -0,0 +1,46 @@
|
||||
# This is a basic version file for the Config-mode of find_package().
|
||||
# It is used by write_basic_package_version_file() as input file for configure_file()
|
||||
# to create a version-file which can be installed along a config.cmake file.
|
||||
#
|
||||
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
|
||||
# the requested version string are exactly the same and it sets
|
||||
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version,
|
||||
# but only if the requested major version is the same as the current one.
|
||||
# The variable CVF_VERSION must be set before calling configure_file().
|
||||
|
||||
|
||||
set(PACKAGE_VERSION "@CVF_VERSION@")
|
||||
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
|
||||
if("@CVF_VERSION@" MATCHES "^([0-9]+)\\.")
|
||||
set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
else()
|
||||
set(CVF_VERSION_MAJOR "@CVF_VERSION@")
|
||||
endif()
|
||||
|
||||
if("${PACKAGE_FIND_VERSION_MAJOR}" STREQUAL "${CVF_VERSION_MAJOR}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
endif()
|
||||
|
||||
if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
|
||||
if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@")
|
||||
math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
|
||||
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
endif()
|
248
cmake/compat_2.8.11/CMakePackageConfigHelpers.cmake
Normal file
248
cmake/compat_2.8.11/CMakePackageConfigHelpers.cmake
Normal file
@ -0,0 +1,248 @@
|
||||
# - CONFIGURE_PACKAGE_CONFIG_FILE(), WRITE_BASIC_PACKAGE_VERSION_FILE()
|
||||
#
|
||||
# CONFIGURE_PACKAGE_CONFIG_FILE(<input> <output> INSTALL_DESTINATION <path>
|
||||
# [PATH_VARS <var1> <var2> ... <varN>]
|
||||
# [NO_SET_AND_CHECK_MACRO]
|
||||
# [NO_CHECK_REQUIRED_COMPONENTS_MACRO])
|
||||
#
|
||||
# CONFIGURE_PACKAGE_CONFIG_FILE() should be used instead of the plain
|
||||
# configure_file() command when creating the <Name>Config.cmake or <Name>-config.cmake
|
||||
# file for installing a project or library. It helps making the resulting package
|
||||
# relocatable by avoiding hardcoded paths in the installed Config.cmake file.
|
||||
#
|
||||
# In a FooConfig.cmake file there may be code like this to make the
|
||||
# install destinations know to the using project:
|
||||
# set(FOO_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@" )
|
||||
# set(FOO_DATA_DIR "@CMAKE_INSTALL_PREFIX@/@RELATIVE_DATA_INSTALL_DIR@" )
|
||||
# set(FOO_ICONS_DIR "@CMAKE_INSTALL_PREFIX@/share/icons" )
|
||||
# ...logic to determine installedPrefix from the own location...
|
||||
# set(FOO_CONFIG_DIR "${installedPrefix}/@CONFIG_INSTALL_DIR@" )
|
||||
# All 4 options shown above are not sufficient, since the first 3 hardcode
|
||||
# the absolute directory locations, and the 4th case works only if the logic
|
||||
# to determine the installedPrefix is correct, and if CONFIG_INSTALL_DIR contains
|
||||
# a relative path, which in general cannot be guaranteed.
|
||||
# This has the effect that the resulting FooConfig.cmake file would work poorly
|
||||
# under Windows and OSX, where users are used to choose the install location
|
||||
# of a binary package at install time, independent from how CMAKE_INSTALL_PREFIX
|
||||
# was set at build/cmake time.
|
||||
#
|
||||
# Using CONFIGURE_PACKAGE_CONFIG_FILE() helps. If used correctly, it makes the
|
||||
# resulting FooConfig.cmake file relocatable.
|
||||
# Usage:
|
||||
# 1. write a FooConfig.cmake.in file as you are used to
|
||||
# 2. insert a line containing only the string "@PACKAGE_INIT@"
|
||||
# 3. instead of set(FOO_DIR "@SOME_INSTALL_DIR@"), use set(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@")
|
||||
# (this must be after the @PACKAGE_INIT@ line)
|
||||
# 4. instead of using the normal configure_file(), use CONFIGURE_PACKAGE_CONFIG_FILE()
|
||||
#
|
||||
# The <input> and <output> arguments are the input and output file, the same way
|
||||
# as in configure_file().
|
||||
#
|
||||
# The <path> given to INSTALL_DESTINATION must be the destination where the FooConfig.cmake
|
||||
# file will be installed to. This can either be a relative or absolute path, both work.
|
||||
#
|
||||
# The variables <var1> to <varN> given as PATH_VARS are the variables which contain
|
||||
# install destinations. For each of them the macro will create a helper variable
|
||||
# PACKAGE_<var...>. These helper variables must be used
|
||||
# in the FooConfig.cmake.in file for setting the installed location. They are calculated
|
||||
# by CONFIGURE_PACKAGE_CONFIG_FILE() so that they are always relative to the
|
||||
# installed location of the package. This works both for relative and also for absolute locations.
|
||||
# For absolute locations it works only if the absolute location is a subdirectory
|
||||
# of CMAKE_INSTALL_PREFIX.
|
||||
#
|
||||
# By default configure_package_config_file() also generates two helper macros,
|
||||
# set_and_check() and check_required_components() into the FooConfig.cmake file.
|
||||
#
|
||||
# set_and_check() should be used instead of the normal set()
|
||||
# command for setting directories and file locations. Additionally to setting the
|
||||
# variable it also checks that the referenced file or directory actually exists
|
||||
# and fails with a FATAL_ERROR otherwise. This makes sure that the created
|
||||
# FooConfig.cmake file does not contain wrong references.
|
||||
# When using the NO_SET_AND_CHECK_MACRO, this macro is not generated into the
|
||||
# FooConfig.cmake file.
|
||||
#
|
||||
# check_required_components(<package_name>) should be called at the end of the
|
||||
# FooConfig.cmake file if the package supports components.
|
||||
# This macro checks whether all requested, non-optional components have been found,
|
||||
# and if this is not the case, sets the Foo_FOUND variable to FALSE, so that the package
|
||||
# is considered to be not found.
|
||||
# It does that by testing the Foo_<Component>_FOUND variables for all requested
|
||||
# required components.
|
||||
# When using the NO_CHECK_REQUIRED_COMPONENTS option, this macro is not generated
|
||||
# into the FooConfig.cmake file.
|
||||
#
|
||||
# For an example see below the documentation for WRITE_BASIC_PACKAGE_VERSION_FILE().
|
||||
#
|
||||
#
|
||||
# WRITE_BASIC_PACKAGE_VERSION_FILE( filename VERSION major.minor.patch COMPATIBILITY (AnyNewerVersion|SameMajorVersion|ExactVersion) )
|
||||
#
|
||||
# Writes a file for use as <package>ConfigVersion.cmake file to <filename>.
|
||||
# See the documentation of find_package() for details on this.
|
||||
# filename is the output filename, it should be in the build tree.
|
||||
# major.minor.patch is the version number of the project to be installed
|
||||
# The COMPATIBILITY mode AnyNewerVersion means that the installed package version
|
||||
# will be considered compatible if it is newer or exactly the same as the requested version.
|
||||
# This mode should be used for packages which are fully backward compatible,
|
||||
# also across major versions.
|
||||
# If SameMajorVersion is used instead, then the behaviour differs from AnyNewerVersion
|
||||
# in that the major version number must be the same as requested, e.g. version 2.0 will
|
||||
# not be considered compatible if 1.0 is requested.
|
||||
# This mode should be used for packages which guarantee backward compatibility within the
|
||||
# same major version.
|
||||
# If ExactVersion is used, then the package is only considered compatible if the requested
|
||||
# version matches exactly its own version number (not considering the tweak version).
|
||||
# For example, version 1.2.3 of a package is only considered compatible to requested version 1.2.3.
|
||||
# This mode is for packages without compatibility guarantees.
|
||||
# If your project has more elaborated version matching rules, you will need to write your
|
||||
# own custom ConfigVersion.cmake file instead of using this macro.
|
||||
#
|
||||
# Internally, this macro executes configure_file() to create the resulting
|
||||
# version file. Depending on the COMPATIBLITY, either the file
|
||||
# BasicConfigVersion-SameMajorVersion.cmake.in or BasicConfigVersion-AnyNewerVersion.cmake.in
|
||||
# is used. Please note that these two files are internal to CMake and you should
|
||||
# not call configure_file() on them yourself, but they can be used as starting
|
||||
# point to create more sophisticted custom ConfigVersion.cmake files.
|
||||
#
|
||||
#
|
||||
# Example using both configure_package_config_file() and write_basic_package_version_file():
|
||||
# CMakeLists.txt:
|
||||
# set(INCLUDE_INSTALL_DIR include/ ... CACHE )
|
||||
# set(LIB_INSTALL_DIR lib/ ... CACHE )
|
||||
# set(SYSCONFIG_INSTALL_DIR etc/foo/ ... CACHE )
|
||||
# ...
|
||||
# include(CMakePackageConfigHelpers)
|
||||
# configure_package_config_file(FooConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
|
||||
# INSTALL_DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake
|
||||
# PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR)
|
||||
# write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
|
||||
# VERSION 1.2.3
|
||||
# COMPATIBILITY SameMajorVersion )
|
||||
# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
|
||||
# DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake )
|
||||
#
|
||||
# With a FooConfig.cmake.in:
|
||||
# set(FOO_VERSION x.y.z)
|
||||
# ...
|
||||
# @PACKAGE_INIT@
|
||||
# ...
|
||||
# set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
|
||||
# set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")
|
||||
#
|
||||
# check_required_components(Foo)
|
||||
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2012 Alexander Neundorf <neundorf@kde.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
include(WriteBasicConfigVersionFile)
|
||||
|
||||
macro(WRITE_BASIC_PACKAGE_VERSION_FILE)
|
||||
write_basic_config_version_file(${ARGN})
|
||||
endmacro()
|
||||
|
||||
|
||||
function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
|
||||
set(options NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO)
|
||||
set(oneValueArgs INSTALL_DESTINATION )
|
||||
set(multiValueArgs PATH_VARS )
|
||||
|
||||
cmake_parse_arguments(CCF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(CCF_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "Unknown keywords given to CONFIGURE_PACKAGE_CONFIG_FILE(): \"${CCF_UNPARSED_ARGUMENTS}\"")
|
||||
endif()
|
||||
|
||||
if(NOT CCF_INSTALL_DESTINATION)
|
||||
message(FATAL_ERROR "No INSTALL_DESTINATION given to CONFIGURE_PACKAGE_CONFIG_FILE()")
|
||||
endif()
|
||||
|
||||
if(IS_ABSOLUTE "${CCF_INSTALL_DESTINATION}")
|
||||
set(absInstallDir "${CCF_INSTALL_DESTINATION}")
|
||||
else()
|
||||
set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}")
|
||||
endif()
|
||||
|
||||
file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" )
|
||||
|
||||
foreach(var ${CCF_PATH_VARS})
|
||||
if(NOT DEFINED ${var})
|
||||
message(FATAL_ERROR "Variable ${var} does not exist")
|
||||
else()
|
||||
if(IS_ABSOLUTE "${${var}}")
|
||||
string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
|
||||
PACKAGE_${var} "${${var}}")
|
||||
else()
|
||||
set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
get_filename_component(inputFileName "${_inputFile}" NAME)
|
||||
|
||||
set(PACKAGE_INIT "
|
||||
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
|
||||
####### Any changes to this file will be overwritten by the next CMake run ####
|
||||
####### The input file was ${inputFileName} ########
|
||||
|
||||
get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE)
|
||||
")
|
||||
|
||||
if("${absInstallDir}" MATCHES "^(/usr)?/lib(64)?/.+")
|
||||
# Handle "/usr move" symlinks created by some Linux distros.
|
||||
set(PACKAGE_INIT "${PACKAGE_INIT}
|
||||
# Use original install prefix when loaded through a \"/usr move\"
|
||||
# cross-prefix symbolic link such as /lib -> /usr/lib.
|
||||
get_filename_component(_realCurr \"\${CMAKE_CURRENT_LIST_DIR}\" REALPATH)
|
||||
get_filename_component(_realOrig \"${absInstallDir}\" REALPATH)
|
||||
if(_realCurr STREQUAL _realOrig)
|
||||
set(PACKAGE_PREFIX_DIR \"${CMAKE_INSTALL_PREFIX}\")
|
||||
endif()
|
||||
unset(_realOrig)
|
||||
unset(_realCurr)
|
||||
")
|
||||
endif()
|
||||
|
||||
if(NOT CCF_NO_SET_AND_CHECK_MACRO)
|
||||
set(PACKAGE_INIT "${PACKAGE_INIT}
|
||||
macro(set_and_check _var _file)
|
||||
set(\${_var} \"\${_file}\")
|
||||
if(NOT EXISTS \"\${_file}\")
|
||||
message(FATAL_ERROR \"File or directory \${_file} referenced by variable \${_var} does not exist !\")
|
||||
endif()
|
||||
endmacro()
|
||||
")
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT CCF_NO_CHECK_REQUIRED_COMPONENTS_MACRO)
|
||||
set(PACKAGE_INIT "${PACKAGE_INIT}
|
||||
macro(check_required_components _NAME)
|
||||
foreach(comp \${\${_NAME}_FIND_COMPONENTS})
|
||||
if(NOT \${_NAME}_\${comp}_FOUND)
|
||||
if(\${_NAME}_FIND_REQUIRED_\${comp})
|
||||
set(\${_NAME}_FOUND FALSE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
")
|
||||
endif()
|
||||
|
||||
set(PACKAGE_INIT "${PACKAGE_INIT}
|
||||
####################################################################################")
|
||||
|
||||
configure_file("${_inputFile}" "${_outputFile}" @ONLY)
|
||||
|
||||
endfunction()
|
50
cmake/compat_2.8.11/WriteBasicConfigVersionFile.cmake
Normal file
50
cmake/compat_2.8.11/WriteBasicConfigVersionFile.cmake
Normal file
@ -0,0 +1,50 @@
|
||||
# WRITE_BASIC_CONFIG_VERSION_FILE( filename VERSION major.minor.patch COMPATIBILITY (AnyNewerVersion|SameMajorVersion) )
|
||||
#
|
||||
# Deprecated, see WRITE_BASIC_PACKAGE_VERSION_FILE(), it is identical.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2008-2011 Alexander Neundorf, <neundorf@kde.org>
|
||||
# Copyright 2004-2009 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
function(WRITE_BASIC_CONFIG_VERSION_FILE _filename)
|
||||
|
||||
set(options )
|
||||
set(oneValueArgs VERSION COMPATIBILITY )
|
||||
set(multiValueArgs )
|
||||
|
||||
cmake_parse_arguments(CVF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(CVF_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "Unknown keywords given to WRITE_BASIC_CONFIG_VERSION_FILE(): \"${CVF_UNPARSED_ARGUMENTS}\"")
|
||||
endif()
|
||||
|
||||
foreach(MODULE_PATH ${CMAKE_MODULE_PATH})
|
||||
if (${MODULE_PATH} MATCHES "compat_2.8.11")
|
||||
set(CURRENT_MODULE_PATH ${MODULE_PATH})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(versionTemplateFile "${CURRENT_MODULE_PATH}/BasicConfigVersion-${CVF_COMPATIBILITY}.cmake.in")
|
||||
if(NOT EXISTS "${versionTemplateFile}")
|
||||
message(FATAL_ERROR "Bad COMPATIBILITY value used for WRITE_BASIC_CONFIG_VERSION_FILE(): \"${CVF_COMPATIBILITY}\"")
|
||||
endif()
|
||||
|
||||
if("${CVF_VERSION}" STREQUAL "")
|
||||
message(FATAL_ERROR "No VERSION specified for WRITE_BASIC_CONFIG_VERSION_FILE()")
|
||||
endif()
|
||||
|
||||
configure_file("${versionTemplateFile}" "${_filename}" @ONLY)
|
||||
|
||||
endfunction()
|
2
include/freerdp/cache/glyph.h
vendored
2
include/freerdp/cache/glyph.h
vendored
@ -24,6 +24,7 @@
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/update.h>
|
||||
|
||||
#include <winpr/wlog.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
typedef struct _GLYPH_CACHE GLYPH_CACHE;
|
||||
@ -56,6 +57,7 @@ struct rdp_glyph_cache
|
||||
FRAGMENT_CACHE fragCache;
|
||||
GLYPH_CACHE glyphCache[10];
|
||||
|
||||
wLog* log;
|
||||
rdpContext* context;
|
||||
rdpSettings* settings;
|
||||
};
|
||||
|
30
include/freerdp/channels/audin.h
Normal file
30
include/freerdp/channels/audin.h
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Audio Input Redirection Virtual Channel
|
||||
*
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
*
|
||||
* 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_AUDIN_H
|
||||
#define FREERDP_CHANNEL_AUDIN_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/dvc.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
|
||||
|
||||
#endif /* FREERDP_CHANNEL_AUDIN_H */
|
||||
|
29
include/freerdp/channels/rail.h
Normal file
29
include/freerdp/channels/rail.h
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Remote Applications Integrated Locally (RAIL)
|
||||
*
|
||||
* 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_RAIL_H
|
||||
#define FREERDP_CHANNEL_RAIL_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RAIL_H */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user