diff --git a/.gitignore b/.gitignore index 00fb8eddc..73c0bf88c 100644 --- a/.gitignore +++ b/.gitignore @@ -39,10 +39,12 @@ Debug *.dylib cunit/test_freerdp client/X11/xfreerdp +client/Mac/xcode client/test/freerdp-test client/DirectFB/dfreerdp server/test/tfreerdp-server server/X11/xfreerdp-server +xcode # Other *~ diff --git a/CMakeLists.txt b/CMakeLists.txt index f17caa2a8..f20ac88b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,9 @@ set(FREERDP_VERSION_MINOR "0") set(FREERDP_VERSION_REVISION "1") set(FREERDP_VERSION "${FREERDP_VERSION_MAJOR}.${FREERDP_VERSION_MINOR}") set(FREERDP_VERSION_FULL "${FREERDP_VERSION}.${FREERDP_VERSION_REVISION}") +include(GetGitRevisionDescription) +git_describe(GIT_REVISION --match "[0-9]*" --abbrev=4 --tags --always) +message(STATUS "Git Revision ${GIT_REVISION}") # Default to release build type if(NOT CMAKE_BUILD_TYPE) @@ -52,7 +55,7 @@ endif() # Default to build shared libs if(NOT DEFINED BUILD_SHARED_LIBS) - set(BUILD_SHARED_LIBS ON) + set(BUILD_SHARED_LIBS ON) endif() # Compiler-specific flags @@ -78,7 +81,11 @@ endif() if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd /MT") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2 /Ob2") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_AMD64_") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_") + endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_UNICODE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS") @@ -88,6 +95,29 @@ if(MSVC) SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}) endif() +# This forces the MSVC runtime to be statically linked + +if(MSVC) + foreach(flag_var CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELWITHDEBINFO) + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}") + endforeach(flag_var) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}" CACHE STRING "MSVC C Debug MT flags " FORCE) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "MSVC CXX Debug MT flags " FORCE) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "MSVC C Release MT flags " FORCE) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "MSVC CXX Release MT flags " FORCE) + set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}" CACHE STRING "MSVC C Debug MT flags " FORCE) + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}" CACHE STRING "MSVC C Release MT flags " FORCE) + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}" CACHE STRING "MSVC CXX Debug MT flags " FORCE) + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" CACHE STRING "MSVC CXX Release MT flags " FORCE) +endif() + +# config.h definition for installable headers +check_include_files(limits.h FREERDP_HAVE_LIMITS_H) +check_include_files(stdint.h FREERDP_HAVE_STDINT_H) +check_include_files(stdbool.h FREERDP_HAVE_STDBOOL_H) +check_include_files(inttypes.h FREERDP_HAVE_INTTYPES_H) + # Include files check_include_files(fcntl.h HAVE_FCNTL_H) check_include_files(unistd.h HAVE_UNISTD_H) @@ -95,6 +125,9 @@ check_include_files(limits.h HAVE_LIMITS_H) check_include_files(stdint.h HAVE_STDINT_H) check_include_files(stdbool.h HAVE_STDBOOL_H) check_include_files(inttypes.h HAVE_INTTYPES_H) +check_include_files(sys/modem.h HAVE_SYS_MODEM_H) +check_include_files(sys/filio.h HAVE_SYS_FILIO_H) +check_include_files(sys/strtio.h HAVE_SYS_STRTIO_H) check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF) @@ -105,14 +138,23 @@ endif() # Mac OS X if(APPLE) - include_directories(/opt/local/include) - link_directories(/opt/local/lib) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.4") + if(IS_DIRECTORY /opt/local/include) + include_directories(/opt/local/include) + link_directories(/opt/local/lib) + endif() + + if(WITH_CLANG) + set(CMAKE_C_COMPILER "clang") + endif() + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.4") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl-framework,CoreFoundation") endif() if(NOT WIN32) find_required_package(ZLIB) find_optional_package(PulseAudio) + find_optional_package(MacAudio) find_optional_package(PCSC) find_suggested_package(Cups) @@ -131,59 +173,64 @@ set(FREERDP_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/freerdp") set(FREERDP_KEYMAP_PATH "${FREERDP_DATA_PATH}/keymaps") # Path to put plugins -set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/freerdp") +set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp") # Path to put extensions -set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/freerdp/extensions") +set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp/extensions") # Include directories -include_directories(${CMAKE_CURRENT_BINARY_DIR}) -include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + +# WinPR +set(WINPR_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/winpr/include") +include_directories(${WINPR_INCLUDE_DIR}) # Configure files -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) +add_definitions("-DHAVE_CONFIG_H") +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/config.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/freerdp/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/freerdp/config.h) # Generate pkg-config -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/freerdp.pc.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc @ONLY) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +if(NOT MSVC) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/freerdp.pc.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +endif() # Build CUnit find_optional_package(CUnit) if(WITH_CUNIT) - enable_testing() - add_subdirectory(cunit) + enable_testing() + add_subdirectory(cunit) endif() # Sub-directories + add_subdirectory(include) -add_subdirectory(libfreerdp-utils) add_subdirectory(winpr) -add_subdirectory(libfreerdp-gdi) -add_subdirectory(libfreerdp-rail) -add_subdirectory(libfreerdp-cache) -add_subdirectory(libfreerdp-codec) -add_subdirectory(libfreerdp-crypto) -add_subdirectory(libfreerdp-channels) -add_subdirectory(libfreerdp-locale) -add_subdirectory(libfreerdp-core) +add_subdirectory(libfreerdp) -if(NOT WIN32) +if(WITH_CHANNELS) add_subdirectory(channels) endif() -option(WITH_CLIENT "Build client binaries" ON) if(WITH_CLIENT) add_subdirectory(client) endif() -option(WITH_SERVER "Build server binaries" OFF) if(WITH_SERVER) add_subdirectory(server) endif() -add_subdirectory(keymaps) +if(WITH_THIRD_PARTY) + add_subdirectory(third-party) +endif() + +if(NOT MSVC) + add_subdirectory(keymaps) +endif() # Source package set(CPACK_SOURCE_IGNORE_FILES "/\\\\.git/;/\\\\.gitignore;/CMakeCache.txt") @@ -192,4 +239,3 @@ string(TOLOWER ${CMAKE_PROJECT_NAME} CMAKE_PROJECT_NAME_lower) set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME_lower}-${FREERDP_VERSION_FULL}") include(CPack) - diff --git a/channels/CMakeLists.txt b/channels/CMakeLists.txt index efb877c08..1951fd8f1 100644 --- a/channels/CMakeLists.txt +++ b/channels/CMakeLists.txt @@ -19,9 +19,11 @@ add_subdirectory(cliprdr) add_subdirectory(drdynvc) -add_subdirectory(rdpdbg) -add_subdirectory(rdpdr) add_subdirectory(rail) -add_subdirectory(rdpsnd) +add_subdirectory(rdpdbg) add_subdirectory(skel) +if(NOT WIN32) + add_subdirectory(rdpdr) + add_subdirectory(rdpsnd) +endif() diff --git a/channels/cliprdr/CMakeLists.txt b/channels/cliprdr/CMakeLists.txt index 03fb0ba20..5c30a67ef 100644 --- a/channels/cliprdr/CMakeLists.txt +++ b/channels/cliprdr/CMakeLists.txt @@ -22,12 +22,15 @@ set(CLIPRDR_SRCS cliprdr_format.c cliprdr_format.h cliprdr_main.c - cliprdr_main.h -) + cliprdr_main.h) add_library(cliprdr ${CLIPRDR_SRCS}) set_target_properties(cliprdr PROPERTIES PREFIX "") -target_link_libraries(cliprdr freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(cliprdr freerdp) +else() + target_link_libraries(cliprdr freerdp-utils) +endif() install(TARGETS cliprdr DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/cliprdr/cliprdr_format.c b/channels/cliprdr/cliprdr_format.c index 19099b080..4f603dbf3 100644 --- a/channels/cliprdr/cliprdr_format.c +++ b/channels/cliprdr/cliprdr_format.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/channels/cliprdr/cliprdr_main.c b/channels/cliprdr/cliprdr_main.c index 075330354..b7f4e136d 100644 --- a/channels/cliprdr/cliprdr_main.c +++ b/channels/cliprdr/cliprdr_main.c @@ -18,7 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include diff --git a/channels/drdynvc/CMakeLists.txt b/channels/drdynvc/CMakeLists.txt index 1e3cc13f3..b1deab049 100644 --- a/channels/drdynvc/CMakeLists.txt +++ b/channels/drdynvc/CMakeLists.txt @@ -28,10 +28,16 @@ set(DRDYNVC_SRCS add_library(drdynvc ${DRDYNVC_SRCS}) set_target_properties(drdynvc PROPERTIES PREFIX "") -target_link_libraries(drdynvc freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(drdynvc freerdp) +else() + target_link_libraries(drdynvc freerdp-utils) +endif() install(TARGETS drdynvc DESTINATION ${FREERDP_PLUGIN_PATH}) -add_subdirectory(tsmf) -add_subdirectory(audin) +if(NOT WIN32) + add_subdirectory(tsmf) +endif() +add_subdirectory(audin) diff --git a/channels/drdynvc/audin/CMakeLists.txt b/channels/drdynvc/audin/CMakeLists.txt index 37fe00462..65534eb87 100644 --- a/channels/drdynvc/audin/CMakeLists.txt +++ b/channels/drdynvc/audin/CMakeLists.txt @@ -19,15 +19,18 @@ set(AUDIN_SRCS audin_main.c - audin_main.h -) + audin_main.h) include_directories(..) add_library(audin ${AUDIN_SRCS}) set_target_properties(audin PROPERTIES PREFIX "") -target_link_libraries(audin freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(audin freerdp) +else() + target_link_libraries(audin freerdp-utils) +endif() install(TARGETS audin DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/drdynvc/audin/alsa/CMakeLists.txt b/channels/drdynvc/audin/alsa/CMakeLists.txt index 786f9ce2c..e7a0df6a2 100644 --- a/channels/drdynvc/audin/alsa/CMakeLists.txt +++ b/channels/drdynvc/audin/alsa/CMakeLists.txt @@ -18,8 +18,7 @@ # limitations under the License. set(AUDIN_ALSA_SRCS - audin_alsa.c -) + audin_alsa.c) include_directories(..) include_directories(${ALSA_INCLUDE_DIRS}) @@ -27,7 +26,12 @@ include_directories(${ALSA_INCLUDE_DIRS}) add_library(audin_alsa ${AUDIN_ALSA_SRCS}) set_target_properties(audin_alsa PROPERTIES PREFIX "") -target_link_libraries(audin_alsa freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(audin_alsa freerdp) +else() + target_link_libraries(audin_alsa freerdp-utils) +endif() + target_link_libraries(audin_alsa ${ALSA_LIBRARIES}) install(TARGETS audin_alsa DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/drdynvc/audin/alsa/audin_alsa.c b/channels/drdynvc/audin/alsa/audin_alsa.c index e6cf74950..cfada9a9f 100644 --- a/channels/drdynvc/audin/alsa/audin_alsa.c +++ b/channels/drdynvc/audin/alsa/audin_alsa.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/channels/drdynvc/audin/audin_main.c b/channels/drdynvc/audin/audin_main.c index 095c53967..71395d421 100644 --- a/channels/drdynvc/audin/audin_main.c +++ b/channels/drdynvc/audin/audin_main.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include @@ -248,7 +253,7 @@ static int audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, STRE DEBUG_DVC("FramesPerPacket=%d initialFormat=%d", FramesPerPacket, initialFormat); - if (initialFormat >= callback->formats_count) + if (initialFormat >= (uint32) callback->formats_count) { DEBUG_WARN("invalid format index %d (total %d)", initialFormat, callback->formats_count); @@ -279,7 +284,7 @@ static int audin_process_format_change(IWTSVirtualChannelCallback* pChannelCallb DEBUG_DVC("NewFormat=%d", NewFormat); - if (NewFormat >= callback->formats_count) + if (NewFormat >= (uint32) callback->formats_count) { DEBUG_WARN("invalid format index %d (total %d)", NewFormat, callback->formats_count); diff --git a/channels/drdynvc/audin/pulse/CMakeLists.txt b/channels/drdynvc/audin/pulse/CMakeLists.txt index c27f87068..bb81b0b99 100644 --- a/channels/drdynvc/audin/pulse/CMakeLists.txt +++ b/channels/drdynvc/audin/pulse/CMakeLists.txt @@ -27,7 +27,12 @@ include_directories(${PULSEAUDIO_INCLUDE_DIR}) add_library(audin_pulse ${AUDIN_PULSE_SRCS}) set_target_properties(audin_pulse PROPERTIES PREFIX "") -target_link_libraries(audin_pulse freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(audin_pulse freerdp) +else() + target_link_libraries(audin_pulse freerdp-utils) +endif() + target_link_libraries(audin_pulse ${PULSEAUDIO_LIBRARY}) install(TARGETS audin_pulse DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/drdynvc/audin/pulse/audin_pulse.c b/channels/drdynvc/audin/pulse/audin_pulse.c index e7af29009..1ad2cc285 100644 --- a/channels/drdynvc/audin/pulse/audin_pulse.c +++ b/channels/drdynvc/audin/pulse/audin_pulse.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/channels/drdynvc/drdynvc_main.c b/channels/drdynvc/drdynvc_main.c index 27ad531b7..1807df11f 100644 --- a/channels/drdynvc/drdynvc_main.c +++ b/channels/drdynvc/drdynvc_main.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/channels/drdynvc/drdynvc_types.h b/channels/drdynvc/drdynvc_types.h index a08a60523..5c9ce5947 100644 --- a/channels/drdynvc/drdynvc_types.h +++ b/channels/drdynvc/drdynvc_types.h @@ -20,7 +20,10 @@ #ifndef __DRDYNVC_TYPES_H #define __DRDYNVC_TYPES_H +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include diff --git a/channels/drdynvc/dvcman.c b/channels/drdynvc/dvcman.c index d24b11489..a8aed81a9 100644 --- a/channels/drdynvc/dvcman.c +++ b/channels/drdynvc/dvcman.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include @@ -194,7 +199,7 @@ int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* while (data && data->size > 0) { - pDVCPluginEntry = freerdp_load_plugin((char*) data->data[0], "DVCPluginEntry"); + pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_plugin((char*) data->data[0], "DVCPluginEntry"); if (pDVCPluginEntry != NULL) { @@ -206,7 +211,7 @@ int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints); } - data = (RDP_PLUGIN_DATA*)(((void*) data) + data->size); + data = (RDP_PLUGIN_DATA*)(((uint8*) data) + data->size); } return 0; @@ -414,7 +419,7 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, uint32 C if (channel->dvc_data) { /* Fragmented data */ - if (stream_get_length(channel->dvc_data) + data_size > stream_get_size(channel->dvc_data)) + if (stream_get_length(channel->dvc_data) + data_size > (uint32) stream_get_size(channel->dvc_data)) { DEBUG_WARN("data exceeding declared length!"); stream_free(channel->dvc_data); diff --git a/channels/drdynvc/tsmf/CMakeLists.txt b/channels/drdynvc/tsmf/CMakeLists.txt index c4e940730..baf97c55b 100644 --- a/channels/drdynvc/tsmf/CMakeLists.txt +++ b/channels/drdynvc/tsmf/CMakeLists.txt @@ -32,15 +32,18 @@ set(TSMF_SRCS tsmf_main.h tsmf_media.c tsmf_media.h - tsmf_types.h -) + tsmf_types.h) include_directories(..) add_library(tsmf ${TSMF_SRCS}) set_target_properties(tsmf PROPERTIES PREFIX "") -target_link_libraries(tsmf freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(tsmf freerdp) +else() + target_link_libraries(tsmf freerdp-utils) +endif() install(TARGETS tsmf DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/drdynvc/tsmf/alsa/CMakeLists.txt b/channels/drdynvc/tsmf/alsa/CMakeLists.txt index c769a1857..4b984e4bf 100644 --- a/channels/drdynvc/tsmf/alsa/CMakeLists.txt +++ b/channels/drdynvc/tsmf/alsa/CMakeLists.txt @@ -27,7 +27,12 @@ include_directories(${ALSA_INCLUDE_DIRS}) add_library(tsmf_alsa ${TSMF_ALSA_SRCS}) set_target_properties(tsmf_alsa PROPERTIES PREFIX "") -target_link_libraries(tsmf_alsa freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(tsmf_alsa freerdp) +else() + target_link_libraries(tsmf_alsa freerdp-utils) +endif() + target_link_libraries(tsmf_alsa ${ALSA_LIBRARIES}) install(TARGETS tsmf_alsa DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/drdynvc/tsmf/alsa/tsmf_alsa.c b/channels/drdynvc/tsmf/alsa/tsmf_alsa.c index d1e587f3e..a05ff09fa 100644 --- a/channels/drdynvc/tsmf/alsa/tsmf_alsa.c +++ b/channels/drdynvc/tsmf/alsa/tsmf_alsa.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/channels/drdynvc/tsmf/ffmpeg/CMakeLists.txt b/channels/drdynvc/tsmf/ffmpeg/CMakeLists.txt index 22e208e5f..290237b5c 100644 --- a/channels/drdynvc/tsmf/ffmpeg/CMakeLists.txt +++ b/channels/drdynvc/tsmf/ffmpeg/CMakeLists.txt @@ -34,7 +34,12 @@ if(CMAKE_COMPILER_IS_GNUCC) endif() endif() -target_link_libraries(tsmf_ffmpeg freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(tsmf_ffmpeg freerdp) +else() + target_link_libraries(tsmf_ffmpeg freerdp-utils) +endif() + target_link_libraries(tsmf_ffmpeg ${FFMPEG_LIBRARIES}) install(TARGETS tsmf_ffmpeg DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/drdynvc/tsmf/ffmpeg/tsmf_ffmpeg.c b/channels/drdynvc/tsmf/ffmpeg/tsmf_ffmpeg.c index 903f64320..f823b7693 100644 --- a/channels/drdynvc/tsmf/ffmpeg/tsmf_ffmpeg.c +++ b/channels/drdynvc/tsmf/ffmpeg/tsmf_ffmpeg.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/channels/drdynvc/tsmf/gstreamer/CMakeLists.txt b/channels/drdynvc/tsmf/gstreamer/CMakeLists.txt index a957667f5..f1a72abbf 100644 --- a/channels/drdynvc/tsmf/gstreamer/CMakeLists.txt +++ b/channels/drdynvc/tsmf/gstreamer/CMakeLists.txt @@ -27,7 +27,12 @@ include_directories(${GSTREAMER_INCLUDE_DIRS}) add_library(tsmf_gstreamer ${TSMF_GSTREAMER_SRCS}) set_target_properties(tsmf_gstreamer PROPERTIES PREFIX "") -target_link_libraries(tsmf_gstreamer freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(tsmf_gstreamer freerdp) +else() + target_link_libraries(tsmf_gstreamer freerdp-utils) +endif() + target_link_libraries(tsmf_gstreamer ${GSTREAMER_LIBRARIES} gstapp-0.10 gstinterfaces-0.10 Xrandr X11 Xext) install(TARGETS tsmf_gstreamer DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/drdynvc/tsmf/gstreamer/tsmf_gstreamer.c b/channels/drdynvc/tsmf/gstreamer/tsmf_gstreamer.c index 7243dcd33..0a5c8580c 100644 --- a/channels/drdynvc/tsmf/gstreamer/tsmf_gstreamer.c +++ b/channels/drdynvc/tsmf/gstreamer/tsmf_gstreamer.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/channels/drdynvc/tsmf/pulse/CMakeLists.txt b/channels/drdynvc/tsmf/pulse/CMakeLists.txt index ae137a555..ef488cd13 100644 --- a/channels/drdynvc/tsmf/pulse/CMakeLists.txt +++ b/channels/drdynvc/tsmf/pulse/CMakeLists.txt @@ -18,8 +18,7 @@ # limitations under the License. set(TSMF_PULSE_SRCS - tsmf_pulse.c -) + tsmf_pulse.c) include_directories(..) include_directories(${PULSEAUDIO_INCLUDE_DIR}) @@ -27,8 +26,11 @@ include_directories(${PULSEAUDIO_INCLUDE_DIR}) add_library(tsmf_pulse ${TSMF_PULSE_SRCS}) set_target_properties(tsmf_pulse PROPERTIES PREFIX "") -target_link_libraries(tsmf_pulse freerdp-utils) -target_link_libraries(tsmf_pulse ${PULSEAUDIO_LIBRARY}) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(tsmf_pulse ${PULSEAUDIO_LIBRARY} freerdp) +else() + target_link_libraries(tsmf_pulse ${PULSEAUDIO_LIBRARY} freerdp-utils) +endif() install(TARGETS tsmf_pulse DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/drdynvc/tsmf/pulse/tsmf_pulse.c b/channels/drdynvc/tsmf/pulse/tsmf_pulse.c index de3c9018c..ca162ae72 100644 --- a/channels/drdynvc/tsmf/pulse/tsmf_pulse.c +++ b/channels/drdynvc/tsmf/pulse/tsmf_pulse.c @@ -17,10 +17,15 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include + #include #include diff --git a/channels/drdynvc/tsmf/tsmf_audio.c b/channels/drdynvc/tsmf/tsmf_audio.c index 5a1a14512..e9f37ce92 100644 --- a/channels/drdynvc/tsmf/tsmf_audio.c +++ b/channels/drdynvc/tsmf/tsmf_audio.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include diff --git a/channels/drdynvc/tsmf/tsmf_audio.h b/channels/drdynvc/tsmf/tsmf_audio.h index af0075927..5492cb88a 100644 --- a/channels/drdynvc/tsmf/tsmf_audio.h +++ b/channels/drdynvc/tsmf/tsmf_audio.h @@ -34,6 +34,8 @@ struct _ITSMFAudioDevice boolean (*Play) (ITSMFAudioDevice* audio, uint8* data, uint32 data_size); /* Get the latency of the last written sample, in 100ns */ uint64 (*GetLatency) (ITSMFAudioDevice* audio); + /* Change the playback volume level */ + void (*ChangeVolume) (ITSMFAudioDevice* audio, uint32 newVolume, uint32 muted); /* Flush queued audio data */ void (*Flush) (ITSMFAudioDevice* audio); /* Free the audio device */ diff --git a/channels/drdynvc/tsmf/tsmf_codec.c b/channels/drdynvc/tsmf/tsmf_codec.c index 7bc61c38e..64296b1c3 100644 --- a/channels/drdynvc/tsmf/tsmf_codec.c +++ b/channels/drdynvc/tsmf/tsmf_codec.c @@ -18,9 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include diff --git a/channels/drdynvc/tsmf/tsmf_decoder.c b/channels/drdynvc/tsmf/tsmf_decoder.c index db31c027b..5a604eb30 100644 --- a/channels/drdynvc/tsmf/tsmf_decoder.c +++ b/channels/drdynvc/tsmf/tsmf_decoder.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include diff --git a/channels/drdynvc/tsmf/tsmf_ifman.c b/channels/drdynvc/tsmf/tsmf_ifman.c index 1881d15d5..71a6d9bef 100644 --- a/channels/drdynvc/tsmf/tsmf_ifman.c +++ b/channels/drdynvc/tsmf/tsmf_ifman.c @@ -18,9 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include @@ -228,14 +233,18 @@ int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman) int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman) { - DEBUG_DVC("on stream volume"); TSMF_PRESENTATION* presentation; + + DEBUG_DVC("on stream volume"); + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + if (presentation) { - stream_seek(ifman->input, 16); uint32 newVolume; uint32 muted; + + stream_seek(ifman->input, 16); stream_read_uint32(ifman->input, newVolume); DEBUG_DVC("on stream volume: new volume=[%d]", newVolume); stream_read_uint32(ifman->input, muted); @@ -243,28 +252,37 @@ int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman) tsmf_presentation_volume_changed(presentation, newVolume, muted); } else + { DEBUG_WARN("unknown presentation id"); + } ifman->output_pending = true; + return 0; } int tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman) { - DEBUG_DVC("on channel volume"); TSMF_PRESENTATION* presentation; + + DEBUG_DVC("on channel volume"); + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + if (presentation) { - stream_seek(ifman->input, 16); uint32 channelVolume; uint32 changedChannel; + + stream_seek(ifman->input, 16); stream_read_uint32(ifman->input, channelVolume); DEBUG_DVC("on channel volume: channel volume=[%d]", channelVolume); stream_read_uint32(ifman->input, changedChannel); DEBUG_DVC("on stream volume: changed channel=[%d]", changedChannel); } + ifman->output_pending = true; + return 0; } @@ -310,7 +328,9 @@ int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman) numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects); if (presentation == NULL) + { error = 1; + } else { if (num_rects > 0) @@ -335,7 +355,9 @@ int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman) } tsmf_presentation_set_geometry_info(presentation, Left, Top, Width, Height, num_rects, rects); } + ifman->output_pending = true; + return error; } @@ -472,11 +494,13 @@ int tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman) int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman) { + TSMF_PRESENTATION* presentation; + DEBUG_DVC(""); ifman->output_pending = true; /* Added pause control so gstreamer pipeline can be paused accordingly */ - TSMF_PRESENTATION* presentation; + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); if (presentation) tsmf_presentation_paused(presentation); @@ -487,16 +511,20 @@ int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman) int tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman) { + TSMF_PRESENTATION* presentation; + DEBUG_DVC(""); ifman->output_pending = true; /* Added restart control so gstreamer pipeline can be resumed accordingly */ - TSMF_PRESENTATION* presentation; + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + if (presentation) tsmf_presentation_restarted(presentation); else DEBUG_WARN("unknown presentation id"); + return 0; } @@ -507,6 +535,7 @@ int tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman) DEBUG_DVC(""); presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + if (presentation) tsmf_presentation_stop(presentation); else diff --git a/channels/drdynvc/tsmf/tsmf_main.c b/channels/drdynvc/tsmf/tsmf_main.c index e0c944d3a..d76961c4e 100644 --- a/channels/drdynvc/tsmf/tsmf_main.c +++ b/channels/drdynvc/tsmf/tsmf_main.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include @@ -416,7 +421,7 @@ static void tsmf_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data) } } - data = (RDP_PLUGIN_DATA*)(((void*)data) + data->size); + data = (RDP_PLUGIN_DATA*)(((uint8*)data) + data->size); } } diff --git a/channels/drdynvc/tsmf/tsmf_media.c b/channels/drdynvc/tsmf/tsmf_media.c index fb34c9409..60a04e786 100644 --- a/channels/drdynvc/tsmf/tsmf_media.c +++ b/channels/drdynvc/tsmf/tsmf_media.c @@ -18,12 +18,23 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include + +#ifdef HAVE_UNISTD_H #include +#endif + +#ifndef _WIN32 #include +#endif + #include #include #include @@ -238,18 +249,19 @@ static void tsmf_stream_process_ack(TSMF_STREAM* stream) TSMF_PRESENTATION* tsmf_presentation_new(const uint8* guid, IWTSVirtualChannelCallback* pChannelCallback) { + TSMF_PRESENTATION* presentation; pthread_t thid = pthread_self(); FILE* fout = NULL; fout = fopen("/tmp/tsmf.tid", "wt"); + if (fout) { fprintf(fout, "%d\n", (int) thid); fclose(fout); } - TSMF_PRESENTATION* presentation; - presentation = tsmf_presentation_find_by_id(guid); + if (presentation) { DEBUG_WARN("duplicated presentation id!"); @@ -319,6 +331,7 @@ static void tsmf_sample_playback_video(TSMF_SAMPLE* sample) if (sample->data) { t = get_current_time(); + if (stream->next_start_time > t && (sample->end_time >= presentation->audio_start_time || sample->end_time < stream->last_end_time)) @@ -726,14 +739,15 @@ static void tsmf_stream_change_volume(TSMF_STREAM* stream, uint32 newVolume, uin { if (!stream) return; - - if (!stream->decoder) - return; - - if (stream->decoder->ChangeVolume) + + if (stream->decoder != NULL && stream->decoder->ChangeVolume) { stream->decoder->ChangeVolume(stream->decoder, newVolume, muted); } + else if (stream->audio != NULL && stream->audio->ChangeVolume) + { + stream->audio->ChangeVolume(stream->audio, newVolume, muted); + } } void tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, uint32 newVolume, uint32 muted) @@ -1006,14 +1020,17 @@ void tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pC uint32 sample_id, uint64 start_time, uint64 end_time, uint64 duration, uint32 extensions, uint32 data_size, uint8* data) { + TSMF_SAMPLE* sample; + pthread_mutex_lock(&tsmf_mutex); + if (TERMINATING) { pthread_mutex_unlock(&tsmf_mutex); return; } + pthread_mutex_unlock(&tsmf_mutex); - TSMF_SAMPLE* sample; sample = xnew(TSMF_SAMPLE); @@ -1033,6 +1050,8 @@ void tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pC freerdp_thread_unlock(stream->thread); } +#ifndef _WIN32 + static void tsmf_signal_handler(int s) { pthread_mutex_lock(&tsmf_mutex); @@ -1069,14 +1088,18 @@ static void tsmf_signal_handler(int s) } } +#endif + void tsmf_media_init(void) { +#ifndef _WIN32 struct sigaction sigtrap; sigtrap.sa_handler = tsmf_signal_handler; sigemptyset(&sigtrap.sa_mask); sigtrap.sa_flags = 0; sigaction(SIGINT, &sigtrap, 0); sigaction(SIGUSR1, &sigtrap, 0); +#endif if (presentation_list == NULL) presentation_list = list_new(); diff --git a/channels/rail/CMakeLists.txt b/channels/rail/CMakeLists.txt index 316411118..6e6a45441 100644 --- a/channels/rail/CMakeLists.txt +++ b/channels/rail/CMakeLists.txt @@ -26,7 +26,11 @@ set(RAIL_SRCS add_library(rail ${RAIL_SRCS}) set_target_properties(rail PROPERTIES PREFIX "") -target_link_libraries(rail freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(rail freerdp) +else() + target_link_libraries(rail freerdp-utils) +endif() install(TARGETS rail DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rail/rail_main.c b/channels/rail/rail_main.c index 58d1de40e..06c3b5bf0 100644 --- a/channels/rail/rail_main.c +++ b/channels/rail/rail_main.c @@ -19,9 +19,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include @@ -128,7 +133,7 @@ static void rail_recv_set_sysparams_event(rdpRailOrder* rail_order, RDP_EVENT* e while (data && data->size > 0) { rail_process_plugin_data(rail_order, data); - data = (RDP_PLUGIN_DATA*)(((void*) data) + data->size); + data = (RDP_PLUGIN_DATA*)((char *)(data) + data->size); } } diff --git a/channels/rail/rail_orders.c b/channels/rail/rail_orders.c index a5a641678..09826f149 100644 --- a/channels/rail/rail_orders.c +++ b/channels/rail/rail_orders.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/channels/rdpdbg/CMakeLists.txt b/channels/rdpdbg/CMakeLists.txt index db562a047..7387269da 100644 --- a/channels/rdpdbg/CMakeLists.txt +++ b/channels/rdpdbg/CMakeLists.txt @@ -24,6 +24,10 @@ set(RDPDBG_SRCS add_library(rdpdbg ${RDPDBG_SRCS}) set_target_properties(rdpdbg PROPERTIES PREFIX "") -target_link_libraries(rdpdbg freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(rdpdbg freerdp) +else() + target_link_libraries(rdpdbg freerdp-utils) +endif() install(TARGETS rdpdbg DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdbg/rdpdbg_main.c b/channels/rdpdbg/rdpdbg_main.c index c4d821736..a1cdc212c 100644 --- a/channels/rdpdbg/rdpdbg_main.c +++ b/channels/rdpdbg/rdpdbg_main.c @@ -18,9 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/channels/rdpdr/CMakeLists.txt b/channels/rdpdr/CMakeLists.txt index e43aeff7b..55b0e09ba 100644 --- a/channels/rdpdr/CMakeLists.txt +++ b/channels/rdpdr/CMakeLists.txt @@ -27,20 +27,25 @@ set(RDPDR_SRCS irp.c irp.h rdpdr_main.c - rdpdr_main.h -) + rdpdr_main.h) add_library(rdpdr ${RDPDR_SRCS}) set_target_properties(rdpdr PROPERTIES PREFIX "") -target_link_libraries(rdpdr freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(rdpdr freerdp) +else() + target_link_libraries(rdpdr freerdp-utils) +endif() install(TARGETS rdpdr DESTINATION ${FREERDP_PLUGIN_PATH}) -add_subdirectory(disk) -add_subdirectory(printer) -add_subdirectory(parallel) -add_subdirectory(serial) +if(NOT WIN32) + add_subdirectory(disk) + add_subdirectory(printer) + add_subdirectory(parallel) + add_subdirectory(serial) +endif() if(WITH_PCSC) add_subdirectory(smartcard) diff --git a/channels/rdpdr/devman.c b/channels/rdpdr/devman.c index 5c15b1f22..d1b5ef02b 100644 --- a/channels/rdpdr/devman.c +++ b/channels/rdpdr/devman.c @@ -18,10 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/channels/rdpdr/disk/CMakeLists.txt b/channels/rdpdr/disk/CMakeLists.txt index c1acd8058..aaac503a0 100644 --- a/channels/rdpdr/disk/CMakeLists.txt +++ b/channels/rdpdr/disk/CMakeLists.txt @@ -20,14 +20,17 @@ set(DISK_SRCS disk_file.c disk_file.h - disk_main.c -) + disk_main.c) include_directories(..) add_library(disk ${DISK_SRCS}) set_target_properties(disk PROPERTIES PREFIX "") -target_link_libraries(disk freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(disk freerdp) +else() + target_link_libraries(disk freerdp-utils) +endif() install(TARGETS disk DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdr/disk/disk_file.c b/channels/rdpdr/disk/disk_file.c index cdc1fe909..44745fb11 100644 --- a/channels/rdpdr/disk/disk_file.c +++ b/channels/rdpdr/disk/disk_file.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef _WIN32 #define __USE_LARGEFILE64 #define _LARGEFILE_SOURCE @@ -26,7 +30,6 @@ #include #endif -#include "config.h" #include #include #include @@ -199,10 +202,14 @@ static boolean disk_file_init(DISK_FILE* file, uint32 DesiredAccess, uint32 Crea file->is_dir = ((CreateOptions & FILE_DIRECTORY_FILE) ? true : false); if (file->is_dir) { - if (mkdir(file->fullpath, mode) != 0) + //Should only create the directory if the disposition allows for it + if ((CreateDisposition == FILE_OPEN_IF) || (CreateDisposition == FILE_CREATE)) { + if (mkdir(file->fullpath, mode) != 0) + { file->err = errno; return true; + } } } exists = false; diff --git a/channels/rdpdr/disk/disk_file.h b/channels/rdpdr/disk/disk_file.h index 68252dfd9..2d85bf80e 100644 --- a/channels/rdpdr/disk/disk_file.h +++ b/channels/rdpdr/disk/disk_file.h @@ -22,11 +22,14 @@ #define __DISK_FILE_H #include -#include #include -#include -#if defined WIN32 +#ifndef _WIN32 +#include +#include +#endif + +#ifdef _WIN32 #define STAT stat #define OPEN open #define LSEEK lseek @@ -60,10 +63,6 @@ (_f->delete_pending ? FILE_ATTRIBUTE_TEMPORARY : 0) | \ (st.st_mode & S_IWUSR ? 0 : FILE_ATTRIBUTE_READONLY)) - - - - typedef struct _DISK_FILE DISK_FILE; struct _DISK_FILE { diff --git a/channels/rdpdr/disk/disk_main.c b/channels/rdpdr/disk/disk_main.c index ad0b5a218..44126dd93 100644 --- a/channels/rdpdr/disk/disk_main.c +++ b/channels/rdpdr/disk/disk_main.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef _WIN32 #define __USE_LARGEFILE64 #define _LARGEFILE_SOURCE @@ -26,12 +30,11 @@ #include #endif - -#include "config.h" #include #include #include #include + #include #include #include diff --git a/channels/rdpdr/irp.c b/channels/rdpdr/irp.c index 3668b1cc4..859e20793 100644 --- a/channels/rdpdr/irp.c +++ b/channels/rdpdr/irp.c @@ -18,7 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include diff --git a/channels/rdpdr/parallel/CMakeLists.txt b/channels/rdpdr/parallel/CMakeLists.txt index 44387f57b..024f12995 100644 --- a/channels/rdpdr/parallel/CMakeLists.txt +++ b/channels/rdpdr/parallel/CMakeLists.txt @@ -26,6 +26,10 @@ include_directories(..) add_library(parallel ${PARALLEL_SRCS}) set_target_properties(parallel PROPERTIES PREFIX "") -target_link_libraries(parallel freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(parallel freerdp) +else() + target_link_libraries(parallel freerdp-utils) +endif() install(TARGETS parallel DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdr/parallel/parallel_main.c b/channels/rdpdr/parallel/parallel_main.c index 934def095..91f2b258d 100644 --- a/channels/rdpdr/parallel/parallel_main.c +++ b/channels/rdpdr/parallel/parallel_main.c @@ -18,16 +18,27 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include +#ifdef HAVE_UNISTD_H #include +#endif + #include -#include #include + +#ifndef _WIN32 +#include #include #include +#endif + #ifdef __LINUX__ #include #include @@ -74,6 +85,7 @@ static void parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp) parallel->id = irp->devman->id_sequence++; parallel->file = open(parallel->path, O_RDWR); + if (parallel->file < 0) { irp->IoStatus = STATUS_ACCESS_DENIED; @@ -163,6 +175,7 @@ static void parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp) DEBUG_SVC("Length %u Offset %llu", Length, Offset); len = Length; + while (len > 0) { status = write(parallel->file, stream_get_tail(irp->input), len); diff --git a/channels/rdpdr/printer/CMakeLists.txt b/channels/rdpdr/printer/CMakeLists.txt index d0f184cf7..ea4e19fa4 100644 --- a/channels/rdpdr/printer/CMakeLists.txt +++ b/channels/rdpdr/printer/CMakeLists.txt @@ -19,15 +19,14 @@ set(PRINTER_SRCS printer_main.c - printer_main.h -) + printer_main.h) if(WITH_CUPS) set(PRINTER_SRCS ${PRINTER_SRCS} printer_cups.c - printer_cups.h - ) + printer_cups.h) + include_directories(${CUPS_INCLUDE_DIR}) add_definitions(-DWITH_CUPS) endif() @@ -37,7 +36,11 @@ include_directories(..) add_library(printer ${PRINTER_SRCS}) set_target_properties(printer PROPERTIES PREFIX "") -target_link_libraries(printer freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(printer freerdp) +else() + target_link_libraries(printer freerdp-utils) +endif() if(WITH_CUPS) target_link_libraries(printer ${CUPS_LIBRARIES}) diff --git a/channels/rdpdr/printer/printer_cups.c b/channels/rdpdr/printer/printer_cups.c index 1f0c58cc1..84d0a2ce8 100644 --- a/channels/rdpdr/printer/printer_cups.c +++ b/channels/rdpdr/printer/printer_cups.c @@ -17,12 +17,18 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include + #include #include + #include #include diff --git a/channels/rdpdr/printer/printer_main.c b/channels/rdpdr/printer/printer_main.c index d379102aa..fdedd193a 100644 --- a/channels/rdpdr/printer/printer_main.c +++ b/channels/rdpdr/printer/printer_main.c @@ -17,10 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/channels/rdpdr/rdpdr_capabilities.c b/channels/rdpdr/rdpdr_capabilities.c index c31dbeadf..0b1b81e51 100644 --- a/channels/rdpdr/rdpdr_capabilities.c +++ b/channels/rdpdr/rdpdr_capabilities.c @@ -18,10 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include + #include #include diff --git a/channels/rdpdr/rdpdr_constants.h b/channels/rdpdr/rdpdr_constants.h index ce8b7f00b..ceb2f6cfe 100644 --- a/channels/rdpdr/rdpdr_constants.h +++ b/channels/rdpdr/rdpdr_constants.h @@ -124,6 +124,8 @@ enum FILE_CREATE_OPTION }; /* DR_CREATE_REQ.DesiredAccess [MS-SMB2] */ + +#ifndef _WIN32 enum FILE_ACCESS { FILE_READ_DATA = 0x00000001, @@ -146,6 +148,7 @@ enum FILE_ACCESS GENERIC_WRITE = 0x40000000, GENERIC_READ = 0x80000000 }; +#endif /* DR_CREATE_RSP.Information */ /* DR_DRIVE_CREATE_RSP.DeviceCreateResponse */ @@ -221,8 +224,10 @@ enum RDP_LOWIO_OP enum NTSTATUS { STATUS_SUCCESS = 0x00000000, +#ifndef _WIN32 STATUS_TIMEOUT = 0x00000102, STATUS_PENDING = 0x00000103, +#endif STATUS_REPARSE = 0x00000104, STATUS_MORE_ENTRIES = 0x00000105, STATUS_NOT_ALL_ASSIGNED = 0x00000106, @@ -245,8 +250,10 @@ enum NTSTATUS STATUS_UNSUCCESSFUL = 0xC0000001, STATUS_NOT_IMPLEMENTED = 0xC0000002, STATUS_INVALID_INFO_CLASS = 0xC0000003, +#ifndef _WIN32 STATUS_INVALID_HANDLE = 0xC0000008, STATUS_INVALID_PARAMETER = 0xC000000D, +#endif STATUS_NO_SUCH_DEVICE = 0xC000000E, STATUS_NO_SUCH_FILE = 0xC000000F, STATUS_INVALID_DEVICE_REQUEST = 0xC0000010, @@ -289,6 +296,9 @@ enum RDPDR_PRINTER_ANNOUNCE_FLAG }; /* [MS-FSCC] FileAttributes */ + +#ifndef _WIN32 + enum FILE_ATTRIBUTE { FILE_ATTRIBUTE_ARCHIVE = 0x00000020, @@ -306,6 +316,8 @@ enum FILE_ATTRIBUTE FILE_ATTRIBUTE_TEMPORARY = 0x00000100 }; +#endif + /* [MS-FSCC] FSCTL Structures */ enum FSCTL_STRUCTURE { @@ -337,6 +349,9 @@ enum FSCTL_STRUCTURE }; /* [MS-FSCC] FileFsAttributeInformation.FileSystemAttributes */ + +#ifndef _WIN32 + enum FILE_FS_ATTRIBUTE_INFORMATION { FILE_SUPPORTS_USN_JOURNAL = 0x02000000, @@ -361,6 +376,8 @@ enum FILE_FS_ATTRIBUTE_INFORMATION FILE_CASE_SENSITIVE_SEARCH = 0x00000001 }; +#endif + /* [MS-FSCC] FileFsDeviceInformation.DeviceType */ enum FILE_FS_DEVICE_TYPE { diff --git a/channels/rdpdr/rdpdr_main.c b/channels/rdpdr/rdpdr_main.c index f9d9a587a..c7fcbb05c 100644 --- a/channels/rdpdr/rdpdr_main.c +++ b/channels/rdpdr/rdpdr_main.c @@ -18,10 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include + #include #include #include @@ -59,7 +63,7 @@ static void rdpdr_process_connect(rdpSvcPlugin* plugin) { devman_load_device_service(rdpdr->devman, data); } - data = (RDP_PLUGIN_DATA*) (((void*) data) + data->size); + data = (RDP_PLUGIN_DATA*) (((uint8*) data) + data->size); } } @@ -83,7 +87,7 @@ static void rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr) stream_write_uint16(data_out, rdpdr->versionMajor); stream_write_uint16(data_out, rdpdr->versionMinor); - stream_write_uint32(data_out, rdpdr->clientID); + stream_write_uint32(data_out, (uint32) rdpdr->clientID); svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out); } diff --git a/channels/rdpdr/rdpdr_types.h b/channels/rdpdr/rdpdr_types.h index a87dad289..c5594e4d0 100644 --- a/channels/rdpdr/rdpdr_types.h +++ b/channels/rdpdr/rdpdr_types.h @@ -21,7 +21,6 @@ #ifndef __RDPDR_TYPES_H #define __RDPDR_TYPES_H -#include "config.h" #include #include #include diff --git a/channels/rdpdr/serial/CMakeLists.txt b/channels/rdpdr/serial/CMakeLists.txt index 40c962a58..4b3ac4492 100644 --- a/channels/rdpdr/serial/CMakeLists.txt +++ b/channels/rdpdr/serial/CMakeLists.txt @@ -21,14 +21,17 @@ set(serial_SRCS serial_tty.c serial_tty.h serial_constants.h - serial_main.c -) + serial_main.c) include_directories(..) add_library(serial ${serial_SRCS}) set_target_properties(serial PROPERTIES PREFIX "") -target_link_libraries(serial freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(serial freerdp) +else() + target_link_libraries(serial freerdp-utils) +endif() install(TARGETS serial DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdr/serial/serial_main.c b/channels/rdpdr/serial/serial_main.c index 3bee5abd0..547edbfa1 100644 --- a/channels/rdpdr/serial/serial_main.c +++ b/channels/rdpdr/serial/serial_main.c @@ -18,13 +18,15 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include -#include "config.h" - #ifdef HAVE_SYS_MODEM_H #include #endif diff --git a/channels/rdpdr/serial/serial_tty.c b/channels/rdpdr/serial/serial_tty.c index bdca70372..4dfa690e7 100644 --- a/channels/rdpdr/serial/serial_tty.c +++ b/channels/rdpdr/serial/serial_tty.c @@ -18,10 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include + #include #include #include @@ -30,13 +34,16 @@ #include #include +#ifndef _WIN32 #include #include +#include +#include +#endif + #include #include #include -#include -#include #include #include "rdpdr_constants.h" @@ -67,7 +74,6 @@ #define TIOCOUTQ FIONWRITE #endif - static uint32 tty_write_data(SERIAL_TTY* tty, uint8* data, int len); static void tty_set_termios(SERIAL_TTY* tty); static boolean tty_get_termios(SERIAL_TTY* tty); diff --git a/channels/rdpdr/serial/serial_tty.h b/channels/rdpdr/serial/serial_tty.h index a4b82f98f..d9b76414e 100644 --- a/channels/rdpdr/serial/serial_tty.h +++ b/channels/rdpdr/serial/serial_tty.h @@ -23,7 +23,10 @@ #include #include + +#ifndef _WIN32 #include +#endif typedef struct _SERIAL_TTY SERIAL_TTY; struct _SERIAL_TTY @@ -59,7 +62,6 @@ struct _SERIAL_TTY int event_pending; }; - SERIAL_TTY* serial_tty_new(const char* path, uint32 id); void serial_tty_free(SERIAL_TTY* tty); diff --git a/channels/rdpdr/smartcard/CMakeLists.txt b/channels/rdpdr/smartcard/CMakeLists.txt index 816fc09f4..c486e1ba7 100644 --- a/channels/rdpdr/smartcard/CMakeLists.txt +++ b/channels/rdpdr/smartcard/CMakeLists.txt @@ -28,7 +28,12 @@ include_directories(${PCSC_INCLUDE_DIRS}) add_library(scard ${SCARD_SRCS}) set_target_properties(scard PROPERTIES PREFIX "") -target_link_libraries(scard freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(scard freerdp) +else() + target_link_libraries(scard freerdp-utils) +endif() + target_link_libraries(scard ${PCSC_LIBRARIES}) install(TARGETS scard DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdr/smartcard/scard_main.c b/channels/rdpdr/smartcard/scard_main.c index 5066bf2d0..216b8ad9b 100644 --- a/channels/rdpdr/smartcard/scard_main.c +++ b/channels/rdpdr/smartcard/scard_main.c @@ -1,25 +1,27 @@ -/* - FreeRDP: A Remote Desktop Protocol client. - Redirected Smart Card Device Service - - Copyright 2011 O.S. Systems Software Ltda. - Copyright 2011 Eduardo Fiss Beloni - Copyright 2011 Anthony Tong - - 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. -*/ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Smartcard Device Service Virtual Channel + * + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Eduardo Fiss Beloni + * Copyright 2011 Anthony Tong + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include #include @@ -28,18 +30,20 @@ #include #include #include +#include +#include #include "rdpdr_types.h" #include "rdpdr_constants.h" #include "scard_main.h" - static void scard_free(DEVICE* dev) { SCARD_DEVICE* scard = (SCARD_DEVICE*)dev; IRP* irp; + COMPLETIONIDINFO* CompletionIdInfo; freerdp_thread_stop(scard->thread); freerdp_thread_free(scard->thread); @@ -48,6 +52,12 @@ scard_free(DEVICE* dev) irp->Discard(irp); list_free(scard->irp_list); + /* Begin TS Client defect workaround. */ + while ((CompletionIdInfo = (COMPLETIONIDINFO*)list_dequeue(scard->CompletionIds)) != NULL) + xfree(CompletionIdInfo); + list_free(scard->CompletionIds); + /* End TS Client defect workaround. */ + xfree(dev); return; } @@ -130,11 +140,138 @@ scard_thread_func(void* arg) } +/* Begin TS Client defect workaround. */ +static COMPLETIONIDINFO* +scard_mark_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId) +{ +/* + * Search from the beginning of the LIST for one outstanding "CompletionID" + * that matches the one passed in. If there is one, mark it as a duplicate + * if it is not already marked. + */ + LIST_ITEM* item; + COMPLETIONIDINFO* CompletionIdInfo; + + for (item = scard->CompletionIds->head; item; item = item->next) + { + CompletionIdInfo = (COMPLETIONIDINFO*)item->data; + if (CompletionIdInfo->ID == CompletionId) + { + if (false == CompletionIdInfo->duplicate) + { + CompletionIdInfo->duplicate = true; + DEBUG_WARN("CompletionID number %u is now marked as a duplicate.", CompletionId); + } + return CompletionIdInfo; + } + } + return NULL; /* Either no items in the list or no match. */ +} + +static boolean +scard_check_for_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId) +{ +/* + * Search from the end of the LIST for one outstanding "CompletionID" + * that matches the one passed in. Remove it from the list and free the + * memory associated with it. Return whether or not it was marked + * as a duplicate. + */ + LIST_ITEM* item; + COMPLETIONIDINFO* CompletionIdInfo; + boolean duplicate; + + for (item = scard->CompletionIds->tail; item; item = item->prev) + { + CompletionIdInfo = (COMPLETIONIDINFO*)item->data; + if (CompletionIdInfo->ID == CompletionId) + { + duplicate = CompletionIdInfo->duplicate; + if (true == duplicate) + { + DEBUG_WARN("CompletionID number %u was previously marked as a duplicate. The response to the command is removed.", CompletionId); + } + list_remove(scard->CompletionIds, CompletionIdInfo); + xfree(CompletionIdInfo); + return duplicate; + } + } + /* This function should only be called when there is + * at least one outstanding CompletionID item in the list. + */ + DEBUG_WARN("Error!!! No CompletionIDs (or no matching IDs) in the list!"); + return false; +} + +static void +scard_irp_complete(IRP* irp) +{ +/* This function is (mostly) a copy of the statically-declared "irp_complete()" + * function except that this function adds extra operations for the + * smart card's handling of duplicate "CompletionID"s. This function needs + * to be in this file so that "scard_irp_request()" can reference it. + */ + int pos; + boolean duplicate; + SCARD_DEVICE* scard = (SCARD_DEVICE*)irp->device; + + DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId); + + pos = stream_get_pos(irp->output); + stream_set_pos(irp->output, 12); + stream_write_uint32(irp->output, irp->IoStatus); + stream_set_pos(irp->output, pos); + + /* Begin TS Client defect workaround. */ + freerdp_mutex_lock(scard->CompletionIdsMutex); + /* Remove from the list the item identified by the CompletionID. + * The function returns whether or not it was a duplicate CompletionID. + */ + duplicate = scard_check_for_duplicate_id(scard, irp->CompletionId); + freerdp_mutex_unlock(scard->CompletionIdsMutex); + + if (false == duplicate) + { + svc_plugin_send(irp->devman->plugin, irp->output); + irp->output = NULL; + } + /* End TS Client defect workaround. */ + + /* irp_free(irp); The "irp_free()" function is statically-declared + * and so is not available to be called + * here. Instead, call it indirectly by calling + * the IRP's "Discard()" function, + * which has already been assigned + * to point to "irp_free()" in "irp_new()". + */ + irp->Discard(irp); +} +/* End TS Client defect workaround. */ + + static void scard_irp_request(DEVICE* device, IRP* irp) { + COMPLETIONIDINFO* CompletionIdInfo; + SCARD_DEVICE* scard = (SCARD_DEVICE*)device; + /* Begin TS Client defect workaround. */ + CompletionIdInfo= xnew(COMPLETIONIDINFO); + CompletionIdInfo->ID = irp->CompletionId;/* "duplicate" member is set + * to false by "xnew()" + */ + freerdp_mutex_lock(scard->CompletionIdsMutex); + scard_mark_duplicate_id(scard, irp->CompletionId); + list_enqueue(scard->CompletionIds, CompletionIdInfo); + freerdp_mutex_unlock(scard->CompletionIdsMutex); + + irp->Complete = scard_irp_complete; /* Overwrite the previous + * assignment made in + * "irp_new()". + */ + /* End TS Client defect workaround. */ + if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL && scard_async_op(irp)) { @@ -161,7 +298,6 @@ scard_irp_request(DEVICE* device, IRP* irp) freerdp_thread_signal(scard->thread); } - int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { @@ -195,6 +331,9 @@ DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) scard->irp_list = list_new(); scard->thread = freerdp_thread_new(); + scard->CompletionIds = list_new(); + scard->CompletionIdsMutex = freerdp_mutex_new(); + pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE *)scard); freerdp_thread_start(scard->thread, scard_thread_func, scard); diff --git a/channels/rdpdr/smartcard/scard_main.h b/channels/rdpdr/smartcard/scard_main.h index 7813f486c..15445929b 100644 --- a/channels/rdpdr/smartcard/scard_main.h +++ b/channels/rdpdr/smartcard/scard_main.h @@ -1,22 +1,22 @@ -/* - FreeRDP: A Remote Desktop Protocol client. - Redirected Smart Card Device Service - - Copyright 2011 O.S. Systems Software Ltda. - Copyright 2011 Eduardo Fiss Beloni - - 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. -*/ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Smartcard Device Service Virtual Channel + * + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Eduardo Fiss Beloni + * + * 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 __SCARD_MAIN_H #define __SCARD_MAIN_H @@ -25,8 +25,74 @@ #include "devman.h" #include "rdpdr_types.h" +#include /* For CompletionIdsMutex */ +#include #include +/* + * When using Windows Server 2008 R2 as the Terminal Services (TS) + * server, and with a smart card reader connected to the TS client machine + * and used to authenticate to an existing login session, the TS server + * will initiate the protocol initialization of MS-RDPEFS, Section 1.3.1, + * twice as it re-establishes a connection. The TS server starts both + * initializations with a "Server Announce Request" message. + * When the TS client receives this message, as per Section 3.2.5.1.2, + * + * The client SHOULD treat this packet as the beginning + * of a new sequence. The client SHOULD also cancel all + * outstanding requests and release previous references to + * all devices. + * + * As of this writing, the code does not cancel all outstanding requests. + * This leads to a problem where, after the first MS-RDPEFS initialization, + * the TS server sends an SCARD_IOCTL_GETSTATUSCHANGEx control in a message + * that uses an available "CompletionID". The + * TS client doesn't respond immediately because it is blocking while + * waiting for a change in the smart card's status in the reader. + * Then the TS server initiates a second MS-RDPEFS initialization sequence. + * As noted above, this should cancel the outstanding + * SCARD_IOCTL_GETSTATUSCHANGEx request, but it does not. + * At this point, the TS server is free to reuse the previously used + * "CompletionID", and it does reuse it for other SCARD_IOCTLs. + * Therefore, when the user removes (for example) the card from the reader, + * the TS client sends an "IOCompetion" message in response to the + * GETSTATUSCHANGEx using the original "CompletionID". The TS server does not + * expect this "CompletionID" and so, as per Section 3.1.5.2 of MS-RDPEFS, + * it treats that "IOCompletion" message as an error and terminates the + * virtual channel. + * + * The following structure is part of a work-around for this missing + * capability of canceling outstanding requests. This work-around + * allows the TS client to send an "IOCompletion" back to the + * TS server for the second (and subsequent) SCARD_IOCTLs that use + * the same "CompletionID" as the still outstanding + * SCARD_IOCTL_GETSTATUSCHANGEx. The work-around in the TS client + * prevents the client from sending the "IOCompletion" back (when + * the user removes the card) for the SCARD_IOCTL_GETSTATUSCHANGEx. + * + * This TS client expects the responses from the PCSC daemon for the second + * and subsequent SCARD_IOCTLs that use the same "CompletionID" + * to arrive at the TS client before the daemon's response to the + * SCARD_IOCTL_GETSTATUSCHANGEx. This is a race condition. + * + * The "CompletionIDs" are a global pool of IDs across all "DeviceIDs". + * However, this problem of duplicate "CompletionIDs" only affects smart cards. + * + * This structure tracks outstanding Terminal Services server "CompletionIDs" + * used by the redirected smart card device. + */ +struct _COMPLETIONIDINFO +{ + uint32 ID; /* CompletionID */ + boolean duplicate; /* Indicates whether or not this + * CompletionID is a duplicate of an + * earlier, outstanding, CompletionID. + */ +}; + +typedef struct _COMPLETIONIDINFO COMPLETIONIDINFO; + + struct _SCARD_DEVICE { DEVICE device; @@ -37,6 +103,11 @@ struct _SCARD_DEVICE LIST* irp_list; freerdp_thread* thread; + + LIST* CompletionIds; + freerdp_mutex CompletionIdsMutex; /* Protect the LIST from + * multiple thread writers. + */ }; typedef struct _SCARD_DEVICE SCARD_DEVICE; diff --git a/channels/rdpdr/smartcard/scard_operations.c b/channels/rdpdr/smartcard/scard_operations.c index 0551a5015..fbf87f4b4 100644 --- a/channels/rdpdr/smartcard/scard_operations.c +++ b/channels/rdpdr/smartcard/scard_operations.c @@ -1,25 +1,27 @@ -/* - FreeRDP: A Remote Desktop Protocol client. - Redirected Smart Card Device Service - - Copyright (C) Alexi Volkov 2006 - Copyright 2011 O.S. Systems Software Ltda. - Copyright 2011 Anthony Tong - - 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. -*/ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Smartcard Device Service Virtual Channel + * + * Copyright (C) Alexi Volkov 2006 + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Anthony Tong + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include #include @@ -114,7 +116,12 @@ static uint32 sc_output_string(IRP* irp, char *src, boolean wide) static void sc_output_alignment(IRP *irp, uint32 seed) { - uint32 size = stream_get_length(irp->output) - 20; + const uint32 field_lengths = 20;/* Remove the lengths of the fields + * RDPDR_HEADER, DeviceID, + * CompletionID, and IoStatus + * of Section 2.2.1.5.5 of MS-RDPEFS. + */ + uint32 size = stream_get_length(irp->output) - field_lengths; uint32 add = (seed - (size % seed)) % seed; if (add > 0) @@ -270,14 +277,15 @@ static uint32 handle_EstablishContext(IRP* irp) rv = SCardEstablishContext(scope, NULL, NULL, &hContext); - stream_write_uint32(irp->output, 4); // ? - stream_write_uint32(irp->output, -1); // ? + stream_write_uint32(irp->output, 4); // cbContext + stream_write_uint32(irp->output, -1); // ReferentID stream_write_uint32(irp->output, 4); stream_write_uint32(irp->output, hContext); /* TODO: store hContext in allowed context list */ + sc_output_alignment(irp, 8); return SCARD_S_SUCCESS; } @@ -298,6 +306,7 @@ static uint32 handle_ReleaseContext(IRP* irp) else DEBUG_SCARD("success 0x%08lx", hContext); + sc_output_alignment(irp, 8); return rv; } @@ -316,7 +325,7 @@ static uint32 handle_IsValidContext(IRP* irp) else DEBUG_SCARD("Success context: 0x%08x", (unsigned) hContext); - stream_write_uint32(irp->output, rv); + sc_output_alignment(irp, 8); return rv; } @@ -454,7 +463,6 @@ static uint32 handle_GetStatusChange(IRP* irp, boolean wide) /* reset high bytes? */ cur->dwCurrentState &= 0x0000FFFF; - cur->dwEventState &= 0x0000FFFF; cur->dwEventState = 0; } @@ -576,7 +584,6 @@ static uint32 handle_Connect(IRP* irp, boolean wide) stream_write_uint32(irp->output, dwActiveProtocol); stream_write_uint32(irp->output, 0x00000004); stream_write_uint32(irp->output, hCard); - stream_seek(irp->output, 28); sc_output_alignment(irp, 8); @@ -616,8 +623,8 @@ static uint32 handle_Reconnect(IRP* irp) else DEBUG_SCARD("Success (proto: 0x%08x)", (unsigned) dwActiveProtocol); + stream_write_uint32(irp->output, dwActiveProtocol); sc_output_alignment(irp, 8); - stream_write_uint32(irp->output, dwActiveProtocol); /* reversed? */ return rv; } @@ -1165,7 +1172,7 @@ static uint32 handle_GetAttrib(IRP* irp) static uint32 handle_AccessStartedEvent(IRP* irp) { - stream_write_zero(irp->output, 8); + sc_output_alignment(irp, 8); return SCARD_S_SUCCESS; } @@ -1365,8 +1372,10 @@ void scard_device_control(SCARD_DEVICE* scard, IRP* irp) uint32 output_len, input_len, ioctl_code; uint32 stream_len, result; uint32 pos, pad_len; - uint32 irp_len; uint32 irp_result_pos, output_len_pos, result_pos; + const uint32 header_lengths = 16; /* MS-RPCE, Sections 2.2.6.1 + * and 2.2.6.2. + */ stream_read_uint32(irp->input, output_len); stream_read_uint32(irp->input, input_len); @@ -1383,8 +1392,12 @@ void scard_device_control(SCARD_DEVICE* scard, IRP* irp) irp_result_pos = stream_get_pos(irp->output); - stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ - + stream_write_uint32(irp->output, 0x00000000); /* MS-RDPEFS + * OutputBufferLength + * will be updated + * later in this + * function. + */ /* [MS-RPCE] 2.2.6.1 */ stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ stream_write_uint32(irp->output, 0xcccccccc); /* filler */ @@ -1510,26 +1523,21 @@ void scard_device_control(SCARD_DEVICE* scard, IRP* irp) /* handle response packet */ pos = stream_get_pos(irp->output); - stream_len = pos - irp_result_pos - 4; + stream_len = pos - irp_result_pos - 4; /* Value of OutputBufferLength */ + stream_set_pos(irp->output, irp_result_pos); + stream_write_uint32(irp->output, stream_len); stream_set_pos(irp->output, output_len_pos); - stream_write_uint32(irp->output, stream_len - 24); + /* Remove the effect of the MS-RPCE Common Type Header and Private + * Header (Sections 2.2.6.1 and 2.2.6.2). + */ + stream_write_uint32(irp->output, stream_len - header_lengths); stream_set_pos(irp->output, result_pos); stream_write_uint32(irp->output, result); stream_set_pos(irp->output, pos); - /* pad stream to 16 byte align */ - pad_len = stream_len % 16; - stream_write_zero(irp->output, pad_len); - pos = stream_get_pos(irp->output); - irp_len = stream_len + pad_len; - - stream_set_pos(irp->output, irp_result_pos); - stream_write_uint32(irp->output, irp_len); - stream_set_pos(irp->output, pos); - #ifdef WITH_DEBUG_SCARD freerdp_hexdump(stream_get_data(irp->output), stream_get_length(irp->output)); #endif diff --git a/channels/rdpsnd/CMakeLists.txt b/channels/rdpsnd/CMakeLists.txt index 3065ac63e..745358da0 100644 --- a/channels/rdpsnd/CMakeLists.txt +++ b/channels/rdpsnd/CMakeLists.txt @@ -19,13 +19,16 @@ set(RDPSND_SRCS rdpsnd_main.c - rdpsnd_main.h -) + rdpsnd_main.h) add_library(rdpsnd ${RDPSND_SRCS}) set_target_properties(rdpsnd PROPERTIES PREFIX "") -target_link_libraries(rdpsnd freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(rdpsnd freerdp) +else() + target_link_libraries(rdpsnd freerdp-utils) +endif() install(TARGETS rdpsnd DESTINATION ${FREERDP_PLUGIN_PATH}) @@ -37,3 +40,7 @@ if(WITH_PULSEAUDIO) add_subdirectory(pulse) endif() +if(WITH_MACAUDIO) + add_subdirectory(mac_audio) +endif() + diff --git a/channels/rdpsnd/alsa/CMakeLists.txt b/channels/rdpsnd/alsa/CMakeLists.txt index 4d6deb43e..1dbe268cf 100644 --- a/channels/rdpsnd/alsa/CMakeLists.txt +++ b/channels/rdpsnd/alsa/CMakeLists.txt @@ -27,7 +27,12 @@ include_directories(${ALSA_INCLUDE_DIRS}) add_library(rdpsnd_alsa ${RDPSND_ALSA_SRCS}) set_target_properties(rdpsnd_alsa PROPERTIES PREFIX "") -target_link_libraries(rdpsnd_alsa freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(rdpsnd_alsa freerdp) +else() + target_link_libraries(rdpsnd_alsa freerdp-utils) +endif() + target_link_libraries(rdpsnd_alsa ${ALSA_LIBRARIES}) install(TARGETS rdpsnd_alsa DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpsnd/alsa/rdpsnd_alsa.c b/channels/rdpsnd/alsa/rdpsnd_alsa.c index 86426bf9c..19c3ecab6 100644 --- a/channels/rdpsnd/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/alsa/rdpsnd_alsa.c @@ -18,10 +18,16 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include + #include #include #include diff --git a/channels/rdpsnd/mac_audio/CMakeLists.txt b/channels/rdpsnd/mac_audio/CMakeLists.txt new file mode 100644 index 000000000..45b50548c --- /dev/null +++ b/channels/rdpsnd/mac_audio/CMakeLists.txt @@ -0,0 +1,40 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2012 Laxmikant Rashinkar +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(RDPSND_MACAUDIO_SRCS + rdpsnd_audio_q.c) + +include_directories(..) +include_directories(${MACAUDIO_INCLUDE_DIRS}) + +add_library(rdpsnd_macaudio ${RDPSND_MACAUDIO_SRCS}) +set_target_properties(rdpsnd_macaudio PROPERTIES PREFIX "") + +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(rdpsnd_macaudio freerdp) +else() + target_link_libraries(rdpsnd_macaudio freerdp-utils) +endif() + +target_link_libraries(rdpsnd_macaudio ${MAC_AUDIOTOOLBOX_LIBRARY_PATH}) +target_link_libraries(rdpsnd_macaudio ${MAC_COREFOUNDATION_LIBRARY_PATH}) + +install(TARGETS rdpsnd_macaudio DESTINATION ${FREERDP_PLUGIN_PATH}) + diff --git a/channels/rdpsnd/mac_audio/rdpsnd_audio_q.c b/channels/rdpsnd/mac_audio/rdpsnd_audio_q.c new file mode 100644 index 000000000..f089588d9 --- /dev/null +++ b/channels/rdpsnd/mac_audio/rdpsnd_audio_q.c @@ -0,0 +1,229 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Audio Output Virtual Channel + * + * Copyright 2012 Laxmikant Rashinkar + * + * 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. + */ + +/** + * Use AudioQueue to implement audio redirection + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "rdpsnd_main.h" + +#define AQ_NUM_BUFFERS 10 +#define AQ_BUF_SIZE (32 * 1024) + +static void aq_playback_cb(void *user_data, + AudioQueueRef aq_ref, + AudioQueueBufferRef aq_buf_ref + ); + +struct rdpsnd_audio_q_plugin +{ + rdpsndDevicePlugin device; + + /* audio queue player state */ + int is_open; // true when audio_q has been inited + char * device_name; + int is_playing; + int buf_index; + + AudioStreamBasicDescription data_format; + AudioQueueRef aq_ref; + AudioQueueBufferRef buffers[AQ_NUM_BUFFERS]; +}; +typedef struct rdpsnd_audio_q_plugin rdpsndAudioQPlugin; + +static void rdpsnd_audio_close(rdpsndDevicePlugin* device) +{ + rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin*) device; + + AudioQueueStop(aq_plugin_p->aq_ref, 0); + aq_plugin_p->is_open = 0; +} + +static void rdpsnd_audio_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency) +{ + int rv; + int i; + + rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin *) device; + if (aq_plugin_p->is_open) { + return; + } + + aq_plugin_p->buf_index = 0; + + // setup AudioStreamBasicDescription + aq_plugin_p->data_format.mSampleRate = 44100; + aq_plugin_p->data_format.mFormatID = kAudioFormatLinearPCM; + aq_plugin_p->data_format.mFormatFlags = kAudioFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; + + // until we know better, assume that one packet = one frame + // one frame = bytes_per_sample x number_of_channels + aq_plugin_p->data_format.mBytesPerPacket = 4; + aq_plugin_p->data_format.mFramesPerPacket = 1; + aq_plugin_p->data_format.mBytesPerFrame = 4; + aq_plugin_p->data_format.mChannelsPerFrame = 2; + aq_plugin_p->data_format.mBitsPerChannel = 16; + + rv = AudioQueueNewOutput(&aq_plugin_p->data_format, // audio stream basic desc + aq_playback_cb, // callback when more data is required + aq_plugin_p, // data to pass to callback + CFRunLoopGetCurrent(), // The current run loop, and the one on + // which the audio queue playback callback + // will be invoked + kCFRunLoopCommonModes, // run loop modes in which callbacks can + // be invoked + 0, // flags - reserved + &aq_plugin_p->aq_ref + ); + if (rv != 0) { + printf("rdpsnd_audio_open: AudioQueueNewOutput() failed with error %d\n", rv); + aq_plugin_p->is_open = 1; + return; + } + + for (i = 0; i < AQ_NUM_BUFFERS; i++) + { + rv = AudioQueueAllocateBuffer(aq_plugin_p->aq_ref, AQ_BUF_SIZE, &aq_plugin_p->buffers[i]); + } + + aq_plugin_p->is_open = 1; +} + +static void rdpsnd_audio_free(rdpsndDevicePlugin* device) +{ +} + +static boolean rdpsnd_audio_format_supported(rdpsndDevicePlugin* device, rdpsndFormat* format) +{ + switch (format->wFormatTag) + { + case 1: /* PCM */ + if (format->cbSize == 0 && + (format->nSamplesPerSec <= 48000) && + (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && + (format->nChannels == 1 || format->nChannels == 2)) + { + return 1; + } + break; + } + return 0; +} + +static void rdpsnd_audio_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency) +{ +} + +static void rdpsnd_audio_set_volume(rdpsndDevicePlugin* device, uint32 value) +{ +} + +static void rdpsnd_audio_play(rdpsndDevicePlugin* device, uint8* data, int size) +{ + rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin *) device; + AudioQueueBufferRef aq_buf_ref; + int len; + + if (!aq_plugin_p->is_open) { + return; + } + + /* get next empty buffer */ + aq_buf_ref = aq_plugin_p->buffers[aq_plugin_p->buf_index]; + + // fill aq_buf_ref with audio data + len = size > AQ_BUF_SIZE ? AQ_BUF_SIZE : size; + + memcpy(aq_buf_ref->mAudioData, (char *) data, len); + aq_buf_ref->mAudioDataByteSize = len; + + // add buffer to audioqueue + AudioQueueEnqueueBuffer(aq_plugin_p->aq_ref, aq_buf_ref, 0, 0); + + // update buf_index + aq_plugin_p->buf_index++; + if (aq_plugin_p->buf_index >= AQ_NUM_BUFFERS) { + aq_plugin_p->buf_index = 0; + } +} + +static void rdpsnd_audio_start(rdpsndDevicePlugin* device) +{ + rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin *) device; + + AudioQueueStart(aq_plugin_p->aq_ref, NULL); +} + +/** + * AudioQueue Playback callback + * + * our job here is to fill aq_buf_ref with audio data and enqueue it + */ + +static void aq_playback_cb(void *user_data, + AudioQueueRef aq_ref, + AudioQueueBufferRef aq_buf_ref + ) +{ +} + +int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) +{ + rdpsndAudioQPlugin* aqPlugin; + RDP_PLUGIN_DATA* data; + + aqPlugin = xnew(rdpsndAudioQPlugin); + + aqPlugin->device.Open = rdpsnd_audio_open; + aqPlugin->device.FormatSupported = rdpsnd_audio_format_supported; + aqPlugin->device.SetFormat = rdpsnd_audio_set_format; + aqPlugin->device.SetVolume = rdpsnd_audio_set_volume; + aqPlugin->device.Play = rdpsnd_audio_play; + aqPlugin->device.Start = rdpsnd_audio_start; + aqPlugin->device.Close = rdpsnd_audio_close; + aqPlugin->device.Free = rdpsnd_audio_free; + + data = pEntryPoints->plugin_data; + + if (data && strcmp((char *)data->data[0], "macaudio") == 0) { + if(strlen((char *)data->data[1]) > 0) + aqPlugin->device_name = strdup((char *)data->data[1]); + else + aqPlugin->device_name = NULL; + } + pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)aqPlugin); + return 0; +} + diff --git a/channels/rdpsnd/pulse/CMakeLists.txt b/channels/rdpsnd/pulse/CMakeLists.txt index 844ffde4f..5ff96249f 100644 --- a/channels/rdpsnd/pulse/CMakeLists.txt +++ b/channels/rdpsnd/pulse/CMakeLists.txt @@ -18,8 +18,7 @@ # limitations under the License. set(RDPSND_PULSE_SRCS - rdpsnd_pulse.c -) + rdpsnd_pulse.c) include_directories(..) include_directories(${PULSEAUDIO_INCLUDE_DIR}) @@ -27,7 +26,12 @@ include_directories(${PULSEAUDIO_INCLUDE_DIR}) add_library(rdpsnd_pulse ${RDPSND_PULSE_SRCS}) set_target_properties(rdpsnd_pulse PROPERTIES PREFIX "") -target_link_libraries(rdpsnd_pulse freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(rdpsnd_pulse freerdp) +else() + target_link_libraries(rdpsnd_pulse freerdp-utils) +endif() + target_link_libraries(rdpsnd_pulse ${PULSEAUDIO_LIBRARY}) install(TARGETS rdpsnd_pulse DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpsnd/pulse/rdpsnd_pulse.c b/channels/rdpsnd/pulse/rdpsnd_pulse.c index 0a1658f64..3fe645ba2 100644 --- a/channels/rdpsnd/pulse/rdpsnd_pulse.c +++ b/channels/rdpsnd/pulse/rdpsnd_pulse.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/channels/rdpsnd/rdpsnd_main.c b/channels/rdpsnd/rdpsnd_main.c index ca774d8ad..6fa9d94f4 100644 --- a/channels/rdpsnd/rdpsnd_main.c +++ b/channels/rdpsnd/rdpsnd_main.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef _WIN32 #include #endif @@ -25,6 +29,7 @@ #include #include #include + #include #include #include @@ -477,7 +482,7 @@ static void rdpsnd_process_plugin_data(rdpsndPlugin* rdpsnd, RDP_PLUGIN_DATA* da static void rdpsnd_process_connect(rdpSvcPlugin* plugin) { - rdpsndPlugin* rdpsnd = (rdpsndPlugin*)plugin; + rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin; RDP_PLUGIN_DATA* data; RDP_PLUGIN_DATA default_data[2] = { { 0 }, { 0 } }; @@ -489,10 +494,11 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin) rdpsnd->latency = -1; data = (RDP_PLUGIN_DATA*)plugin->channel_entry_points.pExtendedData; + while (data && data->size > 0) { rdpsnd_process_plugin_data(rdpsnd, data); - data = (RDP_PLUGIN_DATA*) (((void*) data) + data->size); + data = (RDP_PLUGIN_DATA*) (((uint8*) data) + data->size); } if (rdpsnd->device == NULL) @@ -504,7 +510,22 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin) { default_data[0].data[0] = "alsa"; default_data[0].data[1] = "default"; - rdpsnd_load_device_plugin(rdpsnd, "alsa", default_data); + + if (!rdpsnd_load_device_plugin(rdpsnd, "alsa", default_data)) + { + default_data[0].data[0] = "macaudio"; + default_data[0].data[1] = "default"; + + rdpsnd_load_device_plugin(rdpsnd, "macaudio", default_data); + } + else + { + printf("rdpsnd: successfully loaded alsa plugin\n"); + } + } + else + { + printf("rdpsnd: successfully loaded pulseaudio plugin\n"); } } if (rdpsnd->device == NULL) diff --git a/channels/skel/CMakeLists.txt b/channels/skel/CMakeLists.txt index 1bc5354ea..1c2943c8f 100644 --- a/channels/skel/CMakeLists.txt +++ b/channels/skel/CMakeLists.txt @@ -19,12 +19,15 @@ set(SKEL_SRCS skel_main.c - skel_main.h -) + skel_main.h) add_library(skel ${SKEL_SRCS}) set_target_properties(skel PROPERTIES PREFIX "") -target_link_libraries(skel freerdp-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(skel freerdp) +else() + target_link_libraries(skel freerdp-utils) +endif() install(TARGETS skel DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/skel/readme.txt b/channels/skel/readme.txt index 217589fa2..34c1b340c 100644 --- a/channels/skel/readme.txt +++ b/channels/skel/readme.txt @@ -4,4 +4,8 @@ To create your own virtual channel plugin, copy this directory then change all references of "skel" to your plugin name remember, plugin name are 7 chars or less, no spaces or funny chars +server_chan_test.cpp is an example of how to open a channel to the client +this code needs to be compiled and run on the server in an rdp session +when connect with a client that has the "skel" plugin loaded + Jay diff --git a/channels/skel/server_chan_test.cpp b/channels/skel/server_chan_test.cpp new file mode 100644 index 000000000..8de5f3fde --- /dev/null +++ b/channels/skel/server_chan_test.cpp @@ -0,0 +1,60 @@ +// xrdp_chan_test.cpp : Basic test for virtual channel use. + +// These headers are required for the windows terminal service calls. +#include "windows.h" +#include "wtsapi32.h" +#include + +#define DSIZE 1024 + +int main() +{ + // Initialize the data for send/receive + char* data; + char* data1; + data = (char*)malloc(DSIZE); + data1 = (char*)malloc(DSIZE); + memset(data, 0xca, DSIZE); + memset(data1, 0, DSIZE); + + // Open the skel channel in current session + void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0); + + unsigned long written = 0; + // Write the data to the channel + bool ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written); + if (!ret) + { + long err = GetLastError(); + printf("error 0x%8.8x\n", err); + return 1; + } + + ret = WTSVirtualChannelRead(channel, 100, data1, DSIZE, &written); + if (!ret) + { + long err = GetLastError(); + printf("error 0x%8.8x\n", err); + return 1; + } + if (written != DSIZE) + { + printf("error read %d\n", written); + return 1; + } + + ret = WTSVirtualChannelClose(channel); + if (memcmp(data, data1, DSIZE) == 0) + { + } + else + { + printf("error data no match\n"); + return 1; + } + + printf("Success!\n"); + + Sleep(2000); + return 0; +} diff --git a/channels/skel/skel_main.c b/channels/skel/skel_main.c index 305f7c05f..5fbd92611 100644 --- a/channels/skel/skel_main.c +++ b/channels/skel/skel_main.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef _WIN32 #include #endif @@ -25,6 +29,7 @@ #include #include #include + #include #include #include @@ -58,19 +63,25 @@ static void skel_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) if (skel == NULL) { + printf("skel_process_receive: skel is nil\n"); return; } /* process data in(from server) here */ /* here we just send the same data back */ - bytes = stream_get_length(data_in); + bytes = stream_get_size(data_in); + printf("skel_process_receive: got bytes %d\n", bytes); if (bytes > 0) { data_out = stream_new(bytes); stream_copy(data_out, data_in, bytes); /* svc_plugin_send takes ownership of data_out, that is why we do not free it */ + + bytes = stream_get_length(data_in); + printf("skel_process_receive: sending bytes %d\n", bytes); + svc_plugin_send(plugin, data_out); } diff --git a/client/DirectFB/CMakeLists.txt b/client/DirectFB/CMakeLists.txt index bf317d644..a9c076d2f 100644 --- a/client/DirectFB/CMakeLists.txt +++ b/client/DirectFB/CMakeLists.txt @@ -19,7 +19,7 @@ include_directories(${DIRECTFB_INCLUDE_DIRS}) -add_executable(dfreerdp +set(FREERDP_CLIENT_DIRECTFB_SRCS df_event.c df_event.h df_graphics.c @@ -27,11 +27,20 @@ add_executable(dfreerdp dfreerdp.c dfreerdp.h) -target_link_libraries(dfreerdp freerdp-core) -target_link_libraries(dfreerdp freerdp-gdi) -target_link_libraries(dfreerdp freerdp-locale) -target_link_libraries(dfreerdp freerdp-channels) -target_link_libraries(dfreerdp freerdp-utils) -target_link_libraries(dfreerdp ${DIRECTFB_LIBRARIES}) +add_executable(dfreerdp ${FREERDP_CLIENT_DIRECTFB_SRCS}) +set(FREERDP_CLIENT_DIRECTFB_LIBS ${DIRECTFB_LIBRARIES}) + +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_CLIENT_DIRECTFB_LIBS ${FREERDP_CLIENT_DIRECTFB_LIBS} freerdp) +else() + set(FREERDP_CLIENT_DIRECTFB_LIBS ${FREERDP_CLIENT_DIRECTFB_LIBS} + freerdp-core + freerdp-gdi + freerdp-locale + freerdp-channels + freerdp-utils) +endif() + +target_link_libraries(dfreerdp ${FREERDP_CLIENT_DIRECTFB_LIBS}) install(TARGETS dfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/client/DirectFB/dfreerdp.c b/client/DirectFB/dfreerdp.c index 1af7cc95e..c6799effc 100644 --- a/client/DirectFB/dfreerdp.c +++ b/client/DirectFB/dfreerdp.c @@ -155,6 +155,8 @@ boolean df_pre_connect(freerdp* instance) dfi->clrconv->palette = xnew(rdpPalette); freerdp_channels_pre_connect(instance->context->channels, instance); + + instance->context->cache = cache_new(instance->settings); return true; } diff --git a/client/Mac/AppDelegate.h b/client/Mac/AppDelegate.h new file mode 100644 index 000000000..5af060d1c --- /dev/null +++ b/client/Mac/AppDelegate.h @@ -0,0 +1,19 @@ +// +// AppDelegate.h +// MacFreeRDP +// +// Created by Thomas Goddard on 5/8/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import +#import "MRDPView.h" + +@interface AppDelegate : NSObject + +@property (assign) IBOutlet MRDPView *mrdpView; +@property (assign) IBOutlet NSWindow *window; + + +int rdp_connect(); +@end diff --git a/client/Mac/AppDelegate.m b/client/Mac/AppDelegate.m new file mode 100644 index 000000000..3b7658d80 --- /dev/null +++ b/client/Mac/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// MacFreeRDP +// +// Created by Thomas Goddard on 5/8/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "AppDelegate.h" + +@implementation AppDelegate + +//@synthesize window = _window; +//@synthesize mrdpView; + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + rdp_connect(); +} + +- (void) applicationWillTerminate:(NSNotification *)notification +{ + //[mrdpView releaseResources]; +} + +@end diff --git a/client/Mac/CMakeLists.txt b/client/Mac/CMakeLists.txt new file mode 100644 index 000000000..5a68674c5 --- /dev/null +++ b/client/Mac/CMakeLists.txt @@ -0,0 +1,146 @@ + +cmake_minimum_required (VERSION 2.8) +project (MacFreeRDP) +set(CMAKE_COLOR_MAKEFILE ON) + +include(CheckIncludeFiles) +include(CheckLibraryExists) +include(CheckStructHasMember) +include(FindPkgConfig) +include(TestBigEndian) + +# Include our extra modules +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../../cmake/) + +include(AutoVersioning) +include(ConfigOptions) +include(FindOptionalPackage) +include(CheckCCompilerFlag) +include(GNUInstallDirsWrapper) + +# Default to debug build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") +endif() + +# Default to build shared libs +if(NOT DEFINED BUILD_SHARED_LIBS) + set(BUILD_SHARED_LIBS ON) +endif() + +# Compiler-specific flags +if(CMAKE_COMPILER_IS_GNUCC) + if(CMAKE_BUILD_TYPE STREQUAL "Release") + set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") + endif() + if(WITH_SSE2_TARGET) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2") + endif() +endif() + +# Libraries that we have a hard dependency on +if(NOT DEFINED OPENSSL_INCLUDE_DIR OR NOT DEFINED OPENSSL_LIBRARIES) + find_required_package(OpenSSL) +endif() + +# Mac OS X +if(APPLE) + # Set the include files for FreeRDP to the relative path + set(FREERDP_INCLUDE_PATH ${CMAKE_SOURCE_DIR}/../../include/) + set(FRAMEWORK_HEADERS_PATH /System/Library/Frameworks/Cocoa.framework/Versions/A/Headers/) + include_directories (${FREERDP_INCLUDE_PATH} ${FRAMEWORK_HEADERS_PATH} /System/Library/Frameworks) + + # set(CMAKE_OSX_SYSROOT MacOSX10.7.sdk) # uncomment to specify SDK version + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.4") + set(GUI_TYPE MACOSX_BUNDLE) + + # Import libraries + find_library(FOUNDATION_LIBRARY Foundation) + message("+ Using foundation library ${FOUNDATION_LIBRARY}") + find_library(COCOA_LIBRARY Cocoa) + message("+ Using cocoa library ${COCOA_LIBRARY}") + find_library(APPKIT_LIBRARY AppKit) + message("+ Using appkit library ${APPKIT_LIBRARY}") + + message(" Current source dir: ${CMAKE_CURRENT_SOURCE_DIR}") + # Set the OS X Bundle specific CMake variables which will be used to populate the plist for + # the application bundle + set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.freerdp.mac") + set(MACOSX_BUNDLE_BUNDLE_IDENTIFIER "FreeRDP.Mac") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} Version 1.0.1") + set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}) + set(MACOSX_BUNDLE_SHORT_VERSION_STRING 1.0.1) + set(MACOSX_BUNDLE_BUNDLE_VERSION 1.0.1) + set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2012. All Rights Reserved.") + + # Specific plist and NOT standard CMake variables + set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "MainMenu") + set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication") + + mark_as_advanced(COCOA_LIBRARY + FOUNDATION_LIBRARY + APPKIT_LIBRARY) + set(EXTRA_LIBS ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY}) + set(APP_TYPE MACOSX_BUNDLE) +endif() + +# OS X Interface Builder files +file (GLOB MacFreeRDP_XIBS + *.xib +) + +# Headers +file (GLOB MacFreeRDP_Headers + *.h + ) + +# Source +file (GLOB MacFreeRDP_Source + *.m + ) + +add_executable(MacFreeRDP + ${APP_TYPE} + ${MacFreeRDP_Headers} + ${MacFreeRDP_Source} + ${MacFreeRDP_XIBS}) + +# This is necessary for the xib file part below +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) + +# This allows for automatic xib to nib ibitool +set_target_properties(MacFreeRDP PROPERTIES RESOURCE "${MacFreeRDP_XIBS}") + +# Automatic ref counting +set_target_properties(MacFreeRDP PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES) + +# Support for automatic reference counting requires non-fragile abi. +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-nonfragile-abi") + +# XCode project architecture to native architecture of build machine +# ----------------------------------------------------------------------------------------------------- +# Issue: Had some issues with FreeRDP project building only 64 bit and +# MacFreeRDP attempting to link to both 32 and 64 for dual target. +# In the future the FreeRDP Xcode project should be pulled in for a couple of reasons: +# 1) better step-into debugging 2) automatic dependency compilation and multi-arch compilation + linkage +# If you know the solutions for 1 and 2, please add below. +set_target_properties(MacFreeRDP PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)") + +# Set the info plist to the custom instance +set_target_properties(MacFreeRDP PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) + +if(NOT WIN32) + find_optional_package(MacAudio) +endif() + +# Add all libraries +target_link_libraries(MacFreeRDP ${EXTRA_LIBS}) +target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-core/Debug/libfreerdp-core.dylib) +target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-channels/Debug/libfreerdp-channels.dylib) +target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-cache/Debug/libfreerdp-cache.dylib) +target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-gdi/Debug/libfreerdp-gdi.dylib) +target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-utils/Debug/libfreerdp-utils.dylib) +target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-codec/Debug/libfreerdp-codec.dylib) +target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-rail/Debug/libfreerdp-rail.dylib) diff --git a/client/Mac/Credits.rtf b/client/Mac/Credits.rtf new file mode 100755 index 000000000..41b9f4014 --- /dev/null +++ b/client/Mac/Credits.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf320 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\vieww9600\viewh8400\viewkind0 +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 + +\f0\b\fs24 \cf0 Engineering: +\b0 \ + Jay sorg\ + Marc-Andre Moreau\ + Vic Lee\ + Otvaio Salvador \ + Laxmikant Rashinkar\ + and others\ +\ + +\b Human Interface Design: +\b0 \ + Laxmikant Rashinkar\ + Jay Sorg\ +} \ No newline at end of file diff --git a/client/Mac/Info.plist b/client/Mac/Info.plist new file mode 100644 index 000000000..530ecb9a7 --- /dev/null +++ b/client/Mac/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + FreeRDP.Mac + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + ${MACOSX_DEPLOYMENT_TARGET} + NSHumanReadableCopyright + Copyright © 2012 __MyCompanyName__. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/client/Mac/MRDPCursor.h b/client/Mac/MRDPCursor.h new file mode 100644 index 000000000..98a2a08aa --- /dev/null +++ b/client/Mac/MRDPCursor.h @@ -0,0 +1,25 @@ +// +// MRDPCursor.h +// MacFreeRDP +// +// Created by Laxmikant Rashinkar +// Copyright (c) 2012 FreeRDP.org All rights reserved. +// + +#import + +#define boolean int + +#include "freerdp/graphics.h" + +@interface MRDPCursor : NSObject +{ +@public + rdpPointer *pointer; + uint8 *cursor_data; // bitmapped pixel data + NSBitmapImageRep *bmiRep; + NSCursor *nsCursor; + NSImage *nsImage; +} + +@end diff --git a/client/Mac/MRDPCursor.m b/client/Mac/MRDPCursor.m new file mode 100644 index 000000000..29a93c808 --- /dev/null +++ b/client/Mac/MRDPCursor.m @@ -0,0 +1,12 @@ +// +// MRDPCursor.m +// MacFreeRDP +// +// Created by Laxmikant Rashinkar +// Copyright (c) 2012 FreeRDP.org All rights reserved. +// + +#import "MRDPCursor.h" + +@implementation MRDPCursor +@end diff --git a/client/Mac/MRDPRailView.h b/client/Mac/MRDPRailView.h new file mode 100644 index 000000000..396a67661 --- /dev/null +++ b/client/Mac/MRDPRailView.h @@ -0,0 +1,61 @@ +#import + +#define boolean int + +#import "freerdp/gdi/gdi.h" +#import "freerdp/rail/rail.h" +#import "MRDPRailWindow.h" + +@interface MRDPRailView : NSView +{ + freerdp * rdp_instance; + rdpContext * context; + NSBitmapImageRep * bmiRep; + NSPoint savedDragLocation; + char * pixelData; + boolean mouseInClientArea; + boolean titleBarClicked; + boolean gestureEventInProgress; + int width; + int height; + int savedWindowId; + int scrollWheelCount; + + // store state info for some keys + int kdlshift; + int kdrshift; + int kdlctrl; + int kdrctrl; + int kdlalt; + int kdralt; + int kdlmeta; + int kdrmeta; + int kdcapslock; + + @public + boolean isMoveSizeInProgress; + boolean saveInitialDragLoc; + boolean skipMoveWindowOnce; + int localMoveType; +} + +@property (assign) MRDPRailWindow * mrdpRailWindow; +@property (assign) int windowIndex; +@property (assign) boolean activateWindow; + +- (void) windowDidMove:(NSNotification *) notification; +- (void) updateDisplay; +- (void) setRdpInstance:(freerdp *) instance width:(int) w andHeight:(int) h windowID:(int) windowID; +- (BOOL) eventIsInClientArea :(NSEvent *) event :(int *) xptr :(int *) yptr; +- (void) setupBmiRep:(int) width :(int) height; +- (void) releaseResources; + +void mac_rail_MoveWindow(rdpRail *rail, rdpWindow *window); +void apple_to_windowMove(NSRect * r, RAIL_WINDOW_MOVE_ORDER * windowMove); +void mac_send_rail_client_event(rdpChannels *channels, uint16 event_type, void *param); +void windows_to_apple_cords(NSRect * r); +void rail_MoveWindow(rdpRail * rail, rdpWindow * window); +void mac_rail_send_activate(int window_id); + +@end + diff --git a/client/Mac/MRDPRailView.m b/client/Mac/MRDPRailView.m new file mode 100644 index 000000000..ed380e6b1 --- /dev/null +++ b/client/Mac/MRDPRailView.m @@ -0,0 +1,857 @@ +#include "MRDPRailView.h" + +#define USE_RAIL_CVT + +@implementation MRDPRailView + +@synthesize mrdpRailWindow, windowIndex, activateWindow; + +MRDPRailView * g_mrdpRailView; + +struct kkey +{ + int key_code; + int flags; +}; + +extern struct kkey g_keys[]; + +- (void) updateDisplay +{ + boolean moveWindow = NO; + NSRect srcRectOuter; + NSRect destRectOuter; + + rdpGdi * gdi; + + if ((context == 0) || (context->gdi == 0)) + return; + + if (context->gdi->primary->hdc->hwnd->invalid->null) + return; + + if (context->gdi->drawing != context->gdi->primary) + return; + + gdi = context->gdi; + + srcRectOuter = NSMakeRect(0, 0, self->width, self->height); + destRectOuter = [[self window] frame]; + + // cannot be bigger than our current screen size + NSRect screenSize = [[NSScreen mainScreen] frame]; + if (destRectOuter.size.width > screenSize.size.width) { + destRectOuter.size.width = screenSize.size.width; + moveWindow = YES; + } + + if (destRectOuter.size.height > screenSize.size.height) { + destRectOuter.size.height = screenSize.size.height; + moveWindow = YES; + } + + if (destRectOuter.origin.x + destRectOuter.size.width > width) + destRectOuter.size.width = width - destRectOuter.origin.x; + + [self setupBmiRep:destRectOuter.size.width :destRectOuter.size.height]; + + if (moveWindow) { + moveWindow = NO; + RAIL_WINDOW_MOVE_ORDER newWndLoc; + apple_to_windowMove(&destRectOuter, &newWndLoc); + newWndLoc.windowId = savedWindowId; + //skipMoveWindowOnce = TRUE; + //mac_send_rail_client_event(g_mrdpRailView->rdp_instance->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &newWndLoc); + } + + destRectOuter.origin.y = height - destRectOuter.origin.y - destRectOuter.size.height; + rail_convert_color_space(pixelData, (char *) gdi->primary_buffer, + &destRectOuter, self->width, self->height); + + if (moveWindow) + [self setNeedsDisplayInRect:destRectOuter]; + else + [self setNeedsDisplayInRect:[self frame]]; + + gdi->primary->hdc->hwnd->ninvalid = 0; +} + +/** ********************************************************************* + * called when our view needs to be redrawn + ***********************************************************************/ + +- (void) drawRect:(NSRect)dirtyRect +{ + [bmiRep drawInRect:dirtyRect fromRect:dirtyRect operation:NSCompositeCopy fraction:1.0 respectFlipped:NO hints:nil]; + + if (pixelData) { + free(pixelData); + pixelData = NULL; + } + bmiRep = nil; +} + +/** ********************************************************************* + * become first responder so we can get keyboard and mouse events + ***********************************************************************/ + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent +{ + return NO; +} + +/** ********************************************************************* + * called when a mouse move event occurrs + * + * ideally we want to be called when the mouse moves over NSView client area, + * but in reality we get called any time the mouse moves anywhere on the screen; + * we could use NSTrackingArea class to handle this but this class is available + * on Mac OS X v10.5 and higher; since we want to be compatible with older + * versions, we do this manually. + * + * TODO: here is how it can be done using legacy methods + * http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/MouseTrackingEvents/MouseTrackingEvents.html#//apple_ref/doc/uid/10000060i-CH11-SW1 + ***********************************************************************/ + +- (void) mouseMoved:(NSEvent *)event +{ + [super mouseMoved:event]; + + NSRect winFrame = [[self window] frame]; + NSPoint loc = [event locationInWindow]; + + int x = (int) (winFrame.origin.x + loc.x); + int y = (int) (winFrame.origin.y + loc.y); + + y = height - y; + + // send mouse motion event to RDP server + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y); +} + +/** ********************************************************************* + * called when left mouse button is pressed down + ***********************************************************************/ + +- (void)mouseDown:(NSEvent *) event +{ + [super mouseDown:event]; + + NSRect winFrame = [[self window] frame]; + NSPoint loc = [event locationInWindow]; + int x = (int) (winFrame.origin.x + loc.x); + int y = (int) (winFrame.origin.y + loc.y); + int yPos = (int) (winFrame.size.height - loc.y); + + y = height - y; + + + if ((yPos >= 4) && (yPos <= 20)) + titleBarClicked = YES; + else + titleBarClicked = NO; + + savedDragLocation.x = loc.x; + savedDragLocation.y = loc.y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y); +} + +/** ********************************************************************* + * called when left mouse button is released + ***********************************************************************/ + +- (void) mouseUp:(NSEvent *) event +{ + [super mouseUp:event]; + + NSRect winFrame = [[self window] frame]; + NSPoint loc = [event locationInWindow]; + int x = (int) (winFrame.origin.x + loc.x); + int y = (int) (winFrame.origin.y + loc.y); + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON1, x, y); + titleBarClicked = NO; +} + +/** ********************************************************************* + * called when right mouse button is pressed down + ***********************************************************************/ + +- (void) rightMouseDown:(NSEvent *)event +{ + [super rightMouseDown:event]; + + NSRect winFrame = [[self window] frame]; + NSPoint loc = [event locationInWindow]; + int x = (int) (winFrame.origin.x + loc.x); + int y = (int) (winFrame.origin.y + loc.y); + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y); +} + +/** ********************************************************************* + * called when right mouse button is released + ***********************************************************************/ + +- (void) rightMouseUp:(NSEvent *)event +{ + [super rightMouseUp:event]; + + NSRect winFrame = [[self window] frame]; + NSPoint loc = [event locationInWindow]; + int x = (int) (winFrame.origin.x + loc.x); + int y = (int) (winFrame.origin.y + loc.y); + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON2, x, y); +} + +/** ********************************************************************* + * called when middle mouse button is pressed + ***********************************************************************/ + +- (void) otherMouseDown:(NSEvent *)event +{ + [super otherMouseDown:event]; + + NSRect winFrame = [[self window] frame]; + NSPoint loc = [event locationInWindow]; + int x = (int) (winFrame.origin.x + loc.x); + int y = (int) (winFrame.origin.y + loc.y); + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y); +} + +/** ********************************************************************* + * called when middle mouse button is released + ***********************************************************************/ + +- (void) otherMouseUp:(NSEvent *)event +{ + [super otherMouseUp:event]; + + NSRect winFrame = [[self window] frame]; + NSPoint loc = [event locationInWindow]; + int x = (int) (winFrame.origin.x + loc.x); + int y = (int) (winFrame.origin.y + loc.y); + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON3, x, y); +} + +- (void) scrollWheel:(NSEvent *)event +{ + uint16 flags; + + [super scrollWheel:event]; + + // we get more two finger trackpad scroll events + // than scrollWheel events, so we drop some + + if (gestureEventInProgress) { + scrollWheelCount++; + if (scrollWheelCount % 8 != 0) + return; + } + + if ([event scrollingDeltaY] < 0) { + flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; + } + else { + flags = PTR_FLAGS_WHEEL | 0x78; + } + + rdp_instance->input->MouseEvent(rdp_instance->input, flags, 0, 0); +} + +/** ********************************************************************* + * called when mouse is moved with left button pressed + * note: invocation order is: mouseDown, mouseDragged, mouseUp + ***********************************************************************/ +- (void) mouseDragged:(NSEvent *)event +{ + [super mouseDragged:event]; + + NSRect winFrame = [[self window] frame]; + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + if (titleBarClicked) { + // window is being dragged to a new location + int newX = x - savedDragLocation.x; + int newY = y - savedDragLocation.y; + + if ((newX == 0) && (newY == 0)) + return; + + winFrame.origin.x += newX; + winFrame.origin.y += newY; + + [[self window] setFrame:winFrame display:YES]; + return; + } + + if (localMoveType == RAIL_WMSZ_LEFT) { + // left border resize taking place + int diff = (int) (loc.x - savedDragLocation.x); + if (diff == 0) + return; + + if (diff < 0) { + diff = abs(diff); + winFrame.origin.x -= diff; + winFrame.size.width += diff; + } + else { + winFrame.origin.x += diff; + winFrame.size.width -= diff; + } + + [[self window] setFrame:winFrame display:YES]; + return; + } + + if (localMoveType == RAIL_WMSZ_RIGHT) { + // right border resize taking place + int diff = (int) (loc.x - savedDragLocation.x); + if (diff == 0) + return; + + savedDragLocation.x = loc.x; + savedDragLocation.y = loc.y; + + winFrame.size.width += diff; + [[self window] setFrame:winFrame display:YES]; + return; + } + + if (localMoveType == RAIL_WMSZ_TOP) { + // top border resize taking place + int diff = (int) (loc.y - savedDragLocation.y); + if (diff == 0) + return; + + savedDragLocation.x = loc.x; + savedDragLocation.y = loc.y; + + winFrame.size.height += diff; + [[self window] setFrame:winFrame display:YES]; + return; + } + + if (localMoveType == RAIL_WMSZ_BOTTOM) { + // bottom border resize taking place + int diff = (int) (loc.y - savedDragLocation.y); + if (diff == 0) + return; + + if (diff < 0) { + diff = abs(diff); + winFrame.origin.y -= diff; + winFrame.size.height += diff; + } + else { + winFrame.origin.y += diff; + winFrame.size.height -= diff; + } + + [[self window] setFrame:winFrame display:YES]; + return; + } + + if (localMoveType == RAIL_WMSZ_TOPLEFT) { + // top left border resize taking place + int diff = (int) (loc.x - savedDragLocation.x); + if (diff != 0) { + if (diff < 0) { + diff = abs(diff); + winFrame.origin.x -= diff; + winFrame.size.width += diff; + } + else { + winFrame.origin.x += diff; + winFrame.size.width -= diff; + } + } + + diff = (int) (loc.y - savedDragLocation.y); + if (diff != 0) { + savedDragLocation.y = loc.y; + winFrame.size.height += diff; + } + + [[self window] setFrame:winFrame display:YES]; + return; + } + + if (localMoveType == RAIL_WMSZ_TOPRIGHT) { + // top right border resize taking place + int diff = (int) (loc.x - savedDragLocation.x); + if (diff != 0) { + winFrame.size.width += diff; + } + + diff = (int) (loc.y - savedDragLocation.y); + if (diff != 0) { + winFrame.size.height += diff; + } + + savedDragLocation.x = loc.x; + savedDragLocation.y = loc.y; + + [[self window] setFrame:winFrame display:YES]; + return; + } + + if (localMoveType == RAIL_WMSZ_BOTTOMLEFT) { + // bottom left border resize taking place + int diff = (int) (loc.x - savedDragLocation.x); + if (diff != 0) { + if (diff < 0) { + diff = abs(diff); + winFrame.origin.x -= diff; + winFrame.size.width += diff; + } + else { + winFrame.origin.x += diff; + winFrame.size.width -= diff; + } + } + + diff = (int) (loc.y - savedDragLocation.y); + if (diff != 0) { + if (diff < 0) { + diff = abs(diff); + winFrame.origin.y -= diff; + winFrame.size.height += diff; + } + else { + winFrame.origin.y += diff; + winFrame.size.height -= diff; + } + } + + [[self window] setFrame:winFrame display:YES]; + return; + } + + if (localMoveType == RAIL_WMSZ_BOTTOMRIGHT) { + // bottom right border resize taking place + int diff = (int) (loc.x - savedDragLocation.x); + if (diff != 0) { + savedDragLocation.x = loc.x; + //savedDragLocation.y = loc.y; + winFrame.size.width += diff; + } + + diff = (int) (loc.y - savedDragLocation.y); + if (diff != 0) { + if (diff < 0) { + diff = abs(diff); + winFrame.origin.y -= diff; + winFrame.size.height += diff; + } + else { + winFrame.origin.y += diff; + winFrame.size.height -= diff; + } + } + + [[self window] setFrame:winFrame display:YES]; + return; + } + + x = (int) (winFrame.origin.x + loc.x); + y = (int) (winFrame.origin.y + loc.y); + y = height - y; + + // send mouse motion event to RDP server + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y); +} + +/** ********************************************************************* + * called when a key is pressed + ***********************************************************************/ + +- (void) keyDown:(NSEvent *) event +{ + int key; + + key = [event keyCode]; + rdp_instance->input->KeyboardEvent(rdp_instance->input, g_keys[key].flags | KBD_FLAGS_DOWN, g_keys[key].key_code); +} + +/** ********************************************************************* + * called when a key is released + ***********************************************************************/ + +- (void) keyUp:(NSEvent *) event +{ + int key; + + key = [event keyCode]; + rdp_instance->input->KeyboardEvent(rdp_instance->input, g_keys[key].flags | KBD_FLAGS_RELEASE, g_keys[key].key_code); +} + +/** ********************************************************************* + * called when shift, control, alt and meta keys are pressed/released + ***********************************************************************/ + +- (void) flagsChanged:(NSEvent *) event +{ + NSUInteger mf = [event modifierFlags]; + + // caps lock + if (mf == 0x10100) { + printf("TODO: caps lock is on\n"); + kdcapslock = 1; + } + if (kdcapslock && (mf == 0x100)) { + kdcapslock = 0; + printf("TODO: caps lock is off\n"); + } + // left shift + if ((kdlshift == 0) && ((mf & 2) != 0)) { + // left shift went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x2a); + kdlshift = 1; + } + if ((kdlshift != 0) && ((mf & 2) == 0)) { + // left shift went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x2a); + kdlshift = 0; + } + + // right shift + if ((kdrshift == 0) && ((mf & 4) != 0)) { + // right shift went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x36); + kdrshift = 1; + } + if ((kdrshift != 0) && ((mf & 4) == 0)) { + // right shift went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x36); + kdrshift = 0; + } + + // left ctrl + if ((kdlctrl == 0) && ((mf & 1) != 0)) { + // left ctrl went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x1d); + kdlctrl = 1; + } + if ((kdlctrl != 0) && ((mf & 1) == 0)) { + // left ctrl went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x1d); + kdlctrl = 0; + } + + // right ctrl + if ((kdrctrl == 0) && ((mf & 0x2000) != 0)) { + // right ctrl went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x1d); + kdrctrl = 1; + } + if ((kdrctrl != 0) && ((mf & 0x2000) == 0)) { + // right ctrl went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x1d); + kdrctrl = 0; + } + + // left alt + if ((kdlalt == 0) && ((mf & 0x20) != 0)) { + // left alt went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x38); + kdlalt = 1; + } + if ((kdlalt != 0) && ((mf & 0x20) == 0)) { + // left alt went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x38); + kdlalt = 0; + } + + // right alt + if ((kdralt == 0) && ((mf & 0x40) != 0)) { + // right alt went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x38); + kdralt = 1; + } + if ((kdralt != 0) && ((mf & 0x40) == 0)) { + // right alt went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x38); + kdralt = 0; + } + + // left meta + if ((kdlmeta == 0) && ((mf & 0x08) != 0)) { + // left meta went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5b); + kdlmeta = 1; + } + if ((kdlmeta != 0) && ((mf & 0x08) == 0)) { + // left meta went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5b); + kdlmeta = 0; + } + + // right meta + if ((kdrmeta == 0) && ((mf & 0x10) != 0)) { + // right meta went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5c); + kdrmeta = 1; + } + if ((kdrmeta != 0) && ((mf & 0x10) == 0)) { + // right meta went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5c); + kdrmeta = 0; + } +} + +- (void) setRdpInstance:(freerdp *) instance width:(int) w andHeight:(int) h windowID:(int) windowID +{ + rdp_instance = instance; + context = instance->context; + width = w; + height = h; + savedWindowId = windowID; + + NSRect tr = NSMakeRect(0, 0, + [[NSScreen mainScreen] frame].size.width, + [[NSScreen mainScreen] frame].size.height); + + NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:tr options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveAlways owner:self userInfo:nil]; + + [self addTrackingArea:trackingArea]; + + g_mrdpRailView = self; + + [self becomeFirstResponder]; + [self setAcceptsTouchEvents:YES]; + + // we want to be notified when window resizes.... + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:nil]; + + // ...moves + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:nil]; + + // ...and becomes the key window + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:nil]; +} + +- (void) setupBmiRep:(int) frameWidth :(int) frameHeight +{ + struct rgba_data + { + char red; + char green; + char blue; + char alpha; + }; + + if (pixelData) + free(pixelData); + + pixelData = (char *) malloc(frameWidth * frameHeight * sizeof(struct rgba_data)); + bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &pixelData + pixelsWide:frameWidth + pixelsHigh:frameHeight + bitsPerSample:8 + samplesPerPixel:sizeof(struct rgba_data) + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:0 + bytesPerRow:frameWidth * sizeof(struct rgba_data) + bitsPerPixel:0]; +} +- (void) beginGestureWithEvent:(NSEvent *)event +{ + gestureEventInProgress = YES; +} + +- (void) endGestureWithEvent:(NSEvent *)event +{ + gestureEventInProgress = NO; +} + +/** + * called when a bordered window changes size + */ + +- (void) windowDidResize:(NSNotification *) notification +{ + // if we are not the source of this notification, just return + if ([notification object] != [self mrdpRailWindow]) + return; + + // let RDP server know that window has moved + RAIL_WINDOW_MOVE_ORDER windowMove; + NSRect r = [[self window] frame]; + + int diffInHeight = [[self window] frame].size.height - [self frame].size.height; + r.size.height -= diffInHeight; + + apple_to_windowMove(&r, &windowMove); + windowMove.windowId = self->savedWindowId; + mac_send_rail_client_event(self->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &windowMove); +} + +/** + * called when user moves a bordered window + */ + +- (void) windowDidMove:(NSNotification *) notification +{ + // if we are not the source of this notification, just return + if ([notification object] != [self mrdpRailWindow]) + return; + + // let RDP server know that window has moved + RAIL_WINDOW_MOVE_ORDER windowMove; + NSRect r = [[self window] frame]; + + int diffInHeight = [[self window] frame].size.height - [self frame].size.height; + r.size.height -= diffInHeight; + + apple_to_windowMove(&r, &windowMove); + windowMove.windowId = self->savedWindowId; + mac_send_rail_client_event(self->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &windowMove); +} + +/** + * called when a NSWindow becomes the key window + */ + +- (void) windowDidBecomeKey:(NSNotification *) notification +{ + // if we are not the source of this notification, just return + if ([notification object] != [self mrdpRailWindow]) + return; + + if (![self activateWindow]) + return; + + [[self window] setAcceptsMouseMovedEvents: YES]; + + //if ([self activateWindow]) + mac_rail_send_activate(savedWindowId); + + set_current_window(windowIndex); +} + +- (void) releaseResources +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +void rail_cvt_from_rect(char *dest, char *src, NSRect destRect, int destWidth, int destHeight, NSRect srcRect) +{ +} + +/** ********************************************************************* + * color space conversion used specifically in RAIL + ***********************************************************************/ +void rail_convert_color_space(char *destBuf, char * srcBuf, + NSRect * destRect, int width, int height) +{ + int i; + int j; + int numRows; + int srcX; + int srcY; + int destX; + int destY; + int pixelsPerRow; + int pixel; + int pixel1; + int pixel2; + int * src32; + int * dest32; + + int destWidth = destRect->size.width; + int destHeight = destRect->size.height; + + if ((!destBuf) || (!srcBuf)) { + return; + } + + numRows = (destRect->origin.y + destHeight > height) ? height - destRect->origin.y : destHeight; + pixelsPerRow = destWidth; + + srcX = destRect->origin.x; + srcY = destRect->origin.y; + destX = 0; + destY = 0; + + for (i = 0; i < numRows; i++) + { + src32 = (int *) (srcBuf + ((srcY + i) * width + srcX) * 4); + dest32 = (int *) (destBuf + ((destY + i) * destWidth + destX) * 4); + + for (j = 0; j < pixelsPerRow; j++) + { + pixel = *src32; + pixel1 = (pixel & 0x00ff0000) >> 16; + pixel2 = (pixel & 0x000000ff) << 16; + pixel = (pixel & 0xff00ff00) | pixel1 | pixel2; + + *dest32 = pixel; + + src32++; + dest32++; + } + } + + destRect->origin.y = destHeight - destRect->origin.y - destRect->size.height; + return; +} + +/** + * let RDP server know that window has moved + */ + +void rail_MoveWindow(rdpRail * rail, rdpWindow * window) +{ + if (g_mrdpRailView->isMoveSizeInProgress) { + return; + } + + if (g_mrdpRailView->skipMoveWindowOnce) { + g_mrdpRailView->skipMoveWindowOnce = NO; + return; + } + + // this rect is based on Windows co-ordinates... + NSRect r; + r.origin.x = window->windowOffsetX; + r.origin.y = window->windowOffsetY; + r.size.width = window->windowWidth; + r.size.height = window->windowHeight; + + windows_to_apple_cords(&r); + [[g_mrdpRailView window] setFrame:r display:YES]; +} + + +void mac_rail_send_activate(int window_id) +{ + RAIL_ACTIVATE_ORDER activate; + + activate.windowId = window_id; + activate.enabled = 1; + + mac_send_rail_client_event(g_mrdpRailView->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, &activate); +} + +@end + diff --git a/client/Mac/MRDPRailWindow.h b/client/Mac/MRDPRailWindow.h new file mode 100644 index 000000000..629dc819c --- /dev/null +++ b/client/Mac/MRDPRailWindow.h @@ -0,0 +1,13 @@ +// +// MRDPRailWindow.h +// Mac +// +// Created by Laxmikant Rashinkar +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import + +@interface MRDPRailWindow : NSWindow + +@end diff --git a/client/Mac/MRDPRailWindow.m b/client/Mac/MRDPRailWindow.m new file mode 100644 index 000000000..9cab180f4 --- /dev/null +++ b/client/Mac/MRDPRailWindow.m @@ -0,0 +1,18 @@ +// +// MRDPRailWindow.m +// Mac +// +// Created by Laxmikant Rashinkar +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "MRDPRailWindow.h" + +@implementation MRDPRailWindow + +- (BOOL) canBecomeKeyWindow +{ + return YES; +} + +@end diff --git a/client/Mac/MRDPView.h b/client/Mac/MRDPView.h new file mode 100644 index 000000000..fe8b8cbbf --- /dev/null +++ b/client/Mac/MRDPView.h @@ -0,0 +1,177 @@ +// +// MRDPView.h +// MacFreeRDP +// +// Created by Laxmikant Rashinkar +// Copyright (c) 2012 FreeRDP.org All rights reserved. +// + +#import + +typedef int boolean; + +#import "MRDPWindow.h" +#import "freerdp/freerdp.h" +#import "freerdp/types.h" +#import "freerdp/channels/channels.h" +#import "freerdp/gdi/gdi.h" +#import "freerdp/graphics.h" +#import "freerdp/utils/event.h" +#import "freerdp/plugins/cliprdr.h" +#import "freerdp/utils/args.h" +#import "freerdp/rail/rail.h" +#import "freerdp/rail.h" +#import "freerdp/utils/rail.h" + +@interface MRDPView : NSView +{ + CFRunLoopSourceRef run_loop_src; + CFRunLoopSourceRef run_loop_src_channels; + NSBitmapImageRep *bmiRep; + NSMutableArray *cursors; + NSMutableArray *windows; + NSTimer *pasteboard_timer; + NSRect rect; + NSRect prevWinPosition; + freerdp *rdp_instance; + rdpContext *rdp_context; + char *pixel_data; + int width; + int height; + int argc; + int titleBarHeight; + char **argv; + + // RAIL stuff + MRDPWindow *currentWindow; + NSPoint savedDragLocation; + boolean mouseInClientArea; + boolean isRemoteApp; + boolean firstCreateWindow; + boolean isMoveSizeInProgress; + boolean skipResizeOnce; + boolean saveInitialDragLoc; + boolean 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; + +@public + NSWindow *ourMainWindow; + NSPasteboard *pasteboard_rd; // for reading from clipboard + NSPasteboard *pasteboard_wr; // for writing to clipboard + int pasteboard_changecount; + int pasteboard_format; + int is_connected; // true when connected to RDP server +} + +- (void) rdpConnectEror; +- (void) rdpRemoteAppError; +- (void) saveStateInfo :(freerdp *) instance :(rdpContext *) context; +- (void) onPasteboardTimerFired :(NSTimer *) timer; +- (void) my_draw_rect :(void *) context; +- (void) releaseResources; +- (void) setViewSize : (int) width : (int) height; + +@property (assign) int is_connected; + +@end + +/* Pointer Flags */ +#define PTR_FLAGS_WHEEL 0x0200 +#define PTR_FLAGS_WHEEL_NEGATIVE 0x0100 +#define PTR_FLAGS_MOVE 0x0800 +#define PTR_FLAGS_DOWN 0x8000 +#define PTR_FLAGS_BUTTON1 0x1000 +#define PTR_FLAGS_BUTTON2 0x2000 +#define PTR_FLAGS_BUTTON3 0x4000 +#define WheelRotationMask 0x01FF + +void pointer_new(rdpContext* context, rdpPointer* pointer); +void pointer_free(rdpContext* context, rdpPointer* pointer); +void pointer_set(rdpContext* context, rdpPointer* pointer); +void pointer_setNull(rdpContext* context); +void pointer_setDefault(rdpContext* context); +int rdp_connect(); +boolean mac_pre_connect(freerdp *inst); +boolean mac_post_connect(freerdp *inst); +void mac_context_new(freerdp *inst, rdpContext *context); +void mac_context_free(freerdp *inst, rdpContext *context); +void mac_set_bounds(rdpContext *context, rdpBounds *bounds); +void mac_bitmap_update(rdpContext *context, BITMAP_UPDATE *bitmap); +void mac_begin_paint(rdpContext *context); +void mac_end_paint(rdpContext* context); +void mac_save_state_info(freerdp *inst, rdpContext *context); +void skt_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info); +void channel_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info); +int register_fds(int *fds, int count, void *inst); +int invoke_draw_rect(rdpContext *context); +int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data); +int receive_channel_data(freerdp *inst, int chan_id, uint8 *data, int size, int flags, int total_size); +void process_cliprdr_event(freerdp *inst, RDP_EVENT *event); +void cliprdr_process_cb_format_list_event(freerdp *inst, RDP_CB_FORMAT_LIST_EVENT* event); +void cliprdr_send_data_request(freerdp *inst, uint32 format); +void cliprdr_process_cb_monitor_ready_event(freerdp* inst); +void cliprdr_process_cb_data_response_event(freerdp *inst, RDP_CB_DATA_RESPONSE_EVENT *event); +void cliprdr_process_text(freerdp *inst, uint8 *data, int len); +void cliprdr_send_supported_format_list(freerdp *inst); +int register_channel_fds(int *fds, int count, void *inst); + +void mac_process_rail_event(freerdp *inst, RDP_EVENT *event); +void mac_rail_register_callbacks(freerdp *inst, rdpRail *rail); +void mac_rail_CreateWindow(rdpRail *rail, rdpWindow *window); +void mac_rail_MoveWindow(rdpRail *rail, rdpWindow *window); +void mac_rail_ShowWindow(rdpRail *rail, rdpWindow *window, uint8 state); +void mac_rail_SetWindowText(rdpRail *rail, rdpWindow *window); +void mac_rail_SetWindowIcon(rdpRail *rail, rdpWindow *window, rdpIcon *icon); +void mac_rail_SetWindowRects(rdpRail *rail, rdpWindow *window); +void mac_rail_SetWindowVisibilityRects(rdpRail *rail, rdpWindow *window); +void mac_rail_DestroyWindow(rdpRail *rail, rdpWindow *window); +void mac_process_rail_get_sysparams_event(rdpChannels *channels, RDP_EVENT *event); +void mac_send_rail_client_event(rdpChannels *channels, uint16 event_type, void *param); +void mac_on_free_rail_client_event(RDP_EVENT* event); +void mac_process_rail_server_sysparam_event(rdpChannels* channels, RDP_EVENT* event); +void mac_process_rail_exec_result_event(rdpChannels* channels, RDP_EVENT* event); +void mac_rail_enable_remoteapp_mode(); +void mac_process_rail_server_minmaxinfo_event(rdpChannels* channels, RDP_EVENT* event); +void mac_process_rail_server_localmovesize_event(freerdp *inst, RDP_EVENT *event); +void apple_center_window(NSRect * r); +void apple_to_windowMove(NSRect * r, RAIL_WINDOW_MOVE_ORDER * windowMove); + +struct mac_context +{ + // *must* have this - do not delete + rdpContext _p; +}; + +struct cursor +{ + rdpPointer *pointer; + uint8 *cursor_data; // bitmapped pixel data + void *bmiRep; // NSBitmapImageRep + void *nsCursor; // NSCursor + void *nsImage; // NSImage +}; + +struct rgba_data +{ + char red; + char green; + char blue; + char alpha; +}; + +struct kkey +{ + int key_code; + int flags; +}; + diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m new file mode 100644 index 000000000..757e55be0 --- /dev/null +++ b/client/Mac/MRDPView.m @@ -0,0 +1,2314 @@ +// +// MRDPView.m +// MacFreeRDP +// +// Created by Laxmikant Rashinkar +// Copyright (c) 2012 FreeRDP.org All rights reserved. +// + +/* + * TODO + * + provide a UI for configuring optional parameters, but keep cmd line args + * + audio redirection is delayed considerably + * + caps lock key needs to be sent in func flagsChanged() + * + libfreerdp-utils.1.0.dylib needs to be installed to /usr/local/lib + * + * - MRDPView implementation is incomplete + * - all variables should have consistent nameing scheme - camel case + * - all funcs same as above + * - PolygonSc seems to create a transparent rect + * - ensure mouse cursor changes are working ok after moving to NSTracking area + * - RAIL: + * - + * - + * - tool tips to be correctly positioned + * - dragging is slightly of + * - resize after dragging not working + * - dragging app from macbook to monitor gives exec/access err + * - unable to drag rect out of monitor boundaries + * - + * - + * - + */ + +#import "MRDPView.h" +#import "MRDPCursor.h" + +#define RUN_IN_XCODE + +// LK_TODO +#define GOT_HERE //printf("### got here: %s : %s() : %d\n", __FILE__, __func__, __LINE__) + +// RAIL_TODO DELETE WHEN DONE TESTING +#define MRDP_DRAW_INDIVIDUAL_RECTS + +@implementation MRDPView + +MRDPView *g_mrdpview; + +@synthesize is_connected; + +struct kkey g_keys[]; +void convert_color_space(char *dest, char *src, NSRect* drawRect, int width, int height); + +const char* error_code_names[] = +{ + "RAIL_EXEC_S_OK", + "RAIL_EXEC_E_HOOK_NOT_LOADED", + "RAIL_EXEC_E_DECODE_FAILED", + "RAIL_EXEC_E_NOT_IN_ALLOWLIST", + "RAIL_EXEC_E_FILE_NOT_FOUND", + "RAIL_EXEC_E_FAIL", + "RAIL_EXEC_E_SESSION_LOCKED" +}; + +struct kkey g_keys[256] = +{ + { 0x1e, 0 }, // a 0 + { 0x1f, 0 }, // s + { 0x20, 0 }, // d + { 0x21, 0 }, // f + { 0x23, 0 }, // h + { 0x22, 0 }, // g + { 0x2c, 0 }, // z + { 0x2d, 0 }, // x + { 0x2e, 0 }, // c + { 0x2f, 0 }, // v + { 0x00, 0 }, // 10 + { 0x30, 0 }, // b + { 0x10, 0 }, // q + { 0x11, 0 }, // w + { 0x12, 0 }, // e + { 0x13, 0 }, // r + { 0x15, 0 }, // y + { 0x14, 0 }, // t + { 0x02, 0 }, // 1 + { 0x03, 0 }, // 2 + { 0x04, 0 }, // 3 20 + { 0x05, 0 }, // 4 + { 0x07, 0 }, // 6 + { 0x06, 0 }, // 5 + { 0x0d, 0 }, // = or + + { 0x0a, 0 }, // 9 + { 0x08, 0 }, // 7 + { 0x0c, 0 }, // - or _ + { 0x09, 0 }, // 8 + { 0x0b, 0 }, // 0 + { 0x1b, 0 }, // ] or } 30 + { 0x18, 0 }, // o + { 0x16, 0 }, // u + { 0x1a, 0 }, // [ or { + { 0x17, 0 }, // i + { 0x19, 0 }, // p + { 0x1c, 0 }, // enter + { 0x26, 0 }, // l + { 0x24, 0 }, // j + { 0x28, 0 }, // ' or " + { 0x25, 0 }, // k 40 + { 0x27, 0 }, // ; or : + { 0x2b, 0 }, // \ or | + { 0x33, 0 }, // , or < + { 0x35, 0 }, // / or ? + { 0x31, 0 }, // n + { 0x32, 0 }, // m + { 0x34, 0 }, // . or > + { 0x0f, 0 }, // tab + { 0x39, 0 }, // space + { 0x29, 0 }, // ` or ~ 50 + { 0x0e, 0 }, // backspace + { 0x00, 0 }, // + { 0x01, 0 }, // esc + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, // 60 + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x53, 0 }, // KP. + { 0x00, 0 }, + { 0x37, 0 }, // KP* + { 0x00, 0 }, + { 0x4e, 0 }, // KP+ + { 0x00, 0 }, // 70 + { 0x45, 0 }, // num lock + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x35, 1 }, // KP/ + { 0x1c, 1 }, // KPEnter + { 0x00, 0 }, + { 0x4a, 0 }, // KP- + { 0x00, 0 }, + { 0x00, 0 }, // 80 + { 0x00, 0 }, + { 0x52, 0 }, // KP0 + { 0x4f, 0 }, // KP1 + { 0x50, 0 }, // KP2 + { 0x51, 0 }, // KP3 + { 0x4b, 0 }, // KP4 + { 0x4c, 0 }, // KP5 + { 0x4d, 0 }, // KP6 + { 0x47, 0 }, // KP7 + { 0x00, 0 }, // 90 + { 0x48, 0 }, // KP8 + { 0x49, 0 }, // KP9 + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, // 100 + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x5d, 1 }, // menu 110 + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x52, 1 }, // Insert + { 0x47, 1 }, // Home + { 0x49, 1 }, // PgUp + { 0x53, 1 }, // Delete + { 0x00, 0 }, + { 0x4f, 1 }, // End + { 0x00, 0 }, // 120 + { 0x51, 1 }, // PgDown + { 0x3b, 0 }, // f1 + { 0x4b, 1 }, // left + { 0x4d, 1 }, // right + { 0x50, 1 }, // down + { 0x48, 1 }, // up + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, +}; + +/************************************************************************ + methods we override +************************************************************************/ + +/** ********************************************************************* + * create MRDPView with specified rectangle + ***********************************************************************/ + +- (id)initWithFrame:(NSRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + // Initialization code here. + } + + return self; +} + +/** ********************************************************************* + * called when MRDPView has been successfully created from the NIB + ***********************************************************************/ + +- (void) awakeFromNib +{ + g_mrdpview = self; + + // store our window dimensions + width = [self frame].size.width; + height = [self frame].size.height; + titleBarHeight = 22; + + [[self window] becomeFirstResponder]; + [[self window] setAcceptsMouseMovedEvents:YES]; + + cursors = [[NSMutableArray alloc] initWithCapacity:10]; + + firstCreateWindow = TRUE; + skipResizeOnce = YES; + windows = [[NSMutableArray alloc] initWithCapacity:10]; + + // setup a mouse tracking area + NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil]; + + //[self addTrackingArea:trackingArea]; + + // windows in RemoteApp (RAIL) mode cannot have title bars + NSArray * args = [[NSProcessInfo processInfo] arguments]; + for (NSString * str in args) + { + if ([str compare:@"--app"] == NSOrderedSame) { + isRemoteApp = TRUE; + break; + } + } + + if (!isRemoteApp) + [self addTrackingArea:trackingArea]; + + mouseInClientArea = YES; +} + +/** ********************************************************************* + * become first responder so we can get keyboard and mouse events + ***********************************************************************/ + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +/** ********************************************************************* + * called when a mouse move event occurrs + * + * ideally we want to be called when the mouse moves over NSView client area, + * but in reality we get called any time the mouse moves anywhere on the screen; + * we could use NSTrackingArea class to handle this but this class is available + * on Mac OS X v10.5 and higher; since we want to be compatible with older + * versions, we do this manually. + * + * TODO: here is how it can be done using legacy methods + * http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/MouseTrackingEvents/MouseTrackingEvents.html#//apple_ref/doc/uid/10000060i-CH11-SW1 + ***********************************************************************/ + + - (void) mouseMoved:(NSEvent *)event +{ + [super mouseMoved:event]; + + if (!is_connected) + return; + + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + y = height - y; + + // send mouse motion event to RDP server + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y); +} + +/** ********************************************************************* + * called when left mouse button is pressed down + ***********************************************************************/ + +- (void)mouseDown:(NSEvent *) event +{ + [super mouseDown:event]; + + if (!is_connected) + return; + + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y); +} + +/** ********************************************************************* + * called when left mouse button is released + ***********************************************************************/ + +- (void) mouseUp:(NSEvent *) event +{ + [super mouseUp:event]; + + if (!is_connected) + return; + + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON1, x, y); +} + +/** ********************************************************************* + * called when right mouse button is pressed down + ***********************************************************************/ + +- (void) rightMouseDown:(NSEvent *)event +{ + [super rightMouseDown:event]; + + if (!is_connected) + return; + + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y); +} + +/** ********************************************************************* + * called when right mouse button is released + ***********************************************************************/ + +- (void) rightMouseUp:(NSEvent *)event +{ + [super rightMouseUp:event]; + + if (!is_connected) + return; + + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON2, x, y); +} + +/** ********************************************************************* + * called when middle mouse button is pressed + ***********************************************************************/ + +- (void) otherMouseDown:(NSEvent *)event +{ + [super otherMouseDown:event]; + + if (!is_connected) + return; + + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y); +} + +/** ********************************************************************* + * called when middle mouse button is released + ***********************************************************************/ + +- (void) otherMouseUp:(NSEvent *)event +{ + [super otherMouseUp:event]; + + if (!is_connected) + return; + + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + y = height - y; + + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON3, x, y); +} + +- (void) scrollWheel:(NSEvent *)event +{ + uint16 flags; + + [super scrollWheel:event]; + + if (!is_connected) + return; + + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + y = height - y; + + flags = PTR_FLAGS_WHEEL; + if ([event deltaY] < 0) { + flags |= PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; + } + else { + flags |= 0x0078; + } + x += (int) [event deltaX]; + y += (int) [event deltaY]; + rdp_instance->input->MouseEvent(rdp_instance->input, flags, x, y); +} + +/** ********************************************************************* + * called when mouse is moved with left button pressed + * note: invocation order is: mouseDown, mouseDragged, mouseUp + ***********************************************************************/ + +- (void) mouseDragged:(NSEvent *)event +{ + [super mouseDragged:event]; + + if (!is_connected) + return; + + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + // RAIL_TODO delete this if not reqd + if ((isRemoteApp) && (isMoveSizeInProgress)) { + if (saveInitialDragLoc) { + saveInitialDragLoc = NO; + savedDragLocation.x = x; + savedDragLocation.y = y; + return; + } + + int newX = x - savedDragLocation.x; + int newY = y - savedDragLocation.y; + + NSRect r = [[self window] frame]; + r.origin.x += newX; + r.origin.y += newY; + [[g_mrdpview window] setFrame:r display:YES]; + } + + y = height - y; + + // send mouse motion event to RDP server + rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y); +} + +/** ********************************************************************* + * called when a key is pressed + ***********************************************************************/ + +- (void) keyDown:(NSEvent *) event +{ + int key; + + if (!is_connected) { + return; + } + + key = [event keyCode]; + rdp_instance->input->KeyboardEvent(rdp_instance->input, g_keys[key].flags | KBD_FLAGS_DOWN, g_keys[key].key_code); +} + +/** ********************************************************************* + * called when a key is released + ***********************************************************************/ + +- (void) keyUp:(NSEvent *) event +{ + int key; + + if (!is_connected) { + return; + } + + key = [event keyCode]; + rdp_instance->input->KeyboardEvent(rdp_instance->input, g_keys[key].flags | KBD_FLAGS_RELEASE, g_keys[key].key_code); +} + +/** ********************************************************************* + * called when shift, control, alt and meta keys are pressed/released + ***********************************************************************/ + +- (void) flagsChanged:(NSEvent *) event +{ + NSUInteger mf = [event modifierFlags]; + + 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 + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x2a); + kdlshift = 1; + } + if ((kdlshift != 0) && ((mf & 2) == 0)) { + // left shift went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x2a); + kdlshift = 0; + } + + // right shift + if ((kdrshift == 0) && ((mf & 4) != 0)) { + // right shift went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x36); + kdrshift = 1; + } + if ((kdrshift != 0) && ((mf & 4) == 0)) { + // right shift went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x36); + kdrshift = 0; + } + + // left ctrl + if ((kdlctrl == 0) && ((mf & 1) != 0)) { + // left ctrl went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x1d); + kdlctrl = 1; + } + if ((kdlctrl != 0) && ((mf & 1) == 0)) { + // left ctrl went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x1d); + kdlctrl = 0; + } + + // right ctrl + if ((kdrctrl == 0) && ((mf & 0x2000) != 0)) { + // right ctrl went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x1d); + kdrctrl = 1; + } + if ((kdrctrl != 0) && ((mf & 0x2000) == 0)) { + // right ctrl went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x1d); + kdrctrl = 0; + } + + // left alt + if ((kdlalt == 0) && ((mf & 0x20) != 0)) { + // left alt went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x38); + kdlalt = 1; + } + if ((kdlalt != 0) && ((mf & 0x20) == 0)) { + // left alt went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x38); + kdlalt = 0; + } + + // right alt + if ((kdralt == 0) && ((mf & 0x40) != 0)) { + // right alt went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x38); + kdralt = 1; + } + if ((kdralt != 0) && ((mf & 0x40) == 0)) { + // right alt went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x38); + kdralt = 0; + } + + // left meta + if ((kdlmeta == 0) && ((mf & 0x08) != 0)) { + // left meta went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5b); + kdlmeta = 1; + } + if ((kdlmeta != 0) && ((mf & 0x08) == 0)) { + // left meta went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5b); + kdlmeta = 0; + } + + // right meta + if ((kdrmeta == 0) && ((mf & 0x10) != 0)) { + // right meta went down + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5c); + kdrmeta = 1; + } + if ((kdrmeta != 0) && ((mf & 0x10) == 0)) { + // right meta went up + rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5c); + kdrmeta = 0; + } +} + +- (void) releaseResources +{ + int i; + + for (i = 0; i < argc; i++) + { + if (argv[i]) + free(argv[i]); + } + + for (MRDPWindow * w in windows) + { + [w setWindow:nil]; + [w setView:nil]; + } + + if (!is_connected) + return; + + freerdp_channels_global_uninit(); + + if (pixel_data) + free(pixel_data); + + if (run_loop_src != 0) + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), run_loop_src_channels, kCFRunLoopDefaultMode); + + if (run_loop_src != 0) + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), run_loop_src, kCFRunLoopDefaultMode); +} + +/** ********************************************************************* + * called when our view needs refreshing + ***********************************************************************/ + +- (void) drawRect:(NSRect)dirtyRect +{ + if (!rdp_context) + return; + + if (g_mrdpview->isRemoteApp && g_mrdpview->currentWindow) { + return; + } + + if (!bmiRep) { + pixel_data = (char *) malloc(width * height * sizeof(struct rgba_data)); + bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &pixel_data + pixelsWide:width + pixelsHigh:height + bitsPerSample:8 + samplesPerPixel:sizeof(struct rgba_data) + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:0 //NSAlphaFirstBitmapFormat + bytesPerRow:width * sizeof(struct rgba_data) + bitsPerPixel:0]; + } + + [bmiRep drawInRect:dirtyRect fromRect:dirtyRect operation:NSCompositeCopy fraction:1.0 respectFlipped:NO hints:nil]; +} + +/************************************************************************ + instance methods +************************************************************************/ + +/** ********************************************************************* + * called when RDP server wants us to update a rect with new data + ***********************************************************************/ + +- (void) my_draw_rect:(void *)context +{ + int w; + int h; + + rdpContext * ctx = (rdpContext *) context; + + struct rgba_data + { + char red; + char green; + char blue; + char alpha; + }; + + if (isRemoteApp && currentWindow) { + NSRect vrect = [ [currentWindow view] frame]; + [[currentWindow view] setNeedsDisplayInRect:vrect]; + // actual drawing will be done in MRDPRailView:drawRect() + return; + } + + w = width; + h = height; + rect.origin.x = 0; + rect.origin.y = 0; + rect.size.width = w; + rect.size.height = h; + + if (!bmiRep) { + pixel_data = (char *) malloc(w * h * sizeof(struct rgba_data)); + bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &pixel_data + pixelsWide:w + pixelsHigh:h + bitsPerSample:8 + samplesPerPixel:sizeof(struct rgba_data) + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:0 //NSAlphaFirstBitmapFormat + bytesPerRow:w * sizeof(struct rgba_data) + bitsPerPixel:0]; + } + +#ifdef MRDP_DRAW_INDIVIDUAL_RECTS + [self setNeedsDisplayInRect:rect]; + return; +#endif + + convert_color_space(pixel_data, (char *) ctx->gdi->primary_buffer, &rect, w, h); + [self setNeedsDisplayInRect:rect]; +} + +/** ********************************************************************* + * save state info for use by other methods later on + ***********************************************************************/ + +- (void) saveStateInfo:(freerdp *) instance:(rdpContext *) context +{ + rdp_instance = instance; + rdp_context = context; +} + +/** ********************************************************************* + * double check that a mouse event occurred in our client view + ***********************************************************************/ + +- (BOOL) eventIsInClientArea :(NSEvent *) event :(int *) xptr :(int *) yptr +{ + NSPoint loc = [event locationInWindow]; + int x = (int) loc.x; + int y = (int) loc.y; + + if ((x < 0) || (y < 0)) { + if (mouseInClientArea) { + // set default cursor before leaving client area + mouseInClientArea = NO; + NSCursor *cur = [NSCursor arrowCursor]; + [cur set]; + } + return NO; + } + if ((x > width) || (y > height)) { + if (mouseInClientArea) { + // set default cursor before leaving client area + mouseInClientArea = NO; + NSCursor *cur = [NSCursor arrowCursor]; + [cur set]; + } + return NO; + } + + // on Mac origin is at lower left, but we want it on upper left + y = height - y; + + *xptr = x; + *yptr = y; + mouseInClientArea = YES; + return YES; +} + +/** ********************************************************************* + * called when we fail to connect to a RDP server + ***********************************************************************/ + +- (void) rdpConnectError +{ + + NSAlert *alert = [[NSAlert alloc] init]; + [alert setMessageText:@"Error connecting to server"]; + [alert beginSheetModalForWindow:[g_mrdpview window] + modalDelegate:g_mrdpview + didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) + contextInfo:nil]; +} + +/** ********************************************************************* + * called when we fail to launch remote app on RDP server + ***********************************************************************/ + +- (void) rdpRemoteAppError +{ + NSAlert *alert = [[NSAlert alloc] init]; + [alert setMessageText:@"Error starting remote app on specified server"]; + [alert beginSheetModalForWindow:[g_mrdpview window] + modalDelegate:g_mrdpview + didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) + contextInfo:nil]; +} + +/** ********************************************************************* + * just a terminate selector for above call + ***********************************************************************/ + +- (void) alertDidEnd:(NSAlert *)a returnCode:(NSInteger)rc contextInfo:(void *)ci +{ + [NSApp terminate:nil]; +} + +- (void) onPasteboardTimerFired :(NSTimer *) timer +{ + NSArray *types; + int i; + + i = (int) [pasteboard_rd changeCount]; + if (i != pasteboard_changecount) + { + pasteboard_changecount = i; + types = [NSArray arrayWithObject:NSStringPboardType]; + NSString *str = [pasteboard_rd availableTypeFromArray:types]; + if (str != nil) + { + cliprdr_send_supported_format_list(rdp_instance); + } + } +} + +- (void) setViewSize : (int) w : (int) h +{ + // store current dimensions + width = w; + height = h; + + // compute difference between window and client area + NSRect outerRect = [[g_mrdpview window] frame]; + NSRect innerRect = [g_mrdpview frame]; + + int widthDiff = outerRect.size.width - innerRect.size.width; + int heightDiff = outerRect.size.height - innerRect.size.height; + + if (!g_mrdpview->isRemoteApp) { + // we are not in RemoteApp mode, disable resizing + outerRect.size.width = w + widthDiff; + outerRect.size.height = h + heightDiff; + [[g_mrdpview window] setMaxSize:outerRect.size]; + [[g_mrdpview window] setMinSize:outerRect.size]; + [[g_mrdpview window] setFrame:outerRect display:YES]; + + // set client area to specified dimensions + innerRect.size.width = w; + innerRect.size.height = h; + [g_mrdpview setFrame:innerRect]; + + return; + } + + // we are in RemoteApp mode + + outerRect.origin.x = 0; + outerRect.origin.y = 0; + outerRect.size.width = width + widthDiff; + outerRect.size.height = height + heightDiff; + [[g_mrdpview window] setFrame:outerRect display:YES]; + + // set client area to specified dimensions + innerRect.size.width = width; + innerRect.size.height = height; + [g_mrdpview setFrame:innerRect]; + + // main window displays desktop background - hide it + [[g_mrdpview window] orderOut:g_mrdpview]; +} + +// RAIL_TODO is this func required +- (void) windowDidResize:(NSNotification *) notification +{ + RAIL_WINDOW_MOVE_ORDER windowMove; + + printf("RAIL_TODO: MRDPView: windowDidResize() - not yet implemented\n"); + + return; + + // window resize valid only in RemoteApp mode + if (!g_mrdpview->isRemoteApp) + return; + + // window has resized, let server know + + NSRect r = [[g_mrdpview window] frame]; + printf("----- LK_TODO: MRDPView:windowDidResize (%d,%d %dx%d)\n", + (int) r.origin.x, (int) r.origin.y, + (int) r.size.width, (int) r.size.height); + + + windowMove.windowId = [currentWindow windowID]; + + windowMove.left = (uint16) r.origin.x; // x-cordinate of top left corner + windowMove.right = (uint16) (windowMove.left + r.size.width); // x-cordinate of bottom right corner + windowMove.top = (uint16) r.origin.y; // y-cordinate of top left corner + windowMove.bottom = (uint16) (windowMove.top + r.size.height); // y-cordinate of bottom right corner + + printf("----- LK_TODO: MRDPView:windowDidResize windowID=%d left=%d top=%d right=%d bottom=x%d width=%f height=%f\n", + [currentWindow windowID], windowMove.left, windowMove.top, windowMove.right, windowMove.bottom, r.size.width, r.size.height); + + //mac_send_rail_client_event(g_mrdpview->rdp_instance->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &windowMove); +} + +/************************************************************************ + * * + * C functions * + * * + ***********************************************************************/ + +/** ********************************************************************* + * connect to RDP server + * + * @return 0 on success, -1 on failure + ***********************************************************************/ + +int rdp_connect() +{ + freerdp *inst; + int status; + + freerdp_channels_global_init(); + + inst = freerdp_new(); + inst->PreConnect = mac_pre_connect; + inst->PostConnect = mac_post_connect; + inst->context_size = sizeof(struct mac_context); + inst->ContextNew = mac_context_new; + inst->ContextFree = mac_context_free; + inst->ReceiveChannelData = receive_channel_data; + freerdp_context_new(inst); + + status = freerdp_connect(inst); + if(status) { + freerdp_check_fds(inst); + [g_mrdpview setIs_connected:1]; + return 0; + } + [g_mrdpview setIs_connected:0]; + [g_mrdpview rdpConnectError]; + return -1; +} + +/** ********************************************************************* + * a callback given to freerdp_connect() to process the pre-connect operations. + * + * @param inst - pointer to a rdp_freerdp struct that contains the connection's parameters, and + * will be filled with the appropriate informations. + * + * @return true if successful. false otherwise. + ************************************************************************/ + +boolean mac_pre_connect(freerdp *inst) +{ + char *cptr; + int len; + int i; + + inst->settings->offscreen_bitmap_cache = false; + inst->settings->glyph_cache = true; + inst->settings->glyphSupportLevel = GLYPH_SUPPORT_FULL; + inst->settings->order_support[NEG_GLYPH_INDEX_INDEX] = true; + inst->settings->order_support[NEG_FAST_GLYPH_INDEX] = false; + inst->settings->order_support[NEG_FAST_INDEX_INDEX] = false; + inst->settings->order_support[NEG_SCRBLT_INDEX] = true; + inst->settings->order_support[NEG_SAVEBITMAP_INDEX] = false; + + inst->settings->bitmap_cache = true; + inst->settings->order_support[NEG_MEMBLT_INDEX] = true; + inst->settings->order_support[NEG_MEMBLT_V2_INDEX] = true; + inst->settings->order_support[NEG_MEM3BLT_INDEX] = false; + inst->settings->order_support[NEG_MEM3BLT_V2_INDEX] = false; + inst->settings->bitmapCacheV2NumCells = 3; // 5; + inst->settings->bitmapCacheV2CellInfo[0].numEntries = 0x78; // 600; + inst->settings->bitmapCacheV2CellInfo[0].persistent = false; + inst->settings->bitmapCacheV2CellInfo[1].numEntries = 0x78; // 600; + inst->settings->bitmapCacheV2CellInfo[1].persistent = false; + inst->settings->bitmapCacheV2CellInfo[2].numEntries = 0x150; // 2048; + inst->settings->bitmapCacheV2CellInfo[2].persistent = false; + inst->settings->bitmapCacheV2CellInfo[3].numEntries = 0; // 4096; + inst->settings->bitmapCacheV2CellInfo[3].persistent = false; + inst->settings->bitmapCacheV2CellInfo[4].numEntries = 0; // 2048; + inst->settings->bitmapCacheV2CellInfo[4].persistent = false; + + inst->settings->order_support[NEG_MULTIDSTBLT_INDEX] = false; + inst->settings->order_support[NEG_MULTIPATBLT_INDEX] = false; + inst->settings->order_support[NEG_MULTISCRBLT_INDEX] = false; + inst->settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = false; + inst->settings->order_support[NEG_POLYLINE_INDEX] = false; + inst->settings->color_depth = 24; + inst->settings->sw_gdi = 1; + + // setup callbacks + inst->update->BeginPaint = mac_begin_paint; + inst->update->EndPaint = mac_end_paint; + inst->update->SetBounds = mac_set_bounds; + inst->update->BitmapUpdate = mac_bitmap_update; + + NSArray *args = [[NSProcessInfo processInfo] arguments]; + +#ifdef RUN_IN_XCODE + g_mrdpview->argc = 30; +#else + g_mrdpview->argc = (int) [args count]; +#endif + + g_mrdpview->argv = malloc(sizeof(char *) * g_mrdpview->argc); + if (g_mrdpview->argv == NULL) { + return false; + } + +#ifdef RUN_IN_XCODE + + // create our own cmd line args + i = 0; + + NSString *sptr = [args objectAtIndex:0]; + len = [sptr length] + 1; + cptr = (char *) malloc(len); + strcpy(cptr, [sptr UTF8String]); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "-g"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "1280x800"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "--sec"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "rdp"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "--plugin"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "cliprdr"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "--plugin"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "rdpsnd"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "-u"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "lk"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "-p"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "abc@@@123"); + g_mrdpview->argv[i++] = cptr; + +#if 1 + // for RemoteApp (RAIL) testing + cptr = (char *)malloc(80); + strcpy(cptr, "--app"); + g_mrdpview->argv[i++] = cptr; + g_mrdpview->isRemoteApp = TRUE; + + cptr = (char *)malloc(80); + strcpy(cptr, "--plugin"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "rail"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "--data"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "||WordPad"); + g_mrdpview->argv[i++] = cptr; + + cptr = (char *)malloc(80); + strcpy(cptr, "--"); + g_mrdpview->argv[i++] = cptr; +#endif + + cptr = (char *)malloc(80); + strcpy(cptr, "192.168.1.69:45990"); + g_mrdpview->argv[i++] = cptr; + + g_mrdpview->argc = i; + +#else + // MacFreeRDP was not run in Xcode + i = 0; + + // in RemoteApp (RAIL) mode, we connect to RDP server at max screen resolution; + // in order to achieve this, we need to modify the cmd line args entered by the user; + + if (g_mrdpview->isRemoteApp) { + boolean gotGeometry = NO; + + // get dimensions of screen that has keyboard focus; + // we use these dimensions when connecting to RDP server + inst->settings->width = [[NSScreen mainScreen] frame].size.width; + inst->settings->height = [[NSScreen mainScreen] frame].size.height - g_mrdpview->titleBarHeight; + g_mrdpview->width = inst->settings->width; + g_mrdpview->height = inst->settings->height; + + for (NSString * str in args) + { + if (gotGeometry) { + gotGeometry = NO; + cptr = (char *) malloc(20); + sprintf(cptr, "%dx%d", g_mrdpview->width, g_mrdpview->height); + g_mrdpview->argv[i++] = cptr; + continue; + } + + len = (int) ([str length] + 1); + cptr = (char *) malloc(len); + strcpy(cptr, [str UTF8String]); + g_mrdpview->argv[i++] = cptr; + + // -g is the cmd line arg to specify screen resolution/geometry + if ([str compare:@"-g"] == NSOrderedSame) { + gotGeometry = YES; + } + } + } + else { + for (NSString * str in args) + { + len = (int) ([str length] + 1); + cptr = (char *) malloc(len); + strcpy(cptr, [str UTF8String]); + g_mrdpview->argv[i++] = cptr; + } + } +#endif + + freerdp_parse_args(inst->settings, g_mrdpview->argc, g_mrdpview->argv, process_plugin_args, inst->context->channels, NULL, NULL); + if ((strcmp(g_mrdpview->argv[1], "-h") == 0) || (strcmp(g_mrdpview->argv[1], "--help") == 0)) { + [NSApp terminate:nil]; + return true; + } + + [g_mrdpview setViewSize:inst->settings->width :inst->settings->height]; + + freerdp_channels_pre_connect(inst->context->channels, inst); + return true; +} + +/** ********************************************************************* + * a callback registered with freerdp_connect() to perform post-connection operations. + * we get called only if the connection was initialized properly, and will continue + * the initialization based on the newly created connection. + * + * @param inst - pointer to a rdp_freerdp struct + * + * @return true on success, false on failure + * + ************************************************************************/ + +boolean mac_post_connect(freerdp *inst) +{ + uint32 flags; + rdpPointer rdp_pointer; + void *rd_fds[32]; + void *wr_fds[32]; + int rd_count = 0; + int wr_count = 0; + int index; + int fds[32]; + + memset(&rdp_pointer, 0, sizeof(rdpPointer)); + rdp_pointer.size = sizeof(rdpPointer); + rdp_pointer.New = pointer_new; + rdp_pointer.Free = pointer_free; + rdp_pointer.Set = pointer_set; + rdp_pointer.SetNull = pointer_setNull; + rdp_pointer.SetDefault = pointer_setDefault; + + flags = CLRCONV_ALPHA; + flags |= CLRBUF_32BPP; + + gdi_init(inst, flags, NULL); + pointer_cache_register_callbacks(inst->update); + graphics_register_pointer(inst->context->graphics, &rdp_pointer); + + // register file descriptors with the RunLoop + if (!freerdp_get_fds(inst, rd_fds, &rd_count, 0, 0)) + { + printf("mac_post_connect: freerdp_get_fds() failed!\n"); + } + + for (index = 0; index < rd_count; index++) + { + fds[index] = (int)(long)rd_fds[index]; + } + register_fds(fds, rd_count, inst); + + // register channel manager file descriptors with the RunLoop + if (!freerdp_channels_get_fds(inst->context->channels, inst, rd_fds, &rd_count, wr_fds, &wr_count)) + { + printf("ERROR: freerdp_channels_get_fds() failed\n"); + } + for (index = 0; index < rd_count; index++) + { + fds[index] = (int)(long)rd_fds[index]; + } + register_channel_fds(fds, rd_count, inst); + freerdp_channels_post_connect(inst->context->channels, inst); + + // setup RAIL (remote app) + inst->context->rail = rail_new(inst->settings); + rail_register_update_callbacks(inst->context->rail, inst->update); + mac_rail_register_callbacks(inst, inst->context->rail); + + // setup pasteboard (aka clipboard) for copy operations (write only) + g_mrdpview->pasteboard_wr = [NSPasteboard generalPasteboard]; + + // setup pasteboard for read operations + g_mrdpview->pasteboard_rd = [NSPasteboard generalPasteboard]; + g_mrdpview->pasteboard_changecount = (int) [g_mrdpview->pasteboard_rd changeCount]; + g_mrdpview->pasteboard_timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:g_mrdpview selector:@selector(onPasteboardTimerFired:) userInfo:nil repeats:YES]; + + // we want to be notified when window resizes + [[NSNotificationCenter defaultCenter] addObserver:g_mrdpview selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:nil]; + + return true; +} + +/** ********************************************************************* + * create a new mouse cursor + * + * @param context our context state + * @param pointer information about the cursor to create + * + ************************************************************************/ + +void pointer_new(rdpContext* context, rdpPointer* pointer) +{ + MRDPCursor *mrdpCursor = [[MRDPCursor alloc] init]; + uint8 *cursor_data; + + NSRect rect; + rect.size.width = pointer->width; + rect.size.height = pointer->height; + rect.origin.x = pointer->xPos; + rect.origin.y = pointer->yPos; + + cursor_data = (uint8 *) malloc(rect.size.width * rect.size.height * 4); + mrdpCursor->cursor_data = cursor_data; + + freerdp_alpha_cursor_convert(cursor_data, pointer->xorMaskData, pointer->andMaskData, + pointer->width, pointer->height, pointer->xorBpp, context->gdi->clrconv); + + // TODO if xorBpp is > 24 need to call freerdp_image_swap_color_order + // see file df_graphics.c + + // store cursor bitmap image in representation - required by NSImage + NSBitmapImageRep *bmiRep; + bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &cursor_data + pixelsWide:rect.size.width + pixelsHigh:rect.size.height + bitsPerSample:8 + samplesPerPixel:sizeof(struct rgba_data) + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:0 + bytesPerRow:rect.size.width * 4 + bitsPerPixel:0]; + mrdpCursor->bmiRep = bmiRep; + + // create an image using above representation + NSImage *image = [[NSImage alloc] initWithSize:[bmiRep size]]; + [image addRepresentation: bmiRep]; + [image setFlipped:NO]; + mrdpCursor->nsImage = image; + + // need hotspot to create cursor + NSPoint hotSpot; + hotSpot.x = pointer->xPos; + hotSpot.y = pointer->yPos; + + NSCursor *cursor = [[NSCursor alloc] initWithImage: image hotSpot:hotSpot]; + mrdpCursor->nsCursor = cursor; + mrdpCursor->pointer = pointer; + + // save cursor for later use in pointer_set() + NSMutableArray *ma = g_mrdpview->cursors; + [ma addObject:mrdpCursor]; +} + +/** ********************************************************************* + * release resources on specified cursor + ************************************************************************/ + +void pointer_free(rdpContext* context, rdpPointer* pointer) +{ + NSMutableArray *ma = g_mrdpview->cursors; + + for (MRDPCursor *cursor in ma) + { + if (cursor->pointer == pointer) { + cursor->nsImage = nil; + cursor->nsCursor = nil; + cursor->bmiRep = nil; + free(cursor->cursor_data); + [ma removeObject:cursor]; + return; + } + } +} + +/** ********************************************************************* + * set specified cursor as the current cursor + ************************************************************************/ + +void pointer_set(rdpContext* context, rdpPointer* pointer) +{ + NSMutableArray *ma = g_mrdpview->cursors; + + if (!g_mrdpview->mouseInClientArea) + { + return; // not in client area + } + + for (MRDPCursor *cursor in ma) + { + if (cursor->pointer == pointer) { + [cursor->nsCursor set]; + return; + } + } +} + +/** ********************************************************************* + * do not display any mouse cursor + ***********************************************************************/ + +void pointer_setNull(rdpContext* context) +{ +} + +/** ********************************************************************* + * display default mouse cursor + ***********************************************************************/ + +void pointer_setDefault(rdpContext* context) +{ +} + +/** ********************************************************************* + * create a new context - but all we really need to do is save state info + ***********************************************************************/ + +void mac_context_new(freerdp *inst, rdpContext *context) +{ + [g_mrdpview saveStateInfo:inst :context]; + context->channels = freerdp_channels_new(); +} + +/** ********************************************************************* + * we don't do much over here + ***********************************************************************/ + +void mac_context_free(freerdp *inst, rdpContext *context) +{ +} + +/** ********************************************************************* + * clip drawing surface so nothing is drawn outside specified bounds + ***********************************************************************/ + +void mac_set_bounds(rdpContext *context, rdpBounds *bounds) +{ +} + +/** ********************************************************************* + * we don't do much over here + ***********************************************************************/ + +void mac_bitmap_update(rdpContext *context, BITMAP_UPDATE *bitmap) +{ +} + +/** ********************************************************************* + * we don't do much over here + ***********************************************************************/ + +void mac_begin_paint(rdpContext *context) +{ + rdpGdi* gdi = context->gdi; + gdi->primary->hdc->hwnd->invalid->null = 1; +} + +/** ********************************************************************* + * RDP server wants us to draw new data in the view + ***********************************************************************/ + +void mac_end_paint(rdpContext* context) +{ + int i; + NSRect drawRect; + rdpGdi * gdi; + + if ((context == 0) || (context->gdi == 0)) + return; + + if (context->gdi->primary->hdc->hwnd->invalid->null) + return; + + if (context->gdi->drawing != context->gdi->primary) + return; + + gdi = g_mrdpview->rdp_context->gdi; + + if (g_mrdpview->isRemoteApp && g_mrdpview->currentWindow) { + [[g_mrdpview->currentWindow view] updateDisplay]; + return; + } + + for (i = 0; i < gdi->primary->hdc->hwnd->ninvalid; i++) + { + 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; + + convert_color_space(g_mrdpview->pixel_data, (char *) gdi->primary_buffer, &drawRect, g_mrdpview->width, g_mrdpview->height); + + [g_mrdpview setNeedsDisplayInRect:drawRect]; + } + gdi->primary->hdc->hwnd->ninvalid = 0; +} + +/** ********************************************************************* + * called when data is available on a socket + ***********************************************************************/ + +void skt_activity_cb( + CFSocketRef s, + CFSocketCallBackType callbackType, + CFDataRef address, + const void *data, + void *info + ) +{ + if (!freerdp_check_fds(info)) { + // lost connection or did not connect + [NSApp terminate:nil]; + } +} + +/** ********************************************************************* + * called when data is available on a virtual channel + ***********************************************************************/ + +void channel_activity_cb( + CFSocketRef s, + CFSocketCallBackType callbackType, + CFDataRef address, + const void *data, + void *info + ) +{ + freerdp *inst = (freerdp *) info; + RDP_EVENT* event; + + GOT_HERE; + + freerdp_channels_check_fds(inst->context->channels, inst); + event = freerdp_channels_pop_event(inst->context->channels); + if (event) { + switch (event->event_class) + { + case RDP_EVENT_CLASS_RAIL: + mac_process_rail_event(inst, event); + break; + + case RDP_EVENT_CLASS_CLIPRDR: + process_cliprdr_event(inst, event); + break; + } + } +} + +/** ********************************************************************* + * setup callbacks for data availability on sockets + ***********************************************************************/ + +int register_fds(int *fds, int count, void *inst) +{ + int i; + CFSocketRef skt_ref; + CFSocketContext skt_context = { 0, inst, NULL, NULL, NULL }; + + for (i = 0; i < count; i++) + { + skt_ref = CFSocketCreateWithNative(NULL, fds[i], kCFSocketReadCallBack, skt_activity_cb, &skt_context); + g_mrdpview->run_loop_src = CFSocketCreateRunLoopSource(NULL, skt_ref, 0); + CFRunLoopAddSource(CFRunLoopGetCurrent(), g_mrdpview->run_loop_src, kCFRunLoopDefaultMode); + CFRelease(skt_ref); + } + return 0; +} + +/** ********************************************************************* + * setup callbacks for data availability on channels + ***********************************************************************/ + +int register_channel_fds(int *fds, int count, void *inst) +{ + int i; + CFSocketRef skt_ref; + CFSocketContext skt_context = { 0, inst, NULL, NULL, NULL }; + + for (i = 0; i < count; i++) + { + skt_ref = CFSocketCreateWithNative(NULL, fds[i], kCFSocketReadCallBack, channel_activity_cb, &skt_context); + g_mrdpview->run_loop_src_channels = CFSocketCreateRunLoopSource(NULL, skt_ref, 0); + CFRunLoopAddSource(CFRunLoopGetCurrent(), g_mrdpview->run_loop_src_channels, kCFRunLoopDefaultMode); + CFRelease(skt_ref); + } + return 0; +} + +/** ********************************************************************* + * called when channel data is available + ***********************************************************************/ + +int receive_channel_data(freerdp *inst, int chan_id, uint8 *data, int size, int flags, int total_size) +{ + return freerdp_channels_data(inst, chan_id, data, size, flags, total_size); +} + +/** ********************************************************************* + * convert an array containing ARGB data to RGBA + ***********************************************************************/ + +void convert_color_space(char *dest, char *src, NSRect* drawRect, int width, int height) +{ + int i; + int j; + int x; + int y; + int cx; + int cy; + int pixel; + int pixel1; + int pixel2; + int* src32; + int* dst32; + + if ((!dest) || (!src)) { + return; + } + + x = drawRect->origin.x; + y = drawRect->origin.y; + cx = drawRect->size.width; + cy = drawRect->size.height; + + for (j = 0; j < cy; j++) + { + src32 = (int*)(src + ((y + j) * width + x) * 4); + dst32 = (int*)(dest + ((y + j) * width + x) * 4); + for (i = 0; i < cx; i++) + { + pixel = *src32; + pixel1 = (pixel & 0x00ff0000) >> 16; + pixel2 = (pixel & 0x000000ff) << 16; + pixel = (pixel & 0xff00ff00) | pixel1 | pixel2; + *dst32 = pixel; + src32++; + dst32++; + } + } + + drawRect->origin.y = height - drawRect->origin.y - drawRect->size.height; +} + +/** + * Used to load plugins based on the commandline parameters. + * This function is provided as a parameter to freerdp_parse_args(), that will call it + * each time a plugin name is found on the command line. + * This function just calls freerdp_channels_load_plugin() for the given plugin, and always returns 1. + * + * @param settings + * @param name + * @param plugin_data + * @param user_data + * + * @return 1 + */ + +int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data) +{ + rdpChannels* channels = (rdpChannels*) user_data; + + freerdp_channels_load_plugin(channels, settings, name, plugin_data); + return 1; +} + +/* + * stuff related to clipboard redirection + */ + +/** + * remote system has requested clipboard data from local system + */ + +void cliprdr_process_cb_data_request_event(freerdp *inst) +{ + RDP_CB_DATA_RESPONSE_EVENT *event; + NSArray *types; + int len; + + event = (RDP_CB_DATA_RESPONSE_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_DATA_RESPONSE, NULL, NULL); + types = [NSArray arrayWithObject:NSStringPboardType]; + NSString *str = [g_mrdpview->pasteboard_rd availableTypeFromArray:types]; + if (str == nil) + { + event->data = NULL; + event->size = 0; + } + else + { + NSString *data = [g_mrdpview->pasteboard_rd stringForType:NSStringPboardType]; + len = (int) ([data length] * 2 + 2); + event->data = malloc(len); + [data getCString:(char *) event->data maxLength:len encoding:NSUnicodeStringEncoding]; + event->size = len; + } + freerdp_channels_send_event(inst->context->channels, (RDP_EVENT*) event); +} + +void cliprdr_send_data_request(freerdp *inst, uint32 format) +{ + RDP_CB_DATA_REQUEST_EVENT* event; + + event = (RDP_CB_DATA_REQUEST_EVENT *) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_DATA_REQUEST, NULL, NULL); + event->format = format; + freerdp_channels_send_event(inst->context->channels, (RDP_EVENT*) event); +} + +/** + * at the moment, only the following formats are supported + * CB_FORMAT_TEXT + * CB_FORMAT_UNICODETEXT + */ + +void cliprdr_process_cb_data_response_event(freerdp *inst, RDP_CB_DATA_RESPONSE_EVENT *event) +{ + NSString *str; + NSArray *types; + + if (event->size == 0) { + return; + } + + if (g_mrdpview->pasteboard_format == CB_FORMAT_TEXT || g_mrdpview->pasteboard_format == CB_FORMAT_UNICODETEXT) { + str = [[NSString alloc] initWithCharacters:(unichar *) event->data length:event->size / 2]; + types = [[NSArray alloc] initWithObjects:NSStringPboardType, nil]; + [g_mrdpview->pasteboard_wr declareTypes:types owner:g_mrdpview]; + [g_mrdpview->pasteboard_wr setString:str forType:NSStringPboardType]; + } +} + +void cliprdr_process_cb_monitor_ready_event(freerdp* inst) +{ + RDP_EVENT* event; + RDP_CB_FORMAT_LIST_EVENT* format_list_event; + + event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); + + format_list_event = (RDP_CB_FORMAT_LIST_EVENT*)event; + format_list_event->num_formats = 0; + + freerdp_channels_send_event(inst->context->channels, event); +} + +/** + * list of supported clipboard formats; currently only the following are supported + * CB_FORMAT_TEXT + * CB_FORMAT_UNICODETEXT + */ + +void cliprdr_process_cb_format_list_event(freerdp *inst, RDP_CB_FORMAT_LIST_EVENT* event) +{ + int i; + + if (event->num_formats == 0) { + return; + } + + for (i = 0; i < event->num_formats; i++) + { + switch (event->formats[i]) + { + case CB_FORMAT_RAW: + printf("CB_FORMAT_RAW: not yet supported\n"); + break; + + case CB_FORMAT_TEXT: + case CB_FORMAT_UNICODETEXT: + g_mrdpview->pasteboard_format = CB_FORMAT_UNICODETEXT; + cliprdr_send_data_request(inst, CB_FORMAT_UNICODETEXT); + return; + break; + + case CB_FORMAT_DIB: + printf("CB_FORMAT_DIB: not yet supported\n"); + break; + + case CB_FORMAT_HTML: + printf("CB_FORMAT_HTML\n"); + break; + + case CB_FORMAT_PNG: + printf("CB_FORMAT_PNG: not yet supported\n"); + break; + + case CB_FORMAT_JPEG: + printf("CB_FORMAT_JPEG: not yet supported\n"); + break; + + case CB_FORMAT_GIF: + printf("CB_FORMAT_GIF: not yet supported\n"); + break; + } + } +} + +void process_cliprdr_event(freerdp *inst, RDP_EVENT *event) +{ + if (event) { + switch (event->event_type) + { + // Monitor Ready PDU is sent by server to indicate that it has been + // inited and is ready. This PDU is transmitted by the server after it has sent + // Clipboard Capabilities PDU + case RDP_EVENT_TYPE_CB_MONITOR_READY: + cliprdr_process_cb_monitor_ready_event(inst); + break; + + // The Format List PDU is sent either by the client or the server when its + // local system clipboard is updated with new clipboard data. This PDU + // contains the Clipboard Format ID and name pairs of the new Clipboard + // Formats on the clipboard + case RDP_EVENT_TYPE_CB_FORMAT_LIST: + cliprdr_process_cb_format_list_event(inst, (RDP_CB_FORMAT_LIST_EVENT*) event); + break; + + // The Format Data Request PDU is sent by the receipient of the Format List PDU. + // It is used to request the data for one of the formats that was listed in the + // Format List PDU + case RDP_EVENT_TYPE_CB_DATA_REQUEST: + cliprdr_process_cb_data_request_event(inst); + break; + + // The Format Data Response PDU is sent as a reply to the Format Data Request PDU. + // It is used to indicate whether processing of the Format Data Request PDU + // was successful. If the processing was successful, the Format Data Response PDU + // includes the contents of the requested clipboard data + case RDP_EVENT_TYPE_CB_DATA_RESPONSE: + cliprdr_process_cb_data_response_event(inst, (RDP_CB_DATA_RESPONSE_EVENT*) event); + break; + + default: + printf("process_cliprdr_event: unknown event type %d\n", event->event_type); + break; + } + freerdp_event_free(event); + } +} + +void cliprdr_send_supported_format_list(freerdp *inst) +{ + RDP_CB_FORMAT_LIST_EVENT* event; + + event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); + + event->formats = (uint32 *) malloc(sizeof(uint32) * 1); + event->num_formats = 1; + event->formats[0] = CB_FORMAT_UNICODETEXT; + freerdp_channels_send_event(inst->context->channels, (RDP_EVENT*) event); +} + +<<<<<<< HEAD +/**************************************************************************************** + * * + * * + * RemoteApp (RAIL) related stuff goes here * + * * + * * + ****************************************************************************************/ + +void mac_process_rail_event(freerdp *inst, RDP_EVENT *event) +{ + switch (event->event_type) + { + case RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS: + mac_process_rail_get_sysparams_event(inst->context->channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS: + mac_process_rail_exec_result_event(inst->context->channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM: + mac_process_rail_server_sysparam_event(inst->context->channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO: + mac_process_rail_server_minmaxinfo_event(inst->context->channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE: + mac_process_rail_server_localmovesize_event(inst, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP: + GOT_HERE; + //xf_process_rail_appid_resp_event(xfi, channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO: + GOT_HERE; + //xf_process_rail_langbarinfo_event(xfi, channels, event); + break; + } +} + +void mac_rail_CreateWindow(rdpRail *rail, rdpWindow *window) +{ + boolean centerWindow = NO; + boolean moveWindow = NO; + boolean displayAsModal = NO; + NSMutableArray * ma = g_mrdpview->windows; + + // make sure window fits resolution + if (window->windowWidth > g_mrdpview->width) + window->windowWidth = g_mrdpview->width; + + if (window->windowHeight > g_mrdpview->height) + window->windowHeight = g_mrdpview->height; + + // center main window, which is the first to be created + if ([ma count] == 0) { + centerWindow = YES; + moveWindow = YES; + } + + if ((window->extendedStyle & WS_EX_TOPMOST) || (window->extendedStyle & WS_EX_TOOLWINDOW)) { + [g_mrdpview->currentWindow view]->skipMoveWindowOnce = TRUE; + moveWindow = YES; + } + else if (window->style & WS_POPUP) { + centerWindow = YES; + moveWindow = YES; + } + else { + } + + // create NSWindow + NSRect winFrame = NSMakeRect(window->windowOffsetX, window->windowOffsetY, + window->windowWidth, window->windowHeight); + if (centerWindow) + apple_center_window(&winFrame); + + MRDPRailWindow * newWindow = [[MRDPRailWindow alloc] initWithContentRect:winFrame + styleMask:NSTitledWindowMask | NSResizableWindowMask + backing:NSBackingStoreBuffered + defer:NO]; + + // this does not work if specified during window creation in above code + [newWindow setStyleMask:NSBorderlessWindowMask]; + + if (moveWindow) { + // let RDP server know that window has moved + RAIL_WINDOW_MOVE_ORDER windowMove; + apple_to_windowMove(&winFrame, &windowMove); + windowMove.windowId = window->windowId; + mac_send_rail_client_event(g_mrdpview->rdp_instance->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &windowMove); + } + + // create MRDPRailView and add to above window + NSRect viewFrame = NSMakeRect(window->clientOffsetX, window->clientOffsetY, + window->clientAreaWidth, window->clientAreaHeight); + + MRDPRailView * newView = [[MRDPRailView alloc] initWithFrame:viewFrame]; + [newView setRdpInstance:g_mrdpview->rdp_instance width:g_mrdpview->width andHeight:g_mrdpview->height windowID: window->windowId]; + [newWindow setContentView:newView]; + + // save new window + MRDPWindow * mrdpWindow = [[MRDPWindow alloc] init]; + [mrdpWindow setWindowID:window->windowId]; + [mrdpWindow setWindow:newWindow]; + [mrdpWindow setView:newView]; + + // add to list of windows + [ma addObject:mrdpWindow]; + + // make new window current + g_mrdpview->currentWindow = mrdpWindow; + + if (displayAsModal) { + // display as modal window + NSModalSession session = [NSApp beginModalSessionForWindow:newWindow]; + while (1) + { + if ([NSApp runModalSession:session] != NSRunContinuesResponse) + break; + } + [NSApp endModalSession:session]; + } + else { + [newWindow makeKeyAndOrderFront:NSApp]; + [[g_mrdpview window] resignFirstResponder]; + [g_mrdpview resignFirstResponder]; + [[g_mrdpview window] setNextResponder:newWindow]; + } + + return; +} + +void mac_rail_MoveWindow(rdpRail *rail, rdpWindow *window) +{ + if (g_mrdpview->currentWindow) { + rail_MoveWindow(rail, window); + return; + } +} + +void mac_rail_ShowWindow(rdpRail *rail, rdpWindow *window, uint8 state) +{ +} + +void mac_rail_SetWindowText(rdpRail *rail, rdpWindow *window) +{ +} + +void mac_rail_SetWindowIcon(rdpRail *rail, rdpWindow *window, rdpIcon *icon) +{ +} + +void mac_rail_SetWindowRects(rdpRail *rail, rdpWindow *window) +{ +} + +void mac_rail_SetWindowVisibilityRects(rdpRail *rail, rdpWindow *window) +{ +} + +/** ********************************************************************* + * destroy window created in mac_rail_CreateWindow() + ***********************************************************************/ + +void mac_rail_DestroyWindow(rdpRail *rail, rdpWindow *window) +{ + int count = 0; + + for (MRDPWindow * win in g_mrdpview->windows) + { + if ([win windowID] == window->windowId) { + //[[win window] close]; + [win setView:nil]; + [win setWindow:nil]; + [g_mrdpview->windows removeObject:win]; + count = [g_mrdpview->windows count]; + if (count) { + g_mrdpview->currentWindow = [g_mrdpview->windows objectAtIndex:count - 1]; + //[[g_mrdpview window] makeKeyAndOrderFront:[g_mrdpview->currentWindow window]]; + [[g_mrdpview->currentWindow window] makeKeyAndOrderFront:NSApp]; + } + else { + g_mrdpview->currentWindow = nil; + // RAIL_TODO [[g_mrdpview window] makeKeyAndOrderFront:[g_mrdpview window]]; + [NSApp terminate:nil]; + } + return; + } + } +} + +void mac_rail_register_callbacks(freerdp *inst, rdpRail *rail) +{ + GOT_HERE; + + rail->extra = (void *) inst; + rail->rail_CreateWindow = mac_rail_CreateWindow; + rail->rail_MoveWindow = mac_rail_MoveWindow; + rail->rail_ShowWindow = mac_rail_ShowWindow; + rail->rail_SetWindowText = mac_rail_SetWindowText; + rail->rail_SetWindowIcon = mac_rail_SetWindowIcon; + rail->rail_SetWindowRects = mac_rail_SetWindowRects; + rail->rail_SetWindowVisibilityRects = mac_rail_SetWindowVisibilityRects; + rail->rail_DestroyWindow = mac_rail_DestroyWindow; +} + +/** ********************************************************************* + * set work area size, which is the portion of the screen not obscured + * by the system taskbar or by application desktop toolbars + ************************************************************************/ + +void mac_process_rail_get_sysparams_event(rdpChannels *channels, RDP_EVENT *event) +{ + RAIL_SYSPARAM_ORDER * sysparam; + sysparam = (RAIL_SYSPARAM_ORDER *) event->user_data; + + sysparam->workArea.left = 0; + sysparam->workArea.top = 22; + sysparam->workArea.right = g_mrdpview->width; + sysparam->workArea.bottom = g_mrdpview->height - 22; + + sysparam->taskbarPos.left = 0; + sysparam->taskbarPos.top = 0; + sysparam->taskbarPos.right = 0; + sysparam->taskbarPos.bottom = 0; + + sysparam->dragFullWindows = false; + + mac_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, sysparam); +} + +void mac_process_rail_server_sysparam_event(rdpChannels* channels, RDP_EVENT* event) +{ + RAIL_SYSPARAM_ORDER* sysparam = (RAIL_SYSPARAM_ORDER*) event->user_data; + + GOT_HERE; + + switch (sysparam->param) + { + case SPI_SET_SCREEN_SAVE_ACTIVE: + break; + + case SPI_SET_SCREEN_SAVE_SECURE: + break; + } +} + +/** ********************************************************************* + * server returned result of exec'ing remote app on server + ************************************************************************/ + +void mac_process_rail_exec_result_event(rdpChannels* channels, RDP_EVENT* event) +{ + RAIL_EXEC_RESULT_ORDER* exec_result; + + GOT_HERE; + + exec_result = (RAIL_EXEC_RESULT_ORDER*) event->user_data; + + if (exec_result->execResult != RAIL_EXEC_S_OK) { + printf("RAIL exec error: execResult=%s NtError=0x%X\n", + error_code_names[exec_result->execResult], exec_result->rawResult); + g_mrdpview->is_connected = FALSE; + [g_mrdpview rdpRemoteAppError]; + } + else { + mac_rail_enable_remoteapp_mode(); + } +} + +/** ********************************************************************* + * sent by server when a window move or resize on the server is being + * initiated. this PDU contains info about the min and max extents + * to which the window can be moved or sized + ************************************************************************/ + +void mac_process_rail_server_minmaxinfo_event(rdpChannels* channels, RDP_EVENT* event) +{ + RAIL_MINMAXINFO_ORDER * minmax = (RAIL_MINMAXINFO_ORDER*) event->user_data; + +#if 0 + printf("minmax_info: maxPosX=%d maxPosY=%d maxWidth=%d maxHeight=%d minTrackWidth=%d minTrackHeight=%d maxTrackWidth=%d maxTrackHeight=%d\n", + minmax->maxPosX, minmax->maxPosY, minmax->maxWidth, minmax->maxHeight, + minmax->minTrackWidth, minmax->minTrackHeight, minmax->maxTrackWidth, minmax->maxTrackHeight); +#endif +} + +/** ********************************************************************* + * sent by the server when a window on the server is beginning a move or + * resize; use this info to initiate a local move or resize of the + * corresponding local window + ************************************************************************/ + +void mac_process_rail_server_localmovesize_event(freerdp *inst, RDP_EVENT *event) +{ + RAIL_LOCALMOVESIZE_ORDER * moveSize = (RAIL_LOCALMOVESIZE_ORDER *) event->user_data; + RAIL_WINDOW_MOVE_ORDER windowMove; + + switch (moveSize->moveSizeType) { + case RAIL_WMSZ_LEFT: + printf("!!!! RAIL_WMSZ_LEFT\n"); + break; + + case RAIL_WMSZ_RIGHT: + printf("!!!! RAIL_WMSZ_RIGHT\n"); + break; + + case RAIL_WMSZ_TOP: + printf("!!!! RAIL_WMSZ_TOP\n"); + break; + + case RAIL_WMSZ_TOPLEFT: + printf("!!!! RAIL_WMSZ_TOPLEFT\n"); + break; + + case RAIL_WMSZ_TOPRIGHT: + printf("!!!! RAIL_WMSZ_TOPRIGHT\n"); + break; + + case RAIL_WMSZ_BOTTOM: + printf("!!!! RAIL_WMSZ_BOTTOM\n"); + break; + + case RAIL_WMSZ_BOTTOMLEFT: + printf("!!!! RAIL_WMSZ_BOTTOMLEFT\n"); + break; + + case RAIL_WMSZ_BOTTOMRIGHT: + printf("!!!! RAIL_WMSZ_BOTTOMRIGHT\n"); + break; + + case RAIL_WMSZ_MOVE: + if (moveSize->isMoveSizeStart) { + // local window move in progress + [g_mrdpview->currentWindow view]->isMoveSizeInProgress = YES; + [g_mrdpview->currentWindow view]->saveInitialDragLoc = YES; + + return; + } + + // local move has completed + [g_mrdpview->currentWindow view]->isMoveSizeInProgress = NO; + [g_mrdpview->currentWindow view]->saveInitialDragLoc = NO; + + //NSRect rect = [[g_mrdpview->currentWindow view] frame]; + NSRect rect = [[[g_mrdpview->currentWindow view] window] frame]; + + // let RDP server know where this window is located + mac_send_rail_client_event(inst->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &windowMove); + + // the event we just sent will cause an extra MoveWindow() to be invoked which we need to ignore + [g_mrdpview->currentWindow view]->skipMoveWindowOnce = YES; + + break; + + case RAIL_WMSZ_KEYMOVE: + printf("!!!! RAIL_WMSZ_KEYMOVE\n"); + break; + + case RAIL_WMSZ_KEYSIZE: + printf("!!!! RAIL_WMSZ_KEYSIZE\n"); + break; + + default: + break; + } + return; +} + +void mac_send_rail_client_event(rdpChannels *channels, uint16 event_type, void *param) +{ + RDP_EVENT *out_event = NULL; + void *payload = NULL; + + GOT_HERE; + + payload = rail_clone_order(event_type, param); + if (payload != NULL) { + out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type, + mac_on_free_rail_client_event, payload); + freerdp_channels_send_event(channels, out_event); + } +} + +void mac_on_free_rail_client_event(RDP_EVENT* event) +{ + GOT_HERE; + + if (event->event_class == RDP_EVENT_CLASS_RAIL) + { + rail_free_cloned_order(event->event_type, event->user_data); + } +} + +void mac_rail_enable_remoteapp_mode() +{ + GOT_HERE; + + if (!g_mrdpview->isRemoteApp) + g_mrdpview->isRemoteApp = TRUE; +} + +/** + * given a rect with 0,0 at the bottom left (apple cords) + * convert it to a rect with 0,0 at the top left (windows cords) + */ + +void apple_to_windows_cords(NSRect * r) +{ + r->origin.y = g_mrdpview->height - (r->origin.y + r->size.height); +} + +/** + * given a rect with 0,0 at the top left (windows cords) + * convert it to a rect with 0,0 at the bottom left (apple cords) + */ + +void windows_to_apple_cords(NSRect * r) +{ + r->origin.y = g_mrdpview->height - (r->origin.y + r->size.height); +} + +void apple_center_window(NSRect * r) +{ + r->origin.x = (g_mrdpview->width - r->size.width) / 2; + r->origin.y = (g_mrdpview->height - r->size.height) / 2; +} + +void apple_to_windowMove(NSRect * r, RAIL_WINDOW_MOVE_ORDER * windowMove) +{ + windowMove->left = (uint16) r->origin.x; // x-cord of top left corner + windowMove->top = (uint16) g_mrdpview->height - (r->origin.y + r->size.height); // y-cord of top left corner + windowMove->right = (uint16) (windowMove->left + r->size.width); // x-cord of bottom right corner + windowMove->bottom = (uint16) (windowMove->top + r->size.height); // y-cord of bottom right corner +} + +@end diff --git a/client/Mac/MRDPWindow.h b/client/Mac/MRDPWindow.h new file mode 100644 index 000000000..cef1ab09e --- /dev/null +++ b/client/Mac/MRDPWindow.h @@ -0,0 +1,15 @@ + +#import +#import "MRDPRailView.h" +#import "MRDPRailWindow.h" + +@interface MRDPWindow : NSObject +{ +} + +@property (assign) int windowID; +@property (retain) MRDPRailWindow * window; +@property (retain) MRDPRailView * view; + +@end + diff --git a/client/Mac/MRDPWindow.m b/client/Mac/MRDPWindow.m new file mode 100644 index 000000000..77b99728c --- /dev/null +++ b/client/Mac/MRDPWindow.m @@ -0,0 +1,10 @@ + +#include "MRDPWindow.h" + +@implementation MRDPWindow + +@synthesize windowID; +@synthesize window; +@synthesize view; + +@end diff --git a/client/Mac/MainMenu.xib b/client/Mac/MainMenu.xib new file mode 100755 index 000000000..bff95a9d5 --- /dev/null +++ b/client/Mac/MainMenu.xib @@ -0,0 +1,796 @@ + + + + 1070 + 11D50b + 2177 + 1138.32 + 568.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 2177 + + + NSView + NSMenu + NSWindowTemplate + NSMenuItem + NSCustomView + IBNSLayoutConstraint + NSCustomObject + + + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + + + FreeRDP + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + FreeRDP + + + + About FreeRDP + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide FreeRDP + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit FreeRDP + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + + + + Edit + + 1048576 + 2147483647 + + + + + + Format + + 2147483647 + + + + + + View + + 1048576 + 2147483647 + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 2147483647 + + + submenuAction: + + Help + + + + Mac Help + ? + 1048576 + 2147483647 + + + + + _NSHelpMenu + + + + _NSMainMenu + + + 15 + 2 + {{163, 10}, {1024, 768}} + 1954021376 + FreeRDP + NSWindow + + + {1024, 768} + {1024, 768} + + + 256 + + + + 268 + {1024, 768} + + + _NS:9 + MRDPView + + + {1024, 768} + + + + + {{0, 0}, {1366, 746}} + {1024, 790} + {1024, 790} + 128 + YES + + + AppDelegate + + + NSFontManager + + + + + + + terminate: + + + + 449 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + delegate + + + + 568 + + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + performZoom: + + + + 240 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + showHelp: + + + + 493 + + + + mrdpView + + + + 565 + + + + window + + + + 567 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + + + + + + + + + + + + 19 + + + + + + + + 56 + + + + + + + + 217 + + + + + + 83 + + + + + + 57 + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + + + 236 + + + + + 149 + + + + + 145 + + + + + 24 + + + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + + + + 371 + + + + + + + + 372 + + + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + 8 + 29 + 3 + + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + 8 + 29 + 3 + + + + + 4 + 0 + + 4 + 1 + + 0.0 + + 1000 + 8 + 29 + 3 + + + + + 3 + 0 + + 3 + 1 + + 0.0 + + 1000 + 8 + 29 + 3 + + + + + + + 375 + + + + + + 420 + + + + + 490 + + + + + + + + 491 + + + + + + + + 492 + + + + + 494 + + + + + 551 + + + + + 561 + + + + + 562 + + + + + 563 + + + + + 564 + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + com.apple.InterfaceBuilder.CocoaPlugin + {{380, 496}, {480, 360}} + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 568 + + + + + AppDelegate + NSObject + + MRDPView + NSWindow + + + + mrdpView + MRDPView + + + window + NSWindow + + + + IBProjectSource + ./Classes/AppDelegate.h + + + + MRDPView + NSView + + IBProjectSource + ./Classes/MRDPView.h + + + + NSLayoutConstraint + NSObject + + IBProjectSource + ./Classes/NSLayoutConstraint.h + + + + + 0 + IBCocoaFramework + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + YES + 3 + + {11, 11} + {10, 3} + + YES + + diff --git a/client/Mac/README.txt b/client/Mac/README.txt new file mode 100644 index 000000000..e523d02b4 --- /dev/null +++ b/client/Mac/README.txt @@ -0,0 +1,140 @@ + +------------------------------------------------------------------------- + Building FreeRDP on Mac OS X +------------------------------------------------------------------------- + +Platform: Lion with Xcode 4.3.2 + +------------------ + installing cmake +------------------ + +first install macports by googling for it, the run the following command +sudo port install cmake + +---------------- + installing gcc +---------------- +Click on Xcode->Preferences->Downloads +Click on Components +Click on Install Command line tools + +You will be prompted for your Apple Developer userid and password + +---------------------------------------- + download FreeRDP source code using git +---------------------------------------- + +mkdir ~/projects/A8 +cd ~/projects/A8 +git clone git://github.com/FreeRDP/FreeRDP.git + +------------------ + building FreeRDP +------------------ + +cd ~projects/A8/FreeRDP +cmake -DWITH_MACAUDIO=ON -DCMAKE_INSTALL_PREFIX="" +make +make install + +------------------------ + creating Xcode project +------------------------ + +Start xcode +Select 'Create a new xcode project' +In 'Choose a template for your new project', click on Mac OS X -> application +Click on 'Cocoa Application' +Click on next +I used the following: +Product Name: Mac +Company Identifier: com.freerdp +Check 'Automatic Reference Counting' +Create the project in your directory of choice + +------------------------------- + Adding files to your projects +------------------------------- + +Add the following files to your project: + +cd ~/projects/A8/FreeRDP/client/Mac/MRDPCursor.h +cd ~/projects/A8/FreeRDP/client/Mac/MRDPCursor.m +cd ~/projects/A8/FreeRDP/client/Mac/MRDPView.h +cd ~/projects/A8/FreeRDP/client/Mac/MRDPView.m + +This is what your AppDelegate.h file should like like + +#import +#import "MRDPView.h" + +@interface AppDelegate : NSObject + +@property (assign) IBOutlet NSWindow *window; +@property (assign) IBOutlet MRDPView *mrdpView; + +int rdp_connect(); + +@end + +This is what your AppDelegate.m file should like like + +#import "AppDelegate.h" + +@implementation AppDelegate + +@synthesize window = _window; +@synthesize mrdpView; + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + rdp_connect(); +} + +- (void) applicationWillTerminate:(NSNotification *)notification +{ + [mrdpView releaseResources]; +} + +@end + +---------------------------------- + Modifying your MainMenu.xib file +---------------------------------- + +In your project select MainMenu.xib and drag a NSView object intot the main window +Name the class MRDPView +In Interface Builder, select the Application Delegate and tie the mrdpview outlet to the NSView +Set the default size of the main window to 1024x768. This is FreeRDP's default resolution + +---------------------------- + Configuring build settings +---------------------------- + +In Project Navigator, click on Mac +Click on Targets -> Mac +Click on Build Phases +Click on 'Link Binary With Libraries' and click on the + button, then click on the 'Add Other' button to add the following dynamic libraries +~/projects/A8/FreeRDP/libfreerdp-core/libfreerdp-core.dylib +~/projects/A8/FreeRDP/libfreerdp-channels/libfreerdp-channels.dylilb +~/projects/A8/FreeRDP/libfreerdp-utils/libfreerdp-utils.dylib +~/projects/A8/FreeRDP/libfreerdp-codec/libfreerdp-codec.dylib +~/projects/A8/FreeRDP/libfreerdp-cache/libfreerdp-cache.dylib +~/projects/A8/FreeRDP/libfreerdp-gdi/libfreerdp-gdi.dylib + +Click on 'Build Settings' +In 'Search Paths -> Library Search Paths' set the following + Header Search Path Debug: ~/projects/A8/FreeRDP/include + Header Search Path Release: ~/projects/A8/FreeRDP/include + +TODO: in build settings, set strip build product to yes when done debugging + +--------------------------- + To deploy the application +--------------------------- + +in xcode, click on Product->Archive +Click on Distribute button +Select Export As -> application + diff --git a/client/Mac/main.m b/client/Mac/main.m new file mode 100644 index 000000000..a7ee86852 --- /dev/null +++ b/client/Mac/main.m @@ -0,0 +1,14 @@ +// +// main.m +// MacFreeRDP +// +// Created by Thomas Goddard on 5/8/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **)argv); +} diff --git a/client/Windows/CMakeLists.txt b/client/Windows/CMakeLists.txt index 68b46713f..4b05882d5 100644 --- a/client/Windows/CMakeLists.txt +++ b/client/Windows/CMakeLists.txt @@ -1,36 +1,48 @@ -# FreeRDP: A Remote Desktop Protocol Client -# FreeRDP Windows cmake build script -# -# Copyright 2011 O.S. Systems Software Ltda. -# Copyright 2011 Otavio Salvador -# Copyright 2011 Marc-Andre Moreau -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -add_executable(wfreerdp WIN32 - wf_gdi.c - wf_gdi.h - wf_event.c - wf_event.h - wf_graphics.c - wf_graphics.h - wfreerdp.c - wfreerdp.h) - -target_link_libraries(wfreerdp freerdp-core) -target_link_libraries(wfreerdp freerdp-gdi) -target_link_libraries(wfreerdp freerdp-utils) -target_link_libraries(wfreerdp freerdp-codec) -target_link_libraries(wfreerdp freerdp-channels) - -install(TARGETS wfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR}) +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP Windows cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(FREERDP_CLIENT_WINDOWS_SRCS + wf_gdi.c + wf_gdi.h + wf_event.c + wf_event.h + wf_graphics.c + wf_graphics.h + wf_cliprdr.c + wf_cliprdr.h + wf_window.c + wf_window.h + wf_rail.c + wf_rail.h + wfreerdp.c + wfreerdp.h) + +add_executable(wfreerdp WIN32 ${FREERDP_CLIENT_WINDOWS_SRCS}) + +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_CLIENT_WINDOWS_LIBS ${FREERDP_CLIENT_WINDOWS_LIBS} freerdp) +else() + set(FREERDP_CLIENT_WINDOWS_LIBS ${FREERDP_CLIENT_WINDOWS_LIBS} + freerdp-core + freerdp-gdi + freerdp-codec + freerdp-channels + freerdp-utils) +endif() + +target_link_libraries(wfreerdp ${FREERDP_CLIENT_WINDOWS_LIBS}) +install(TARGETS wfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/client/Windows/wf_cliprdr.c b/client/Windows/wf_cliprdr.c new file mode 100644 index 000000000..ca277bc2c --- /dev/null +++ b/client/Windows/wf_cliprdr.c @@ -0,0 +1,110 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows Clipboard Redirection + * + * Copyright 2012 Jason Champion + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "wf_cliprdr.h" + +void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman) +{ + +} + +void wf_cliprdr_uninit(wfInfo* wfi) +{ + +} + +static void wf_cliprdr_process_cb_monitor_ready_event(wfInfo* wfi) +{ + +} + +static void wf_cliprdr_process_cb_data_request_event(wfInfo* wfi, RDP_CB_DATA_REQUEST_EVENT* event) +{ + +} + +static void wf_cliprdr_process_cb_format_list_event(wfInfo* wfi, RDP_CB_FORMAT_LIST_EVENT* event) +{ + +} + +static void wf_cliprdr_process_cb_data_response_event(wfInfo* wfi, RDP_CB_DATA_RESPONSE_EVENT* event) +{ + +} + +void wf_process_cliprdr_event(wfInfo* wfi, RDP_EVENT* event) +{ + switch (event->event_type) + { + case RDP_EVENT_TYPE_CB_MONITOR_READY: + wf_cliprdr_process_cb_monitor_ready_event(wfi); + break; + + case RDP_EVENT_TYPE_CB_FORMAT_LIST: + wf_cliprdr_process_cb_format_list_event(wfi, (RDP_CB_FORMAT_LIST_EVENT*) event); + break; + + case RDP_EVENT_TYPE_CB_DATA_REQUEST: + wf_cliprdr_process_cb_data_request_event(wfi, (RDP_CB_DATA_REQUEST_EVENT*) event); + break; + + case RDP_EVENT_TYPE_CB_DATA_RESPONSE: + wf_cliprdr_process_cb_data_response_event(wfi, (RDP_CB_DATA_RESPONSE_EVENT*) event); + break; + + default: + break; + } +} + +boolean wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + return true; +} + +boolean wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + return true; +} + +boolean wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + return true; +} + +boolean wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + return true; +} + +void wf_cliprdr_check_owner(wfInfo* wfi) +{ + +} + diff --git a/client/Windows/wf_cliprdr.h b/client/Windows/wf_cliprdr.h new file mode 100644 index 000000000..99e38b63f --- /dev/null +++ b/client/Windows/wf_cliprdr.h @@ -0,0 +1,33 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows Clipboard Redirection + * + * Copyright 2012 Jason Champion + * + * 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 __WF_CLIPRDR_H +#define __WF_CLIPRDR_H + +#include "wfreerdp.h" + +void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman); +void wf_cliprdr_uninit(wfInfo* wfi); +void wf_process_cliprdr_event(wfInfo* wfi, RDP_EVENT* event); +boolean wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +boolean wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +boolean wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +boolean wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void wf_cliprdr_check_owner(wfInfo* wfi); + +#endif /* __WF_CLIPRDR_H */ diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index 89edbd0e1..bbdad59a3 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -19,8 +19,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include + #include + #include "wfreerdp.h" #include "wf_event.h" diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index 01ffc868e..bcbe1c6ec 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -19,6 +19,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -237,8 +241,8 @@ void wf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) COLORREF org_textcolor; wfInfo* wfi = ((wfContext*) context)->wfi; - fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfi->srcBpp, 32, wfi->clrconv); - bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfi->srcBpp, 32, wfi->clrconv); + fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); + bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); brush = wf_create_brush(wfi, &patblt->brush, fgcolor, wfi->srcBpp); org_bkmode = SetBkMode(wfi->drawing->hdc, OPAQUE); @@ -279,7 +283,7 @@ void wf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) uint32 brush_color; wfInfo* wfi = ((wfContext*) context)->wfi; - brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfi->srcBpp, 24, wfi->clrconv); + brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); rect.left = opaque_rect->nLeftRect; rect.top = opaque_rect->nTopRect; @@ -306,7 +310,7 @@ void wf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult { rectangle = &multi_opaque_rect->rectangles[i]; - brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfi->srcBpp, 32, wfi->clrconv); + brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); rect.left = rectangle->left; rect.top = rectangle->top; diff --git a/client/Windows/wf_graphics.c b/client/Windows/wf_graphics.c index 0f32aabd2..17d0b85c5 100644 --- a/client/Windows/wf_graphics.c +++ b/client/Windows/wf_graphics.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -45,12 +49,12 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data, bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = negHeight; bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = bpp; + bmi.bmiHeader.biBitCount = wfi->dstBpp; bmi.bmiHeader.biCompression = BI_RGB; bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0); if (data != NULL) - freerdp_image_convert(data, cdata, width, height, bpp, bpp, wfi->clrconv); + freerdp_image_convert(data, cdata, width, height, bpp, wfi->dstBpp, wfi->clrconv); if (pdata != NULL) *pdata = cdata; @@ -157,7 +161,7 @@ void wf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) } void wf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, - uint8* data, int width, int height, int bpp, int length, boolean compressed) + uint8* data, int width, int height, int bpp, int length, boolean compressed, int codec_id) { uint16 size; diff --git a/client/Windows/wf_rail.c b/client/Windows/wf_rail.c new file mode 100644 index 000000000..4dac4a4fb --- /dev/null +++ b/client/Windows/wf_rail.c @@ -0,0 +1,58 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows RAIL + * + * Copyright 2012 Jason Champion + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "wf_window.h" +#include "wf_rail.h" + +void wf_rail_paint(wfInfo* wfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 uright, uint32 ubottom) +{ +} + +void wf_rail_register_callbacks(wfInfo* wfi, rdpRail* rail) +{ +} + +void wf_rail_send_client_system_command(wfInfo* wfi, uint32 windowId, uint16 command) +{ +} + +void wf_rail_send_activate(wfInfo* wfi, HWND window, boolean enabled) +{ +} + +void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, RDP_EVENT* event) +{ +} + +void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window) +{ +} + +void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window) +{ +} diff --git a/client/Windows/wf_rail.h b/client/Windows/wf_rail.h new file mode 100644 index 000000000..82683ef42 --- /dev/null +++ b/client/Windows/wf_rail.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows RAIL + * + * Copyright 2012 Jason Champion + * + * 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 __WF_RAIL_H +#define __WF_RAIL_H + +#include "wfreerdp.h" + +void wf_rail_paint(wfInfo* wfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 uright, uint32 ubottom); +void wf_rail_register_callbacks(wfInfo* wfi, rdpRail* rail); +void wf_rail_send_client_system_command(wfInfo* wfi, uint32 windowId, uint16 command); +void wf_rail_send_activate(wfInfo* wfi, HWND window, boolean enabled); +void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, RDP_EVENT* event); +void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window); +void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window); + +#endif \ No newline at end of file diff --git a/winpr/asn1/asn1.c b/client/Windows/wf_window.c similarity index 75% rename from winpr/asn1/asn1.c rename to client/Windows/wf_window.c index 0dbff7601..9dfc91b6f 100644 --- a/winpr/asn1/asn1.c +++ b/client/Windows/wf_window.c @@ -1,8 +1,8 @@ /** - * WinPR: Windows Portable Runtime - * ASN.1 Encoding & Decoding Engine + * FreeRDP: A Remote Desktop Protocol Client + * Windows RAIL * - * Copyright 2012 Marc-Andre Moreau + * Copyright 2012 Jason Champion * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,8 @@ * limitations under the License. */ -#include - - -#ifndef _WIN32 - - - +#ifdef HAVE_CONFIG_H +#include "config.h" #endif + +#include "wf_window.h" diff --git a/client/Windows/wf_window.h b/client/Windows/wf_window.h new file mode 100644 index 000000000..aeb54f4c6 --- /dev/null +++ b/client/Windows/wf_window.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows RAIL + * + * Copyright 2012 Jason Champion + * + * 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 __WF_WINDOW_H +#define __WF_WINDOW_H + +#include +#include + +#include "wfreerdp.h" + +#endif \ No newline at end of file diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c index 2354aaecc..2fe643dca 100644 --- a/client/Windows/wfreerdp.c +++ b/client/Windows/wfreerdp.c @@ -19,6 +19,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -41,6 +45,7 @@ #include "wf_gdi.h" #include "wf_graphics.h" +#include "wf_cliprdr.h" #include "wfreerdp.h" @@ -383,6 +388,8 @@ boolean wf_post_connect(freerdp* instance) freerdp_channels_post_connect(instance->context->channels, instance); + wf_cliprdr_init(wfi, instance->context->channels); + return true; } diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index 77bc263e2..5ecd0fbaf 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -20,7 +20,7 @@ include(FindXmlto) include_directories(${X11_INCLUDE_DIRS}) -add_executable(xfreerdp +set(FREERDP_CLIENT_X11_SRCS xf_gdi.c xf_gdi.h xf_rail.c @@ -42,6 +42,12 @@ add_executable(xfreerdp xfreerdp.c xfreerdp.h) +add_executable(xfreerdp ${FREERDP_CLIENT_X11_SRCS}) + +set(FREERDP_CLIENT_X11_LIBS + ${X11_LIBRARIES} + ${CMAKE_DL_LIBS}) + if(WITH_MANPAGES) if(XMLTO_FOUND) add_custom_command(OUTPUT xfreerdp.1 @@ -61,38 +67,43 @@ find_suggested_package(Xinerama) if(WITH_XINERAMA) add_definitions(-DWITH_XINERAMA -DWITH_XEXT) include_directories(${XINERAMA_INCLUDE_DIRS}) - target_link_libraries(xfreerdp ${XINERAMA_LIBRARIES}) + set(FREERDP_CLIENT_X11_LIBS ${FREERDP_CLIENT_X11_LIBS} ${XINERAMA_LIBRARIES}) endif() find_suggested_package(Xext) if(WITH_XEXT) add_definitions(-DWITH_XEXT) include_directories(${XEXT_INCLUDE_DIRS}) - target_link_libraries(xfreerdp ${XEXT_LIBRARIES}) + set(FREERDP_CLIENT_X11_LIBS ${FREERDP_CLIENT_X11_LIBS} ${XEXT_LIBRARIES}) endif() find_suggested_package(Xcursor) if(WITH_XCURSOR) add_definitions(-DWITH_XCURSOR) include_directories(${XCURSOR_INCLUDE_DIRS}) - target_link_libraries(xfreerdp ${XCURSOR_LIBRARIES}) + set(FREERDP_CLIENT_X11_LIBS ${FREERDP_CLIENT_X11_LIBS} ${XCURSOR_LIBRARIES}) endif() find_suggested_package(Xv) if(WITH_XV) add_definitions(-DWITH_XV) include_directories(${XV_INCLUDE_DIRS}) - target_link_libraries(xfreerdp ${XV_LIBRARIES}) + set(FREERDP_CLIENT_X11_LIBS ${FREERDP_CLIENT_X11_LIBS} ${XV_LIBRARIES}) endif() include_directories(${CMAKE_SOURCE_DIR}/resources) -target_link_libraries(xfreerdp freerdp-core) -target_link_libraries(xfreerdp freerdp-gdi) -target_link_libraries(xfreerdp freerdp-locale) -target_link_libraries(xfreerdp freerdp-rail) -target_link_libraries(xfreerdp freerdp-channels) -target_link_libraries(xfreerdp freerdp-utils) -target_link_libraries(xfreerdp ${X11_LIBRARIES} ${CMAKE_DL_LIBS}) +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_CLIENT_X11_LIBS ${FREERDP_CLIENT_X11_LIBS} freerdp) +else() + set(FREERDP_CLIENT_X11_LIBS ${FREERDP_CLIENT_X11_LIBS} + freerdp-core + freerdp-gdi + freerdp-locale + freerdp-rail + freerdp-channels + freerdp-utils) +endif() +target_link_libraries(xfreerdp ${FREERDP_CLIENT_X11_LIBS}) install(TARGETS xfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index 700a7d447..982fabab4 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index bb57fc056..9a0e9b2d4 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -366,8 +370,18 @@ static boolean xf_event_FocusIn(xfInfo* xfi, XEvent* event, boolean app) XGrabKeyboard(xfi->display, xfi->window->handle, true, GrabModeAsync, GrabModeAsync, CurrentTime); if (app) - xf_rail_send_activate(xfi, event->xany.window, true); - + { + xf_rail_send_activate(xfi, event->xany.window, true); + + rdpWindow* window; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + + window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window); + + //Update the server with any window changes that occured while the window was not focused. + if (window != NULL) + xf_rail_adjust_position(xfi, window); + } xf_kbd_focus_in(xfi); if (app != true) @@ -506,7 +520,11 @@ static boolean xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, boolean app) (uint32) xfw->handle, xfw->left, xfw->top, xfw->right, xfw->bottom, xfw->width, xfw->height, event->xconfigure.send_event); - if (app && ! event->xconfigure.send_event) + //additonal checks for not in a local move and not ignoring configure to send position update to server, + //also should the window not be focused then do not send to server yet(ie. resizing using window decoration). + //The server will be updated when the window gets refocused. + if (app && (!event->xconfigure.send_event || xfi->window->local_move.state == LMS_NOT_ACTIVE) + && !xfw->rail_ignore_configure && xfi->focused) xf_rail_adjust_position(xfi, window); } @@ -539,7 +557,10 @@ static boolean xf_event_MapNotify(xfInfo* xfi, XEvent* event, boolean app) if (window != NULL) { /* local restore event */ - xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE); + //This is now handled as part of the PropertyNotify + //Doing this here would inhibit the ability to restore a maximized window + //that is minimized back to the maximized state + //xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE); xfWindow *xfw = (xfWindow*) window->extra; xfw->is_mapped = true; } @@ -613,6 +634,92 @@ static boolean xf_event_SelectionClear(xfInfo* xfi, XEvent* event, boolean app) static boolean xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, boolean app) { + //This section handles sending the appropriate commands to the rail server + //when the window has been minimized, maximized, restored locally + //ie. not using the buttons on the rail window itself + if (app == true) + { + rdpWindow* window; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + + window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window); + + if ((((Atom)event->xproperty.atom == xfi->_NET_WM_STATE) && (event->xproperty.state != PropertyDelete)) || + (((Atom)event->xproperty.atom == xfi->WM_STATE) && (event->xproperty.state != PropertyDelete))) + { + boolean status; + boolean maxVert = false; + boolean maxHorz = false; + boolean minimized = false; + unsigned long nitems; + unsigned long bytes; + unsigned char* prop; + int i; + + status = xf_GetWindowProperty(xfi, event->xproperty.window, + xfi->_NET_WM_STATE, 12, &nitems, &bytes, &prop); + + if (status != true) { + DEBUG_X11_LMS("No return _NET_WM_STATE, window is not maximized"); + } + + for (i=0;idisplay, "_NET_WM_STATE_MAXIMIZED_VERT", False)) + { + maxVert = true; + } + + if ((Atom) ((uint16 **)prop)[i] == XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False)) + { + maxHorz = true; + } + } + + XFree(prop); + + status = xf_GetWindowProperty(xfi, event->xproperty.window, + xfi->WM_STATE, 1, &nitems, &bytes, &prop); + + if (status != true) { + DEBUG_X11_LMS("No return WM_STATE, window is not minimized"); + } + else + { + //If the window is in the iconic state + if (((uint32) *prop == 3)) + { + minimized = true; + } + else + minimized = false; + + XFree(prop); + } + + + if (maxVert && maxHorz && !minimized && (xfi->window->rail_state != WINDOW_SHOW_MAXIMIZED)) + { + DEBUG_X11_LMS("Send SC_MAXIMIZE command to rail server."); + xfi->window->rail_state = WINDOW_SHOW_MAXIMIZED; + xf_rail_send_client_system_command(xfi, window->windowId, SC_MAXIMIZE); + } + else if (minimized && (xfi->window->rail_state != WINDOW_SHOW_MINIMIZED)) + { + DEBUG_X11_LMS("Send SC_MINIMIZE command to rail server."); + xfi->window->rail_state = WINDOW_SHOW_MINIMIZED; + xf_rail_send_client_system_command(xfi, window->windowId, SC_MINIMIZE); + } + else if (!minimized && !maxVert && !maxHorz && (xfi->window->rail_state != WINDOW_SHOW)) + { + DEBUG_X11_LMS("Send SC_RESTORE command to rail server"); + xfi->window->rail_state = WINDOW_SHOW; + xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE); + } + } + } + + if (app != true) { if (xf_cliprdr_process_property_notify(xfi, event)) @@ -631,6 +738,15 @@ static boolean xf_event_suppress_events(xfInfo *xfi, rdpWindow *window, XEvent*e { case LMS_NOT_ACTIVE: // No local move in progress, nothing to do + + //Prevent Configure from happening during indeterminant state of Horz or Vert Max only + if ( (event->type == ConfigureNotify) && xfi->window->rail_ignore_configure) + { + DEBUG_X11_LMS("ConfigureNotify Event Ignored"); + xfi->window->rail_ignore_configure = false; + return true; + } + break; case LMS_STARTING: // Local move initiated by RDP server, but we @@ -677,9 +793,11 @@ static boolean xf_event_suppress_events(xfInfo *xfi, rdpWindow *window, XEvent*e case VisibilityNotify: case PropertyNotify: case Expose: + case GravityNotify: // Keep us up to date on position break; default: + DEBUG_X11_LMS("Event Type to break LMS: %s", X11_EVENT_STRINGS[event->type]); // Any other event terminates move xf_rail_end_local_move(xfi, window); break; diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 421306c50..462465e37 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -329,13 +333,14 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) rdpBrush* brush; uint32 foreColor; uint32 backColor; - xfInfo* xfi = ((xfContext*) context)->xfi; + xfContext* context_ = (xfContext*) context; + xfInfo* xfi = context_->xfi; brush = &patblt->brush; xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop)); - foreColor = freerdp_color_convert_rgb(patblt->foreColor, xfi->srcBpp, xfi->bpp, xfi->clrconv); - backColor = freerdp_color_convert_rgb(patblt->backColor, xfi->srcBpp, xfi->bpp, xfi->clrconv); + foreColor = freerdp_color_convert_rgb(patblt->foreColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv); + backColor = freerdp_color_convert_rgb(patblt->backColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv); if (brush->style == GDI_BS_SOLID) { @@ -436,9 +441,10 @@ void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) { uint32 color; - xfInfo* xfi = ((xfContext*) context)->xfi; + xfContext* context_ = (xfContext*) context; + xfInfo* xfi = context_->xfi; - color = freerdp_color_convert_var(opaque_rect->color, xfi->srcBpp, xfi->bpp, xfi->clrconv); + color = freerdp_color_convert_var(opaque_rect->color, context_->settings->color_depth, xfi->bpp, xfi->clrconv); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); @@ -466,9 +472,10 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult int i; uint32 color; DELTA_RECT* rectangle; - xfInfo* xfi = ((xfContext*) context)->xfi; + xfContext* context_ = (xfContext*) context; + xfInfo* xfi = context_->xfi; - color = freerdp_color_convert_var(multi_opaque_rect->color, xfi->srcBpp, xfi->bpp, xfi->clrconv); + color = freerdp_color_convert_var(multi_opaque_rect->color, context_->settings->color_depth, xfi->bpp, xfi->clrconv); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); @@ -503,10 +510,11 @@ void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) { uint32 color; - xfInfo* xfi = ((xfContext*) context)->xfi; + xfContext* context_ = (xfContext*) context; + xfInfo* xfi = context_->xfi; xf_set_rop2(xfi, line_to->bRop2); - color = freerdp_color_convert_rgb(line_to->penColor, xfi->srcBpp, xfi->bpp, xfi->clrconv); + color = freerdp_color_convert_rgb(line_to->penColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv); XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetForeground(xfi->display, xfi->gc, color); @@ -550,10 +558,11 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) uint32 color; XPoint* points; int width, height; - xfInfo* xfi = ((xfContext*) context)->xfi; + xfContext* context_ = (xfContext*) context; + xfInfo* xfi = context_->xfi; xf_set_rop2(xfi, polyline->bRop2); - color = freerdp_color_convert_var(polyline->penColor, xfi->srcBpp, xfi->bpp, xfi->clrconv); + color = freerdp_color_convert_var(polyline->penColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv); XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetForeground(xfi->display, xfi->gc, color); @@ -636,13 +645,14 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) uint32 foreColor; uint32 backColor; Pixmap pattern = 0; - xfInfo* xfi = ((xfContext*) context)->xfi; + xfContext* context_ = (xfContext*) context; + xfInfo* xfi = context_->xfi; brush = &mem3blt->brush; bitmap = (xfBitmap*) mem3blt->bitmap; xf_set_rop3(xfi, gdi_rop3_code(mem3blt->bRop)); - foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, xfi->srcBpp, xfi->bpp, xfi->clrconv); - backColor = freerdp_color_convert_rgb(mem3blt->backColor, xfi->srcBpp, xfi->bpp, xfi->clrconv); + foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv); + backColor = freerdp_color_convert_rgb(mem3blt->backColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv); if (brush->style == GDI_BS_PATTERN) { @@ -711,7 +721,7 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) xfInfo* xfi = ((xfContext*) context)->xfi; xf_set_rop2(xfi, polygon_sc->bRop2); - brush_color = freerdp_color_convert_var(polygon_sc->brushColor, xfi->srcBpp, xfi->bpp, xfi->clrconv); + brush_color = freerdp_color_convert_var(polygon_sc->brushColor, ((xfContext*)context)->settings->color_depth, xfi->bpp, xfi->clrconv); npoints = polygon_sc->numPoints + 1; points = xmalloc(sizeof(XPoint) * npoints); @@ -768,8 +778,8 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) brush = &(polygon_cb->brush); xf_set_rop2(xfi, polygon_cb->bRop2); - foreColor = freerdp_color_convert_rgb(polygon_cb->foreColor, xfi->srcBpp, xfi->bpp, xfi->clrconv); - backColor = freerdp_color_convert_rgb(polygon_cb->backColor, xfi->srcBpp, xfi->bpp, xfi->clrconv); + foreColor = freerdp_color_convert_rgb(polygon_cb->foreColor, ((xfContext*)context)->settings->color_depth, xfi->bpp, xfi->clrconv); + backColor = freerdp_color_convert_rgb(polygon_cb->backColor, ((xfContext*)context)->settings->color_depth, xfi->bpp, xfi->clrconv); npoints = polygon_cb->numPoints + 1; points = xmalloc(sizeof(XPoint) * npoints); diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index b25dc99d1..58c94e366 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -25,6 +29,8 @@ #endif #include +#include +#include #include "xf_graphics.h" @@ -35,7 +41,8 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) uint8* data; Pixmap pixmap; XImage* image; - xfInfo* xfi = ((xfContext*) context)->xfi; + xfContext* context_ = (xfContext*) context; + xfInfo* xfi = context_->xfi; XSetFunction(xfi->display, xfi->gc, GXcopy); pixmap = XCreatePixmap(xfi->display, xfi->drawable, bitmap->width, bitmap->height, xfi->depth); @@ -43,7 +50,7 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) if (bitmap->data != NULL) { data = freerdp_image_convert(bitmap->data, NULL, - bitmap->width, bitmap->height, xfi->srcBpp, xfi->bpp, xfi->clrconv); + bitmap->width, bitmap->height, context_->settings->color_depth, xfi->bpp, xfi->clrconv); if (bitmap->ephemeral != true) { @@ -60,7 +67,7 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) { if (data != bitmap->data) xfree(bitmap->data); - + bitmap->data = data; } } @@ -105,9 +112,17 @@ void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) } void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, - uint8* data, int width, int height, int bpp, int length, boolean compressed) + uint8* data, int width, int height, int bpp, int length, + boolean compressed, int codec_id) { uint16 size; + RFX_MESSAGE* msg; + uint8* src; + uint8* dst; + int yindex; + int xindex; + xfInfo* xfi; + boolean status; size = width * height * (bpp + 7) / 8; @@ -116,20 +131,57 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, else bitmap->data = (uint8*) xrealloc(bitmap->data, size); - if (compressed) + switch (codec_id) { - boolean status; + case CODEC_ID_NSCODEC: + printf("xf_Bitmap_Decompress: nsc not done\n"); + break; + case CODEC_ID_REMOTEFX: + xfi = ((xfContext*)context)->xfi; + rfx_context_set_pixel_format(xfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); + msg = rfx_process_message(xfi->rfx_context, data, length); + if (msg == NULL) + { + printf("xf_Bitmap_Decompress: rfx Decompression Failed\n"); + } + else + { + for (yindex = 0; yindex < height; yindex++) + { + src = msg->tiles[0]->data + yindex * 64 * 4; + dst = bitmap->data + yindex * width * 3; + for (xindex = 0; xindex < width; xindex++) + { + *(dst++) = *(src++); + *(dst++) = *(src++); + *(dst++) = *(src++); + src++; + } + } + rfx_message_free(xfi->rfx_context, msg); + } + break; + case CODEC_ID_JPEG: + if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp)) + { + printf("xf_Bitmap_Decompress: jpeg Decompression Failed\n"); + } + break; + default: + if (compressed) + { + status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); - status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); - - if (status != true) - { - printf("Bitmap Decompression Failed\n"); - } - } - else - { - freerdp_image_flip(data, bitmap->data, width, height, bpp); + if (status == false) + { + printf("xf_Bitmap_Decompress: Bitmap Decompression Failed\n"); + } + } + else + { + freerdp_image_flip(data, bitmap->data, width, height, bpp); + } + break; } bitmap->compressed = false; @@ -270,15 +322,16 @@ void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y) void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor) { - xfInfo* xfi = ((xfContext*) context)->xfi; + xfContext* context_ = (xfContext*) context; + xfInfo* xfi = context_->xfi; bgcolor = (xfi->clrconv->invert)? - freerdp_color_convert_var_bgr(bgcolor, xfi->srcBpp, xfi->bpp, xfi->clrconv): - freerdp_color_convert_var_rgb(bgcolor, xfi->srcBpp, xfi->bpp, xfi->clrconv); + freerdp_color_convert_var_bgr(bgcolor, context_->settings->color_depth, xfi->bpp, xfi->clrconv): + freerdp_color_convert_var_rgb(bgcolor, context_->settings->color_depth, xfi->bpp, xfi->clrconv); fgcolor = (xfi->clrconv->invert)? - freerdp_color_convert_var_bgr(fgcolor, xfi->srcBpp, xfi->bpp, xfi->clrconv): - freerdp_color_convert_var_rgb(fgcolor, xfi->srcBpp, xfi->bpp, xfi->clrconv); + freerdp_color_convert_var_bgr(fgcolor, context_->settings->color_depth, xfi->bpp, xfi->clrconv): + freerdp_color_convert_var_rgb(fgcolor, context_->settings->color_depth, xfi->bpp, xfi->clrconv); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 771f40181..b9382d5cf 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c index eedf715a3..14ce09ab5 100644 --- a/client/X11/xf_monitor.c +++ b/client/X11/xf_monitor.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -117,6 +121,16 @@ boolean xf_detect_monitors(xfInfo* xfi, rdpSettings* settings) vscreen->area.bottom = MAX(vscreen->monitors[i].area.bottom, vscreen->area.bottom); } + //if no monitor information is present then make sure variables are set accordingly + if (settings->num_monitors == 0) + { + vscreen->area.left = 0; + vscreen->area.right = settings->width -1; + vscreen->area.top = 0; + vscreen->area.bottom = settings->height - 1; + } + + if (settings->num_monitors) { settings->width = vscreen->area.right - vscreen->area.left + 1; diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index d4408a5f9..daeef3196 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -39,6 +43,15 @@ void xf_rail_enable_remoteapp_mode(xfInfo* xfi) } } +void xf_rail_disable_remoteapp_mode(xfInfo* xfi) +{ + if (xfi->remote_app == true) + { + xfi->remote_app = false; + xf_create_window(xfi); + } +} + void xf_rail_paint(xfInfo* xfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 uright, uint32 ubottom) { xfWindow* xfw; @@ -64,10 +77,10 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 continue; } - wleft = window->windowOffsetX; - wtop = window->windowOffsetY; - wright = window->windowOffsetX + window->windowWidth - 1; - wbottom = window->windowOffsetY + window->windowHeight - 1; + wleft = window->visibleOffsetX; + wtop = window->visibleOffsetY; + wright = window->visibleOffsetX + window->windowWidth - 1; + wbottom = window->visibleOffsetY + window->windowHeight - 1; ileft = MAX(uleft, wleft); itop = MAX(utop, wtop); @@ -86,6 +99,14 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 } } +void xf_rail_DesktopNonMonitored(rdpRail *rail, rdpWindow* window) +{ + xfInfo* xfi; + xfi = (xfInfo*) rail->extra; + xf_rail_disable_remoteapp_mode(xfi); +} + + static void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window) { xfInfo* xfi; @@ -116,8 +137,28 @@ static void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window) xfi = (xfInfo*) rail->extra; xfw = (xfWindow*) window->extra; + //The rail server like to set the window to a small size when it is minimized even though it is hidden + //in some cases this can cause the window not to restore back to its original size. Therefore we dont update + //our local window when that rail window state is minimized + if (xfw->rail_state == WINDOW_SHOW_MINIMIZED) + return; + + // Do nothing if window is already in the correct position + if ( xfw->left == window->visibleOffsetX && + xfw->top == window->visibleOffsetY && + xfw->width == window->windowWidth && + xfw->height == window->windowHeight) + { + //Just ensure entire window area is updated to + //handle cases where we have drawn locally before getting new bitmap + //from the server + xf_UpdateWindowArea(xfi, xfw, 0, 0, window->windowWidth, window->windowHeight); + return; + } + + xf_MoveWindow(xfi, xfw, - window->windowOffsetX, window->windowOffsetY, + window->visibleOffsetX, window->visibleOffsetY, window->windowWidth, window->windowHeight); } @@ -197,6 +238,7 @@ void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail) rail->rail_SetWindowRects = xf_rail_SetWindowRects; rail->rail_SetWindowVisibilityRects = xf_rail_SetWindowVisibilityRects; rail->rail_DestroyWindow = xf_rail_DestroyWindow; + rail->rail_DesktopNonMonitored = xf_rail_DesktopNonMonitored; } static void xf_on_free_rail_client_event(RDP_EVENT* event) @@ -275,21 +317,39 @@ void xf_rail_adjust_position(xfInfo* xfi, rdpWindow *window) // If current window position disagrees with RDP window position, send // update to RDP server - if ( xfw->left != window->windowOffsetX || - xfw->top != window->windowOffsetY || + if ( xfw->left != window->visibleOffsetX || + xfw->top != window->visibleOffsetY || xfw->width != window->windowWidth || xfw->height != window->windowHeight) { + //Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY, + //we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0 when + //attempting to adjust the rail window. + uint32 offsetX = 0; + uint32 offsetY = 0; + + if (window->windowOffsetX < 0) + offsetX = offsetX - window->windowOffsetX; + + if (window->windowOffsetY < 0) + offsetY = offsetY - window->windowOffsetY; + //windowOffset corresponds to the window location on the rail server + //but our local window is based on the visibleOffset since using the windowOffset + //can result in blank areas for a maximized window window_move.windowId = window->windowId; - window_move.left = xfw->left; - window_move.top = xfw->top; - window_move.right = xfw->right; - window_move.bottom = xfw->bottom; + + //Calculate new offsets for the rail server window + //Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset) + window_move.left = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX); + window_move.top = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY); + + window_move.right = window_move.left + xfw->width; + window_move.bottom = window_move.top + xfw->height; DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%u h=%u" " RDP=0x%X rc={l=%d t=%d} w=%d h=%d", - (uint32) xfw->handle, xfw->left, xfw->top, - xfw->right, xfw->bottom, xfw->width, xfw->height, + (uint32) xfw->handle, window_move.left, window_move.top, + window_move.right, window_move.bottom, xfw->width, xfw->height, window->windowId, window->windowOffsetX, window->windowOffsetY, window->windowWidth, window->windowHeight); @@ -319,14 +379,31 @@ void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window) xfw->left, xfw->top, xfw->right, xfw->bottom, xfw->width, xfw->height); + //Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY, + //we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0 when + //attempting to adjust the rail window. + uint32 offsetX = 0; + uint32 offsetY = 0; + + if (window->windowOffsetX < 0) + offsetX = offsetX - window->windowOffsetX; + + if (window->windowOffsetY < 0) + offsetY = offsetY - window->windowOffsetY; + /* * For keyboard moves send and explicit update to RDP server */ window_move.windowId = window->windowId; - window_move.left = xfw->left; - window_move.top = xfw->top; - window_move.right = xfw->right + 1; // The update to RDP the position is one past the window - window_move.bottom = xfw->bottom + 1; + + //Calculate new offsets for the rail server window + //Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset) + window_move.left = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX); + window_move.top = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY); + + window_move.right = window_move.left + xfw->width; // In the update to RDP the position is one past the window + window_move.bottom = window_move.top + xfw->height; + xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &window_move); @@ -339,13 +416,21 @@ void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window) &root_window, &child_window, &x, &y, &child_x, &child_y, &mask); input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y); + + //only send the mouse coordinates if not a keyboard move or size + if ((xfw->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) && + (xfw->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD)) + { + input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y); + DEBUG_X11_LMS("Mouse coordinates. x= %i, y= %i", x, y); + } // Proactively update the RAIL window dimensions. There is a race condition where // we can start to receive GDI orders for the new window dimensions before we // receive the RAIL ORDER for the new window size. This avoids that race condition. - window->windowOffsetX = xfw->left; - window->windowOffsetY = xfw->top; + window->windowOffsetX = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX); + window->windowOffsetY = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY); window->windowWidth = xfw->width; window->windowHeight = xfw->height; diff --git a/client/X11/xf_tsmf.c b/client/X11/xf_tsmf.c index 7256aae4c..61e5e4382 100644 --- a/client/X11/xf_tsmf.c +++ b/client/X11/xf_tsmf.c @@ -17,15 +17,22 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include + #include #include #include #include + #include #include #include diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index e93d75ef8..a2e2677ea 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -18,11 +18,18 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include +#include +#include + #include #include #include -#include + #include #include @@ -235,7 +242,7 @@ void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, uint32 style, uint32 ex_st { Atom window_type; - if ((ex_style & WS_EX_TOPMOST) || (ex_style & WS_EX_TOOLWINDOW)) + if (/*(ex_style & WS_EX_TOPMOST) ||*/ (ex_style & WS_EX_TOOLWINDOW)) { /* * Tooltips and menu items should be unmanaged windows @@ -254,6 +261,12 @@ void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, uint32 style, uint32 ex_st xf_SetWindowUnlisted(xfi, window); window_type = xfi->_NET_WM_WINDOW_TYPE_POPUP; } + //TOPMOST window that is not a toolwindow is treated like a regular window(ie. task manager). + //Want to do this here, since the window may have type WS_POPUP + else if (ex_style & WS_EX_TOPMOST) + { + window_type = xfi->_NET_WM_WINDOW_TYPE_NORMAL; + } else if (style & WS_POPUP) { /* this includes dialogs, popups, etc, that need to be full-fledged windows */ @@ -276,6 +289,19 @@ void xf_SetWindowText(xfInfo *xfi, xfWindow* window, char *name) XStoreName(xfi->display, window->handle, name); } +static void xf_SetWindowPID(xfInfo* xfi, xfWindow* window, pid_t pid) +{ + Atom am_wm_pid; + + if (pid == 0) + pid = getpid(); + + am_wm_pid = XInternAtom(xfi->display, "_NET_WM_PID", False); + + XChangeProperty(xfi->display, window->handle, am_wm_pid, XA_CARDINAL, + 32, PropModeReplace, (unsigned char *)&pid, 1); +} + xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, boolean decorations) { xfWindow* window; @@ -297,7 +323,7 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, window->is_transient = false; window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen), - xfi->workArea.x, xfi->workArea.y, xfi->width, xfi->height, 0, xfi->depth, InputOutput, xfi->visual, + xfi->workArea.x, xfi->workArea.y, xfi->workArea.width, xfi->workArea.height, 0, xfi->depth, InputOutput, xfi->visual, CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | CWBorderPixel | CWWinGravity | CWBitGravity, &xfi->attribs); @@ -331,6 +357,7 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, xf_ResizeDesktopWindow(xfi, window, width, height); xf_SetWindowDecorations(xfi, window, decorations); + xf_SetWindowPID(xfi, window, 0); input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | @@ -358,6 +385,13 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, XMaskEvent(xfi->display, VisibilityChangeMask, &xevent); } while (xevent.type != VisibilityNotify); + + //The XCreateWindow call will start the window in the upper-left corner of our current + //monitor instead of the upper-left monitor for remote app mode(which uses all monitors). + //This extra call after the window is mapped will position the login window correctly + if (xfi->instance->settings->remote_app) + XMoveWindow(xfi->display, window->handle, 0, 0); + } xf_SetWindowText(xfi, window, name); @@ -446,6 +480,8 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width, window->local_move.state = LMS_NOT_ACTIVE; window->is_mapped = false; window->is_transient = false; + window->rail_state = 0; + window->rail_ignore_configure = false; window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen), x, y, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual, @@ -473,6 +509,14 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width, xfree(class); } + //Set the input mode hint for the WM + XWMHints *InputModeHint = XAllocWMHints(); + InputModeHint->flags = (1L << 0); + InputModeHint->input = True; + XSetWMHints(xfi->display, window->handle, InputModeHint); + XFree(InputModeHint); + + XSetWMProtocols(xfi->display, window->handle, &(xfi->WM_DELETE_WINDOW), 1); input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | @@ -488,6 +532,7 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width, xf_SetWindowDecorations(xfi, window, window->decorations); xf_SetWindowStyle(xfi, window, wnd->style, wnd->extendedStyle); + xf_SetWindowPID(xfi, window, 0); xf_ShowWindow(xfi, window, WINDOW_SHOW); XMapWindow(xfi->display, window->handle); @@ -544,6 +589,7 @@ void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x, window->local_move.root_x = x; window->local_move.root_y = y; window->local_move.state = LMS_STARTING; + window->local_move.direction = direction; XUngrabPointer(xfi->display, CurrentTime); @@ -644,11 +690,37 @@ void xf_ShowWindow(xfInfo* xfi, xfWindow* window, uint8 state) break; case WINDOW_SHOW_MAXIMIZED: - XRaiseWindow(xfi->display, window->handle); + //Set the window as maximized + xf_SendClientEvent(xfi, window, xfi->_NET_WM_STATE, 4, + 1, + XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_VERT", False), + XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), + 0); + + //This is a workaround for the case where the window is maximized locally before the rail server is told to maximize + //the window, this appears to be a race condition where the local window with incomplete data and once the window is + //actually maximized on the server - an update of the new areas may not happen. So, we simply to do a full update of + //the entire window once the rail server notifies us that the window is now maximized. + if (window->rail_state == WINDOW_SHOW_MAXIMIZED) + xf_UpdateWindowArea(xfi, window, 0, 0, window->window->windowWidth, window->window->windowHeight); break; case WINDOW_SHOW: - XMapWindow(xfi->display, window->handle); + //Ensure the window is not maximized + xf_SendClientEvent(xfi, window, xfi->_NET_WM_STATE, 4, + 0, + XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_VERT", False), + XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), + 0); + + //Ignore configure requests until both the Maximized properties have been processed + //to prevent condition where WM overrides size of request due to one or both of these properties + //still being set - which causes a position adjustment to be sent back to the server + //thus causing the window to not return to its original size + if (window->rail_state == WINDOW_SHOW_MAXIMIZED) + window->rail_ignore_configure = true; + + if (window->is_transient) { xf_SetWindowUnlisted(xfi, window); @@ -656,6 +728,9 @@ void xf_ShowWindow(xfInfo* xfi, xfWindow* window, uint8 state) break; } + //Save off the current rail state of this window + window->rail_state = state; + XFlush(xfi->display); } @@ -713,7 +788,8 @@ void xf_SetWindowRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int n } #ifdef WITH_XEXT - XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0); + //This is currently unsupported with the new logic to handle window placement with VisibleOffset variables + //XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0); #endif xfree(xrects); @@ -738,7 +814,8 @@ void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* re } #ifdef WITH_XEXT - XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0); + //This is currently unsupported with the new logic to handle window placement with VisibleOffset variables + //XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0); #endif xfree(xrects); @@ -750,15 +827,30 @@ void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width, rdpWindow* wnd; wnd = window->window; - ax = x + wnd->windowOffsetX; - ay = y + wnd->windowOffsetY; + //Remote app mode uses visibleOffset instead of windowOffset + if (!xfi->remote_app) + { + ax = x + wnd->windowOffsetX; + ay = y + wnd->windowOffsetY; - if (ax + width > wnd->windowOffsetX + wnd->windowWidth) - width = (wnd->windowOffsetX + wnd->windowWidth - 1) - ax; + if (ax + width > wnd->windowOffsetX + wnd->windowWidth) + width = (wnd->windowOffsetX + wnd->windowWidth - 1) - ax; - if (ay + height > wnd->windowOffsetY + wnd->windowHeight) - height = (wnd->windowOffsetY + wnd->windowHeight - 1) - ay; + if (ay + height > wnd->windowOffsetY + wnd->windowHeight) + height = (wnd->windowOffsetY + wnd->windowHeight - 1) - ay; + } + else + { + ax = x + wnd->visibleOffsetX; + ay = y + wnd->visibleOffsetY; + if (ax + width > wnd->visibleOffsetX + wnd->windowWidth) + width = (wnd->visibleOffsetX + wnd->windowWidth - 1) - ax; + + if (ay + height > wnd->visibleOffsetY + wnd->windowHeight) + height = (wnd->visibleOffsetY + wnd->windowHeight - 1) - ay; + } + if (xfi->sw_gdi) { XPutImage(xfi->display, xfi->primary, window->gc, xfi->image, diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index 760838c7a..f77795dbb 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -58,6 +58,7 @@ struct xf_localmove int window_x; // relative to window int window_y; enum xf_localmove_state state; + int direction; }; struct xf_window @@ -76,6 +77,8 @@ struct xf_window boolean is_mapped; boolean is_transient; xfLocalMove local_move; + uint8 rail_state; + boolean rail_ignore_configure; }; void xf_ewmhints_init(xfInfo* xfi); @@ -102,10 +105,12 @@ void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width, boolean xf_IsWindowBorder(xfInfo* xfi, xfWindow* xfw, int x, int y); void xf_DestroyWindow(xfInfo* xfi, xfWindow* window); +boolean xf_GetWindowProperty(xfInfo* xfi, Window window, Atom property, int length, + unsigned long* nitems, unsigned long* bytes, uint8** prop); + void xf_SetWindowMinMaxInfo(xfInfo* xfi, xfWindow* window, int maxWidth, int maxHeight, int maxPosX, int maxPosY, int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight); - void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x, int y); void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window); void xf_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int numArgs, ...); diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index a0e69eb84..232d6e048 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -40,6 +44,7 @@ #include #include #include + #include #include #include @@ -299,8 +304,8 @@ void xf_create_window(xfInfo* xfi) xfi->attribs.backing_store = xfi->primary ? NotUseful : Always; xfi->attribs.override_redirect = xfi->fullscreen; xfi->attribs.colormap = xfi->colormap; - xfi->attribs.bit_gravity = ForgetGravity; - xfi->attribs.win_gravity = StaticGravity; + xfi->attribs.bit_gravity = NorthWestGravity; + xfi->attribs.win_gravity = NorthWestGravity; if (xfi->instance->settings->window_title != NULL) { @@ -583,6 +588,7 @@ boolean xf_pre_connect(freerdp* instance) xfi->WM_PROTOCOLS = XInternAtom(xfi->display, "WM_PROTOCOLS", False); xfi->WM_DELETE_WINDOW = XInternAtom(xfi->display, "WM_DELETE_WINDOW", False); + xfi->WM_STATE = XInternAtom(xfi->display, "WM_STATE", False); xf_kbd_init(xfi); diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 82fcec3dc..1a2d673b4 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -20,7 +20,10 @@ #ifndef __XFREERDP_H #define __XFREERDP_H +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include @@ -160,10 +163,12 @@ struct xf_info Atom _NET_WM_MOVERESIZE; Atom _NET_MOVERESIZE_WINDOW; + Atom WM_STATE; Atom WM_PROTOCOLS; Atom WM_DELETE_WINDOW; }; +void xf_create_window(xfInfo* xfi); void xf_toggle_fullscreen(xfInfo* xfi); boolean xf_post_connect(freerdp* instance); diff --git a/client/test/CMakeLists.txt b/client/test/CMakeLists.txt index f07f72dc3..2ef51bef2 100644 --- a/client/test/CMakeLists.txt +++ b/client/test/CMakeLists.txt @@ -17,11 +17,21 @@ # See the License for the specific language governing permissions and # limitations under the License. -add_executable(freerdp-test +set(FREERDP_CLIENT_TEST_SRCS freerdp.c) -target_link_libraries(freerdp-test freerdp-core) -target_link_libraries(freerdp-test freerdp-gdi) -target_link_libraries(freerdp-test freerdp-utils) -target_link_libraries(freerdp-test freerdp-channels ${CMAKE_DL_LIBS}) +add_executable(freerdp-test ${FREERDP_CLIENT_TEST_SRCS}) +set(FREERDP_CLIENT_TEST_LIBS ${FREERDP_CLIENT_TEST_LIBS} ${CMAKE_DL_LIBS}) + +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_CLIENT_TEST_LIBS ${FREERDP_CLIENT_TEST_LIBS} freerdp) +else() + set(FREERDP_CLIENT_TEST_LIBS ${FREERDP_CLIENT_TEST_LIBS} + freerdp-core + freerdp-gdi + freerdp-utils + freerdp-channels) +endif() + +target_link_libraries(freerdp-test ${FREERDP_CLIENT_TEST_LIBS}) diff --git a/client/test/freerdp.c b/client/test/freerdp.c index 6c0a19790..a301666ba 100644 --- a/client/test/freerdp.c +++ b/client/test/freerdp.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef _WIN32 #include #include @@ -231,6 +235,7 @@ int tfreerdp_run(freerdp* instance) max_fds = 0; FD_ZERO(&rfds_set); + FD_ZERO(&wfds_set); for (i = 0; i < rcount; i++) { diff --git a/cmake/AutoVersioning.cmake b/cmake/AutoVersioning.cmake index 04e6479ed..fe6e3399f 100644 --- a/cmake/AutoVersioning.cmake +++ b/cmake/AutoVersioning.cmake @@ -40,7 +40,8 @@ else() endif() # Check if has not commited changes - execute_process(COMMAND git update-index -q --refresh) + execute_process(COMMAND git update-index -q --refresh + ERROR_QUIET) execute_process(COMMAND git diff-index --name-only HEAD -- OUTPUT_VARIABLE CHANGED_SOURCE OUTPUT_STRIP_TRAILING_WHITESPACE diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index 0e1951674..cc2afd95d 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -1,8 +1,27 @@ + option(WITH_MANPAGES "Generate manpages." ON) option(WITH_NEON "Enable NEON optimization for rfx decoder" OFF) option(WITH_PROFILER "Compile profiler." OFF) option(WITH_SSE2_TARGET "Allow compiler to generate SSE2 instructions." OFF) option(WITH_SSE2 "Use SSE2 optimization." OFF) +option(WITH_JPEG "Use JPEG decoding." OFF) + +if(APPLE) + option(WITH_CLANG "Build using clang" OFF) +endif() + +if(MSVC) + option(WITH_NATIVE_SSPI "Use native SSPI modules" ON) +endif() + +if(${CMAKE_VERSION} VERSION_GREATER 2.8.8) + option(WITH_MONOLITHIC_BUILD "Use monolithic build" OFF) +endif() + +option(WITH_CLIENT "Build client binaries" ON) +option(WITH_SERVER "Build server binaries" OFF) +option(WITH_CHANNELS "Build virtual channel plugins" ON) +option(WITH_THIRD_PARTY "Build third-party components" OFF) option(WITH_DEBUG_CERTIFICATE "Print certificate related debug messages." OFF) option(WITH_DEBUG_CHANNELS "Print channel manager debug messages." OFF) @@ -28,3 +47,4 @@ option(WITH_DEBUG_X11_CLIPRDR "Print X11 clipboard redirection debug messages" O option(WITH_DEBUG_X11_LOCAL_MOVESIZE "Print X11 Client local movesize debug messages" OFF) option(WITH_DEBUG_X11 "Print X11 Client debug messages" OFF) option(WITH_DEBUG_XV "Print XVideo debug messages" OFF) + diff --git a/cmake/GNUInstallDirsWrapper.cmake b/cmake/GNUInstallDirsWrapper.cmake index e438a0128..53e9fc970 100644 --- a/cmake/GNUInstallDirsWrapper.cmake +++ b/cmake/GNUInstallDirsWrapper.cmake @@ -9,5 +9,13 @@ if(GID_PATH STREQUAL "NOTFOUND") set(CMAKE_INSTALL_LIBDIR "lib${LIB_SUFFIX}" CACHE PATH "object code libraries (lib)") endif() + foreach(dir BINDIR LIBDIR) + if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}}) + set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}") + else() + set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}") + endif() + endforeach() + mark_as_advanced(CMAKE_INSTALL_BINDIR CMAKE_INSTALL_LIBDIR) endif() diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake new file mode 100644 index 000000000..8f0169fde --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake @@ -0,0 +1,106 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ ...]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +function(get_git_head_revision _refspecvar _hashvar) + set(GIT_PARENT_DIR "${CMAKE_SOURCE_DIR}") + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories + set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") + get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) + if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) + # We have reached the root directory, we are not in git + set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + endwhile() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${GIT_DIR}/HEAD") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" + @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) + set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + if(NOT GIT_FOUND) + set(${_var} "n/a" PARENT_SCOPE) + return() + endif() + get_git_head_revision(refspec hash) + if(NOT hash) + set(${_var} "n/a" PARENT_SCOPE) + return() + endif() + + execute_process(COMMAND "${GIT_EXECUTABLE}" describe ${hash} ${ARGN} + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "n/a") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/GetGitRevisionDescription.cmake.in new file mode 100644 index 000000000..888ce13aa --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake.in @@ -0,0 +1,38 @@ +# +# Internal file for GetGitRevisionDescription.cmake +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(HEAD_HASH) + +file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) + +string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) +if(HEAD_CONTENTS MATCHES "ref") + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}") + configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + set(HEAD_HASH "${HEAD_REF}") + endif() +else() + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) +endif() + +if(NOT HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) +endif() diff --git a/config.h.in b/config.h.in index 1dced6c30..8b6f2db61 100644 --- a/config.h.in +++ b/config.h.in @@ -6,6 +6,7 @@ #define FREERDP_VERSION_MAJOR ${FREERDP_VERSION_MAJOR} #define FREERDP_VERSION_MINOR ${FREERDP_VERSION_MINOR} #define FREERDP_VERSION_REVISION ${FREERDP_VERSION_REVISION} +#define GIT_REVISION "${GIT_REVISION}" #define FREERDP_DATA_PATH "${FREERDP_DATA_PATH}" #define FREERDP_PLUGIN_PATH "${FREERDP_PLUGIN_PATH}" @@ -18,6 +19,9 @@ #cmakedefine HAVE_STDINT_H #cmakedefine HAVE_STDBOOL_H #cmakedefine HAVE_INTTYPES_H +#cmakedefine HAVE_SYS_MODEM_H +#cmakedefine HAVE_SYS_FILIO_H +#cmakedefine HAVE_SYS_STRTIO_H #cmakedefine HAVE_TM_GMTOFF @@ -26,6 +30,7 @@ #cmakedefine WITH_SSE2 #cmakedefine WITH_NEON #cmakedefine WITH_NATIVE_SSPI +#cmakedefine WITH_JPEG /* Debug */ #cmakedefine WITH_DEBUG_CERTIFICATE @@ -46,6 +51,7 @@ #cmakedefine WITH_DEBUG_RFX #cmakedefine WITH_DEBUG_SCARD #cmakedefine WITH_DEBUG_SVC +#cmakedefine WITH_DEBUG_TIMEZONE #cmakedefine WITH_DEBUG_TRANSPORT #cmakedefine WITH_DEBUG_WND #cmakedefine WITH_DEBUG_X11 diff --git a/freerdp.pc.in b/freerdp.pc.in index e0a3c3f47..08be9d138 100644 --- a/freerdp.pc.in +++ b/freerdp.pc.in @@ -1,6 +1,6 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=@CMAKE_INSTALL_PREFIX@/include Name: FreeRDP diff --git a/freerdp.spec b/freerdp.spec index 369a283a7..445f132d8 100644 --- a/freerdp.spec +++ b/freerdp.spec @@ -97,6 +97,7 @@ cmake \ -DWITH_CUPS:BOOL=ON \ -DWITH_PCSC:BOOL=ON \ -DWITH_PULSEAUDIO:BOOL=ON \ + -DWITH_MACAUDIO:BOOL=ON \ -DWITH_X11:BOOL=ON \ -DWITH_XCURSOR:BOOL=ON \ -DWITH_XEXT:BOOL=ON \ diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index fce03ec18..ae8acdede 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -17,20 +17,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -file(GLOB HEADERS "freerdp/*.h") -install_files(/include/freerdp FILES ${HEADERS}) +file(GLOB FREERDP_HEADERS "freerdp/*.h") +install(FILES ${FREERDP_HEADERS} DESTINATION include/freerdp) -install(DIRECTORY freerdp/utils DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") -install(DIRECTORY freerdp/channels DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") install(DIRECTORY freerdp/cache DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") -install(DIRECTORY freerdp/gdi DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") -install(DIRECTORY freerdp/rail DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/channels DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") install(DIRECTORY freerdp/codec DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") -install(DIRECTORY freerdp/plugins DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") -install(DIRECTORY freerdp/locale DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") install(DIRECTORY freerdp/crypto DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") -install(DIRECTORY freerdp/auth DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/gdi DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/locale DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/plugins DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/rail DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") install(DIRECTORY freerdp/server DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/utils DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") + -file(GLOB HEADERS "winpr/*.h") -install_files(/include/winpr FILES ${HEADERS}) diff --git a/include/freerdp/codec/jpeg.h b/include/freerdp/codec/jpeg.h new file mode 100644 index 000000000..36540d922 --- /dev/null +++ b/include/freerdp/codec/jpeg.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Compressed Bitmap + * + * Copyright 2012 Jay Sorg + * + * 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 __JPEG_H +#define __JPEG_H + +#include + +boolean +jpeg_decompress(uint8* input, uint8* output, int width, int height, int size, int bpp); + +#endif /* __BITMAP_H */ diff --git a/include/freerdp/config.h.in b/include/freerdp/config.h.in new file mode 100644 index 000000000..7042956aa --- /dev/null +++ b/include/freerdp/config.h.in @@ -0,0 +1,36 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * config.h definitions for installable headers + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CONFIG_H +#define FREERDP_CONFIG_H + +/* + * This generated config.h header is meant for installation, which is why + * all definitions MUST be prefixed to avoid conflicting with third-party + * libraries. Only add configurable definitions which really must be used + * from installable headers, such as the base type definition types. + */ + +#cmakedefine FREERDP_HAVE_LIMITS_H +#cmakedefine FREERDP_HAVE_STDINT_H +#cmakedefine FREERDP_HAVE_STDBOOL_H +#cmakedefine FREERDP_HAVE_INTTYPES_H + +#endif + diff --git a/include/freerdp/constants.h b/include/freerdp/constants.h index 88b3c321f..c9bcf67c7 100644 --- a/include/freerdp/constants.h +++ b/include/freerdp/constants.h @@ -27,6 +27,7 @@ enum RDP_CODEC_ID { CODEC_ID_NONE = 0x00, CODEC_ID_NSCODEC = 0x01, + CODEC_ID_JPEG = 0x02, CODEC_ID_REMOTEFX = 0x03 }; diff --git a/include/freerdp/crypto/nla.h b/include/freerdp/crypto/nla.h index 520d904cd..7e0a08b93 100644 --- a/include/freerdp/crypto/nla.h +++ b/include/freerdp/crypto/nla.h @@ -41,6 +41,7 @@ struct rdp_credssp int recv_seq_num; freerdp* instance; CtxtHandle context; + LPTSTR SspiModule; rdpSettings* settings; SecBuffer negoToken; SecBuffer pubKeyAuth; diff --git a/include/freerdp/graphics.h b/include/freerdp/graphics.h index 033ff3a23..578feae3b 100644 --- a/include/freerdp/graphics.h +++ b/include/freerdp/graphics.h @@ -35,7 +35,8 @@ typedef void (*pBitmap_New)(rdpContext* context, rdpBitmap* bitmap); typedef void (*pBitmap_Free)(rdpContext* context, rdpBitmap* bitmap); typedef void (*pBitmap_Paint)(rdpContext* context, rdpBitmap* bitmap); typedef void (*pBitmap_Decompress)(rdpContext* context, rdpBitmap* bitmap, - uint8* data, int width, int height, int bpp, int length, boolean compressed); + uint8* data, int width, int height, int bpp, int length, + boolean compressed, int codec_id); typedef void (*pBitmap_SetSurface)(rdpContext* context, rdpBitmap* bitmap, boolean primary); struct rdp_bitmap diff --git a/include/freerdp/rail/rail.h b/include/freerdp/rail/rail.h index a5b4f5412..ce0686ffb 100644 --- a/include/freerdp/rail/rail.h +++ b/include/freerdp/rail/rail.h @@ -40,6 +40,7 @@ typedef void (*railSetWindowText)(rdpRail* rail, rdpWindow* window); typedef void (*railSetWindowIcon)(rdpRail* rail, rdpWindow* window, rdpIcon* icon); typedef void (*railSetWindowRects)(rdpRail* rail, rdpWindow* window); typedef void (*railSetWindowVisibilityRects)(rdpRail* rail, rdpWindow* window); +typedef void (*railDesktopNonMonitored) (rdpRail* rail, rdpWindow* window); struct rdp_rail { @@ -57,6 +58,7 @@ struct rdp_rail railSetWindowIcon rail_SetWindowIcon; railSetWindowRects rail_SetWindowRects; railSetWindowVisibilityRects rail_SetWindowVisibilityRects; + railDesktopNonMonitored rail_DesktopNonMonitored; }; FREERDP_API void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update); diff --git a/include/freerdp/rail/window_list.h b/include/freerdp/rail/window_list.h index 82914a497..57da47c11 100644 --- a/include/freerdp/rail/window_list.h +++ b/include/freerdp/rail/window_list.h @@ -48,6 +48,7 @@ FREERDP_API rdpWindow* window_list_get_by_extra_id(rdpWindowList* list, void* ex FREERDP_API void window_list_create(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); FREERDP_API void window_list_update(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); FREERDP_API void window_list_delete(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo); +FREERDP_API void window_list_clear(rdpWindowList* list); FREERDP_API rdpWindowList* window_list_new(rdpRail* rail); FREERDP_API void window_list_free(rdpWindowList* list); diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 7d0a24be8..ab37336ef 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -269,7 +269,8 @@ struct rdp_settings ALIGN64 uint32 encryption_level; /* 28 */ ALIGN64 boolean authentication; /* 29 */ ALIGN64 uint32 negotiationFlags; /* 30 */ - ALIGN64 uint64 paddingB[48 - 31]; /* 31 */ + ALIGN64 boolean security_layer_negotiation; /* 31 */ + ALIGN64 uint64 paddingB[48 - 32]; /* 32 */ /* Connection Settings */ ALIGN64 uint32 port; /* 48 */ @@ -295,7 +296,10 @@ struct rdp_settings ALIGN64 boolean local; /* 68 */ ALIGN64 boolean authentication_only; /* 69 */ ALIGN64 boolean from_stdin; /* 70 */ - ALIGN64 uint64 paddingC[80 - 71]; /* 71 */ + ALIGN64 boolean send_preconnection_pdu; /* 71 */ + ALIGN64 uint32 preconnection_id; /* 72 */ + ALIGN64 char* preconnection_blob; /* 73 */ + ALIGN64 uint64 paddingC[80 - 74]; /* 74 */ /* User Interface Parameters */ ALIGN64 boolean sw_gdi; /* 80 */ @@ -394,8 +398,12 @@ struct rdp_settings ALIGN64 uint32 rfx_codec_id; /* 282 */ ALIGN64 uint32 ns_codec_id; /* 283 */ ALIGN64 uint32 rfx_codec_mode; /* 284 */ - ALIGN64 uint32 frame_acknowledge; /* 285 */ - ALIGN64 uint64 paddingM[296 - 286]; /* 286 */ + ALIGN64 boolean frame_acknowledge; /* 285 */ + ALIGN64 boolean jpeg_codec; /* 286 */ + ALIGN64 uint32 jpeg_codec_id; /* 287 */ + ALIGN64 uint32 jpeg_quality; /* 288 */ + ALIGN64 uint32 v3_codec_id; /* 289 */ + ALIGN64 uint64 paddingM[296 - 290]; /* 290 */ /* Recording */ ALIGN64 boolean dump_rfx; /* 296 */ diff --git a/include/freerdp/types.h b/include/freerdp/types.h index bce09650f..5fa72377f 100644 --- a/include/freerdp/types.h +++ b/include/freerdp/types.h @@ -18,24 +18,24 @@ * limitations under the License. */ -#ifndef __RDP_TYPES_H -#define __RDP_TYPES_H +#ifndef FREERDP_TYPES_H +#define FREERDP_TYPES_H + +#include #ifdef _WIN32 #include #endif -/* Base Types */ - -#ifdef HAVE_LIMITS_H +#ifdef FREERDP_HAVE_LIMITS_H #include #endif -#ifdef HAVE_STDINT_H +#ifdef FREERDP_HAVE_STDINT_H #include #endif -#ifdef HAVE_INTTYPES_H +#ifdef FREERDP_HAVE_INTTYPES_H #include typedef uint8_t uint8; @@ -65,7 +65,7 @@ typedef signed long long sint64; #endif /* HAVE_INTTYPES_H */ -#ifdef HAVE_STDBOOL_H +#ifdef FREERDP_HAVE_STDBOOL_H #include @@ -107,7 +107,7 @@ typedef int boolean; #endif /* __cplusplus */ -#endif /* HAVE_STDBOOL_H */ +#endif /* FREERDP_HAVE_STDBOOL_H */ #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) diff --git a/include/freerdp/utils/load_plugin.h b/include/freerdp/utils/load_plugin.h index 9b698d0b4..6ba2a292d 100644 --- a/include/freerdp/utils/load_plugin.h +++ b/include/freerdp/utils/load_plugin.h @@ -29,5 +29,7 @@ FREERDP_API boolean freerdp_close_library(void* library); FREERDP_API void* freerdp_load_library_symbol(const char* file, const char* name); FREERDP_API void* freerdp_load_plugin(const char* name, const char* entry_name); FREERDP_API void* freerdp_load_channel_plugin(rdpSettings* settings, const char* name, const char* entry_name); +FREERDP_API boolean freerdp_register_static_plugin(const char* name, const char* entry_name, void* entry_addr); +FREERDP_API void* freerdp_load_static_plugin(const char* name, const char* entry_name); #endif /* __LOAD_PLUGIN_UTILS_H */ diff --git a/include/freerdp/utils/svc_plugin.h b/include/freerdp/utils/svc_plugin.h index 829b09b2a..4f593d15e 100644 --- a/include/freerdp/utils/svc_plugin.h +++ b/include/freerdp/utils/svc_plugin.h @@ -60,9 +60,15 @@ FREERDP_API int svc_plugin_send_event(rdpSvcPlugin* plugin, RDP_EVENT* event); #define DEBUG_SVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #endif +#ifdef WITH_STATIC_PLUGINS +#define DEFINE_SVC_PLUGIN_ENTRY(_prefix) int _prefix##_entry(PCHANNEL_ENTRY_POINTS pEntryPoints) +#else +#define DEFINE_SVC_PLUGIN_ENTRY(_prefix) int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +#endif + #define DEFINE_SVC_PLUGIN(_prefix, _name, _options) \ \ -int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) \ +DEFINE_SVC_PLUGIN_ENTRY(_prefix) \ { \ _prefix##Plugin* _p; \ \ diff --git a/include/winpr/asn1.h b/include/winpr/asn1.h deleted file mode 100644 index b1c90acfe..000000000 --- a/include/winpr/asn1.h +++ /dev/null @@ -1,383 +0,0 @@ -/** - * WinPR: Windows Portable Runtime - * ASN.1 Encoding & Decoding Engine - * - * Copyright 2012 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WINPR_ASN1_H -#define WINPR_ASN1_H - -#ifdef _WIN32 - -#include -#include - -#else - -#include -#include - -typedef unsigned char ASN1uint8_t; -typedef signed char ASN1int8_t; - -typedef unsigned short ASN1uint16_t; -typedef signed short ASN1int16_t; - -typedef unsigned long ASN1uint32_t; -typedef signed long ASN1int32_t; - -typedef ASN1uint8_t ASN1octet_t; - -typedef ASN1uint8_t ASN1bool_t; - -struct tagASN1intx_t -{ - ASN1uint32_t length; - ASN1octet_t* value; -}; -typedef struct tagASN1intx_t ASN1intx_t; - -struct tagASN1octetstring_t -{ - ASN1uint32_t length; - ASN1octet_t* value; -}; -typedef struct tagASN1octetstring_t ASN1octetstring_t; - -struct tagASN1octetstring2_t -{ - ASN1uint32_t length; - ASN1octet_t value[1]; -}; -typedef struct tagASN1octetstring2_t ASN1octetstring2_t; - -struct ASN1iterator_s -{ - struct ASN1iterator_s* next; - void* value; -}; -typedef struct ASN1iterator_s ASN1iterator_t; - -struct tagASN1bitstring_t -{ - ASN1uint32_t length; - ASN1octet_t* value; -}; -typedef struct tagASN1bitstring_t ASN1bitstring_t; - -typedef char ASN1char_t; - -struct tagASN1charstring_t -{ - ASN1uint32_t length; - ASN1char_t* value; -}; -typedef struct tagASN1charstring_t ASN1charstring_t; - -typedef ASN1uint16_t ASN1char16_t; - -struct tagASN1char16string_t -{ - ASN1uint32_t length; - ASN1char16_t* value; -}; -typedef struct tagASN1char16string_t ASN1char16string_t; - -typedef ASN1uint32_t ASN1char32_t; - -struct tagASN1char32string_t -{ - ASN1uint32_t length; - ASN1char32_t* value; -}; -typedef struct tagASN1char32string_t ASN1char32string_t; - -typedef ASN1char_t* ASN1ztcharstring_t; -typedef ASN1char16_t* ASN1ztchar16string_t; -typedef ASN1char32_t* ASN1ztchar32string_t; - -struct tagASN1wstring_t -{ - ASN1uint32_t length; - WCHAR* value; -}; -typedef struct tagASN1wstring_t ASN1wstring_t; - -struct ASN1objectidentifier_s -{ - struct ASN1objectidentifier_s* next; - ASN1uint32_t value; -}; -typedef struct ASN1objectidentifier_s* ASN1objectidentifier_t; - -struct tagASN1objectidentifier2_t -{ - ASN1uint16_t count; - ASN1uint32_t value[16]; -}; -typedef struct tagASN1objectidentifier2_t ASN1objectidentifier2_t; - -struct tagASN1encodedOID_t -{ - ASN1uint16_t length; - ASN1octet_t* value; -}; -typedef struct tagASN1encodedOID_t ASN1encodedOID_t; - -typedef ASN1ztcharstring_t ASN1objectdescriptor_t; - -struct tagASN1generalizedtime_t -{ - ASN1uint16_t year; - ASN1uint8_t month; - ASN1uint8_t day; - ASN1uint8_t hour; - ASN1uint8_t minute; - ASN1uint8_t second; - ASN1uint16_t millisecond; - ASN1bool_t universal; - ASN1int16_t diff; -}; -typedef struct tagASN1generalizedtime_t ASN1generalizedtime_t; - -struct tagASN1utctime_t -{ - ASN1uint8_t year; - ASN1uint8_t month; - ASN1uint8_t day; - ASN1uint8_t hour; - ASN1uint8_t minute; - ASN1uint8_t second; - ASN1bool_t universal; - ASN1int16_t diff; -}; -typedef struct tagASN1utctime_t ASN1utctime_t; - -struct tagASN1open_t -{ - ASN1uint32_t length; - - union - { - void* encoded; - void* value; - }; -}; -typedef struct tagASN1open_t ASN1open_t; - -enum tagASN1blocktype_e -{ - ASN1_DER_SET_OF_BLOCK, -}; -typedef enum tagASN1blocktype_e ASN1blocktype_e; - -typedef ASN1int32_t ASN1enum_t; -typedef ASN1uint16_t ASN1choice_t; -typedef ASN1uint32_t ASN1magic_t; - -enum -{ - ASN1_CHOICE_BASE = 1, - ASN1_CHOICE_INVALID = -1, - ASN1_CHOICE_EXTENSION = 0, -}; - -enum tagASN1error_e -{ - ASN1_SUCCESS = 0, - ASN1_ERR_INTERNAL = -1001, - ASN1_ERR_EOD = -1002, - ASN1_ERR_CORRUPT = -1003, - ASN1_ERR_LARGE = -1004, - ASN1_ERR_CONSTRAINT = -1005, - ASN1_ERR_MEMORY = -1006, - ASN1_ERR_OVERFLOW = -1007, - ASN1_ERR_BADPDU = -1008, - ASN1_ERR_BADARGS = -1009, - ASN1_ERR_BADREAL = -1010, - ASN1_ERR_BADTAG = -1011, - ASN1_ERR_CHOICE = -1012, - ASN1_ERR_RULE = -1013, - ASN1_ERR_UTF8 = -1014, - ASN1_ERR_PDU_TYPE = -1051, - ASN1_ERR_NYI = -1052, - ASN1_WRN_EXTENDED = 1001, - ASN1_WRN_NOEOD = 1002, -}; -typedef enum tagASN1error_e ASN1error_e; - -enum tagASN1encodingrule_e -{ - ASN1_BER_RULE_BER = 0x0100, - ASN1_BER_RULE_CER = 0x0200, - ASN1_BER_RULE_DER = 0x0400, - ASN1_BER_RULE = ASN1_BER_RULE_BER | ASN1_BER_RULE_CER | ASN1_BER_RULE_DER, -}; -typedef enum tagASN1encodingrule_e ASN1encodingrule_e; - -typedef struct ASN1encoding_s* ASN1encoding_t; -typedef struct ASN1decoding_s* ASN1decoding_t; - -typedef ASN1int32_t (*ASN1BerEncFun_t)(ASN1encoding_t enc, ASN1uint32_t tag, void* data); -typedef ASN1int32_t (*ASN1BerDecFun_t)(ASN1decoding_t enc, ASN1uint32_t tag, void* data); - -struct tagASN1BerFunArr_t -{ - const ASN1BerEncFun_t* apfnEncoder; - const ASN1BerDecFun_t* apfnDecoder; -}; -typedef struct tagASN1BerFunArr_t ASN1BerFunArr_t; - -typedef void (*ASN1GenericFun_t)(void); -typedef void (*ASN1FreeFun_t)(void* data); - -struct tagASN1module_t -{ - ASN1magic_t nModuleName; - ASN1encodingrule_e eRule; - ASN1uint32_t dwFlags; - ASN1uint32_t cPDUs; - const ASN1FreeFun_t* apfnFreeMemory; - const ASN1uint32_t* acbStructSize; - ASN1BerFunArr_t BER; -} -typedef struct tagASN1module_t* ASN1module_t; - -struct ASN1encoding_s -{ - ASN1magic_t magic; - ASN1uint32_t version; - ASN1module_t module; - ASN1octet_t* buf; - ASN1uint32_t size; - ASN1uint32_t len; - ASN1error_e err; - ASN1uint32_t bit; - ASN1octet_t* pos; - ASN1uint32_t cbExtraHeader; - ASN1encodingrule_e eRule; - ASN1uint32_t dwFlags; -}; - -struct ASN1decoding_s -{ - ASN1magic_t magic; - ASN1uint32_t version; - ASN1module_t module; - ASN1octet_t* buf; - ASN1uint32_t size; - ASN1uint32_t len; - ASN1error_e err; - ASN1uint32_t bit; - ASN1octet_t* pos; - ASN1encodingrule_e eRule; - ASN1uint32_t dwFlags; -}; - -enum -{ - ASN1FLAGS_NONE = 0x00000000L, - ASN1FLAGS_NOASSERT = 0x00001000L, -}; - -enum -{ - ASN1ENCODE_APPEND = 0x00000001L, - ASN1ENCODE_REUSEBUFFER = 0x00000004L, - ASN1ENCODE_SETBUFFER = 0x00000008L, - ASN1ENCODE_ALLOCATEBUFFER = 0x00000010L, - ASN1ENCODE_NOASSERT = ASN1FLAGS_NOASSERT, -}; - -enum -{ - ASN1DECODE_APPENDED = 0x00000001L, - ASN1DECODE_REWINDBUFFER = 0x00000004L, - ASN1DECODE_SETBUFFER = 0x00000008L, - ASN1DECODE_AUTOFREEBUFFER = 0x00000010L, - ASN1DECODE_NOASSERT = ASN1FLAGS_NOASSERT, -}; - -WINPR_API ASN1module_t ASN1_CreateModule(ASN1uint32_t nVersion, ASN1encodingrule_e eRule, - ASN1uint32_t dwFlags, ASN1uint32_t cPDU, const ASN1GenericFun_t apfnEncoder[], - const ASN1GenericFun_t apfnDecoder[], const ASN1FreeFun_t apfnFreeMemory[], - const ASN1uint32_t acbStructSize[], ASN1magic_t nModuleName); - -WINPR_API void ASN1_CloseModule(ASN1module_t pModule); - -WINPR_API ASN1error_e ASN1_CreateEncoder(ASN1module_t pModule, ASN1encoding_t* ppEncoderInfo, - ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize, ASN1encoding_t pParent); - -WINPR_API ASN1error_e ASN1_Encode(ASN1encoding_t pEncoderInfo, void* pDataStruct, ASN1uint32_t nPduNum, - ASN1uint32_t dwFlags, ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize); - -WINPR_API void ASN1_CloseEncoder(ASN1encoding_t pEncoderInfo); - -WINPR_API void ASN1_CloseEncoder2(ASN1encoding_t pEncoderInfo); - -WINPR_API ASN1error_e ASN1_CreateDecoder(ASN1module_t pModule, ASN1decoding_t* ppDecoderInfo, - ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize, ASN1decoding_t pParent); - -WINPR_API ASN1error_e ASN1_Decode(ASN1decoding_t pDecoderInfo, void** ppDataStruct, ASN1uint32_t nPduNum, - ASN1uint32_t dwFlags, ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize); - -WINPR_API void ASN1_CloseDecoder(ASN1decoding_t pDecoderInfo); - -WINPR_API void ASN1_FreeEncoded(ASN1encoding_t pEncoderInfo, void* pBuf); - -WINPR_API void ASN1_FreeDecoded(ASN1decoding_t pDecoderInfo, void* pDataStruct, ASN1uint32_t nPduNum); - -enum tagASN1option_e -{ - ASN1OPT_CHANGE_RULE = 0x101, - ASN1OPT_GET_RULE = 0x201, - ASN1OPT_NOT_REUSE_BUFFER = 0x301, - ASN1OPT_REWIND_BUFFER = 0x302, - ASN1OPT_SET_DECODED_BUFFER = 0x501, - ASN1OPT_DEL_DECODED_BUFFER = 0x502, - ASN1OPT_GET_DECODED_BUFFER_SIZE = 0x601, -}; -typedef enum ASN1option_e; - -struct tagASN1optionparam_t -{ - ASN1option_e eOption; - - union - { - ASN1encodingrule_e eRule; - ASN1uint32_t cbRequiredDecodedBufSize; - - struct - { - ASN1octet_t* pbBuf; - ASN1uint32_t cbBufSize; - } Buffer; - }; -}; -typedef struct tagASN1optionparam_t ASN1optionparam_t; -typedef struct tagASN1optionparam_t ASN1optionparam_s; - -WINPR_API ASN1error_e ASN1_SetEncoderOption(ASN1encoding_t pEncoderInfo, ASN1optionparam_t* pOptParam); -WINPR_API ASN1error_e ASN1_GetEncoderOption(ASN1encoding_t pEncoderInfo, ASN1optionparam_t* pOptParam); - -WINPR_API ASN1error_e ASN1_SetDecoderOption(ASN1decoding_t pDecoderInfo, ASN1optionparam_t* pOptParam); -WINPR_API ASN1error_e ASN1_GetDecoderOption(ASN1decoding_t pDecoderInfo, ASN1optionparam_t* pOptParam); - -#endif - -#endif /* WINPR_ASN1_H */ - diff --git a/libfreerdp/CMakeLists.txt b/libfreerdp/CMakeLists.txt new file mode 100644 index 000000000..20a46bc9b --- /dev/null +++ b/libfreerdp/CMakeLists.txt @@ -0,0 +1,50 @@ +# FreeRDP: A Remote Desktop Protocol Client +# libfreerdp cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if(WITH_MONOLITHIC_BUILD) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() + +add_subdirectory(utils) +add_subdirectory(gdi) +add_subdirectory(rail) +add_subdirectory(cache) +add_subdirectory(codec) +add_subdirectory(crypto) +add_subdirectory(channels) +add_subdirectory(locale) +add_subdirectory(core) + +if(WITH_MONOLITHIC_BUILD) + add_library(freerdp + $ + $ + $ + $ + $ + $ + $ + $ + $) + + set_target_properties(freerdp PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + + target_link_libraries(freerdp ${FREERDP_LIBS}) + install(TARGETS freerdp DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + + diff --git a/libfreerdp-cache/CMakeLists.txt b/libfreerdp/cache/CMakeLists.txt similarity index 67% rename from libfreerdp-cache/CMakeLists.txt rename to libfreerdp/cache/CMakeLists.txt index 25e0b7727..940f9e409 100644 --- a/libfreerdp-cache/CMakeLists.txt +++ b/libfreerdp/cache/CMakeLists.txt @@ -27,11 +27,23 @@ set(FREERDP_CACHE_SRCS glyph.c cache.c) -add_library(freerdp-cache ${FREERDP_CACHE_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(freerdp-cache OBJECT ${FREERDP_CACHE_SRCS}) +else() + add_library(freerdp-cache ${FREERDP_CACHE_SRCS}) +endif() set_target_properties(freerdp-cache PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -target_link_libraries(freerdp-cache freerdp-core) -target_link_libraries(freerdp-cache freerdp-utils) +set(FREERDP_CACHE_LIBS) -install(TARGETS freerdp-cache DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_LIBS ${FREERDP_LIBS} ${FREERDP_CACHE_LIBS} PARENT_SCOPE) +else() + set(FREERDP_CACHE_LIBS ${FREERDP_CACHE_LIBS} + freerdp-core + freerdp-utils) + + target_link_libraries(freerdp-cache ${FREERDP_CACHE_LIBS}) + install(TARGETS freerdp-cache DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/libfreerdp-cache/bitmap.c b/libfreerdp/cache/bitmap.c similarity index 84% rename from libfreerdp-cache/bitmap.c rename to libfreerdp/cache/bitmap.c index a382bfe0c..c361c4f88 100644 --- a/libfreerdp-cache/bitmap.c +++ b/libfreerdp/cache/bitmap.c @@ -17,7 +17,12 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include +#include #include #include @@ -74,7 +79,8 @@ void update_gdi_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitm bitmap->Decompress(context, bitmap, cache_bitmap->bitmapDataStream, cache_bitmap->bitmapWidth, cache_bitmap->bitmapHeight, - cache_bitmap->bitmapBpp, cache_bitmap->bitmapLength, cache_bitmap->compressed); + cache_bitmap->bitmapBpp, cache_bitmap->bitmapLength, + cache_bitmap->compressed, CODEC_ID_NONE); bitmap->New(context, bitmap); @@ -104,7 +110,8 @@ void update_gdi_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cach bitmap->Decompress(context, bitmap, cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapWidth, cache_bitmap_v2->bitmapHeight, - cache_bitmap_v2->bitmapBpp, cache_bitmap_v2->bitmapLength, cache_bitmap_v2->compressed); + cache_bitmap_v2->bitmapBpp, cache_bitmap_v2->bitmapLength, + cache_bitmap_v2->compressed, CODEC_ID_NONE); bitmap->New(context, bitmap); @@ -116,6 +123,38 @@ void update_gdi_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cach bitmap_cache_put(cache->bitmap, cache_bitmap_v2->cacheId, cache_bitmap_v2->cacheIndex, bitmap); } +void update_gdi_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3) +{ + rdpBitmap* bitmap; + rdpBitmap* prevBitmap; + rdpCache* cache = context->cache; + BITMAP_DATA_EX* bitmapData = &cache_bitmap_v3->bitmapData; + + bitmap = Bitmap_Alloc(context); + + Bitmap_SetDimensions(context, bitmap, bitmapData->width, bitmapData->height); + + if (cache_bitmap_v3->bitmapData.bpp == 0) + { + /* Workaround for Windows 8 bug where bitmapBpp is not set */ + cache_bitmap_v3->bitmapData.bpp = context->instance->settings->color_depth; + } + + bitmap->Decompress(context, bitmap, + bitmapData->data, bitmap->width, bitmap->height, + bitmapData->bpp, bitmapData->length, true, + bitmapData->codecID); + + bitmap->New(context, bitmap); + + prevBitmap = bitmap_cache_get(cache->bitmap, cache_bitmap_v3->cacheId, cache_bitmap_v3->cacheIndex); + + if (prevBitmap != NULL) + Bitmap_Free(context, prevBitmap); + + bitmap_cache_put(cache->bitmap, cache_bitmap_v3->cacheId, cache_bitmap_v3->cacheIndex, bitmap); +} + void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap_update) { int i; @@ -149,7 +188,8 @@ void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap_update) bitmap->Decompress(context, bitmap, bitmap_data->bitmapDataStream, bitmap_data->width, bitmap_data->height, - bitmap_data->bitsPerPixel, bitmap_data->bitmapLength, bitmap_data->compressed); + bitmap_data->bitsPerPixel, bitmap_data->bitmapLength, + bitmap_data->compressed, CODEC_ID_NONE); if (reused) bitmap->Free(context, bitmap); @@ -220,6 +260,7 @@ void bitmap_cache_register_callbacks(rdpUpdate* update) update->secondary->CacheBitmap = update_gdi_cache_bitmap; update->secondary->CacheBitmapV2 = update_gdi_cache_bitmap_v2; + update->secondary->CacheBitmapV3 = update_gdi_cache_bitmap_v3; update->BitmapUpdate = update_gdi_bitmap_update; } diff --git a/libfreerdp-cache/brush.c b/libfreerdp/cache/brush.c similarity index 99% rename from libfreerdp-cache/brush.c rename to libfreerdp/cache/brush.c index f07cd5a18..28ef07ef7 100644 --- a/libfreerdp-cache/brush.c +++ b/libfreerdp/cache/brush.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-cache/cache.c b/libfreerdp/cache/cache.c similarity index 97% rename from libfreerdp-cache/cache.c rename to libfreerdp/cache/cache.c index a3462526a..19a5ae337 100644 --- a/libfreerdp-cache/cache.c +++ b/libfreerdp/cache/cache.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-cache/glyph.c b/libfreerdp/cache/glyph.c similarity index 99% rename from libfreerdp-cache/glyph.c rename to libfreerdp/cache/glyph.c index fc3326631..ca0ca8931 100644 --- a/libfreerdp-cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-cache/nine_grid.c b/libfreerdp/cache/nine_grid.c similarity index 98% rename from libfreerdp-cache/nine_grid.c rename to libfreerdp/cache/nine_grid.c index c0f05c67b..40bd9a3f8 100644 --- a/libfreerdp-cache/nine_grid.c +++ b/libfreerdp/cache/nine_grid.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-cache/offscreen.c b/libfreerdp/cache/offscreen.c similarity index 98% rename from libfreerdp-cache/offscreen.c rename to libfreerdp/cache/offscreen.c index cbc485f0c..51ad5139b 100644 --- a/libfreerdp-cache/offscreen.c +++ b/libfreerdp/cache/offscreen.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -137,7 +141,7 @@ rdpOffscreenCache* offscreen_cache_new(rdpSettings* settings) offscreen_cache->currentSurface = SCREEN_BITMAP_SURFACE; offscreen_cache->maxSize = 7680; - offscreen_cache->maxEntries = 100; + offscreen_cache->maxEntries = 2000; settings->offscreen_bitmap_cache_size = offscreen_cache->maxSize; settings->offscreen_bitmap_cache_entries = offscreen_cache->maxEntries; diff --git a/libfreerdp-cache/palette.c b/libfreerdp/cache/palette.c similarity index 97% rename from libfreerdp-cache/palette.c rename to libfreerdp/cache/palette.c index 62ffabe18..ca4576700 100644 --- a/libfreerdp-cache/palette.c +++ b/libfreerdp/cache/palette.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-cache/pointer.c b/libfreerdp/cache/pointer.c similarity index 99% rename from libfreerdp-cache/pointer.c rename to libfreerdp/cache/pointer.c index e1409e701..dea91ebf5 100644 --- a/libfreerdp-cache/pointer.c +++ b/libfreerdp/cache/pointer.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-channels/CMakeLists.txt b/libfreerdp/channels/CMakeLists.txt similarity index 66% rename from libfreerdp-channels/CMakeLists.txt rename to libfreerdp/channels/CMakeLists.txt index 56f2fa710..51cb08ba4 100644 --- a/libfreerdp-channels/CMakeLists.txt +++ b/libfreerdp/channels/CMakeLists.txt @@ -23,10 +23,22 @@ set(FREERDP_CHANNELS_SRCS wtsvc.c wtsvc.h) -add_library(freerdp-channels ${FREERDP_CHANNELS_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(freerdp-channels OBJECT ${FREERDP_CHANNELS_SRCS}) +else() + add_library(freerdp-channels ${FREERDP_CHANNELS_SRCS}) +endif() set_target_properties(freerdp-channels PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -target_link_libraries(freerdp-channels freerdp-utils) -install(TARGETS freerdp-channels DESTINATION ${CMAKE_INSTALL_LIBDIR}) +set(FREERDP_CHANNELS_LIBS) +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_LIBS ${FREERDP_LIBS} ${FREERDP_CHANNELS_LIBS} PARENT_SCOPE) +else() + set(FREERDP_CHANNELS_LIBS ${FREERDP_CHANNELS_LIBS} + freerdp-utils) + + target_link_libraries(freerdp-channels ${FREERDP_CHANNELS_LIBS}) + install(TARGETS freerdp-channels DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/libfreerdp-channels/libchannels.c b/libfreerdp/channels/libchannels.c similarity index 99% rename from libfreerdp-channels/libchannels.c rename to libfreerdp/channels/libchannels.c index c50196675..70ebc8049 100644 --- a/libfreerdp-channels/libchannels.c +++ b/libfreerdp/channels/libchannels.c @@ -32,10 +32,14 @@ * from the main thread. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-channels/libchannels.h b/libfreerdp/channels/libchannels.h similarity index 97% rename from libfreerdp-channels/libchannels.h rename to libfreerdp/channels/libchannels.h index ab116719e..f34bdeed8 100644 --- a/libfreerdp-channels/libchannels.h +++ b/libfreerdp/channels/libchannels.h @@ -21,7 +21,10 @@ #ifndef __LIBCHANNELS_H #define __LIBCHANNELS_H +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #ifdef WITH_DEBUG_CHANNELS diff --git a/libfreerdp-channels/wtsvc.c b/libfreerdp/channels/wtsvc.c similarity index 98% rename from libfreerdp-channels/wtsvc.c rename to libfreerdp/channels/wtsvc.c index 266cab1b2..2fb9f3626 100644 --- a/libfreerdp-channels/wtsvc.c +++ b/libfreerdp/channels/wtsvc.c @@ -17,7 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include @@ -159,7 +162,7 @@ static void wts_read_drdynvc_data_first(rdpPeerChannel* channel, STREAM* s, int return; stream_set_pos(channel->receive_data, 0); - stream_check_size(channel->receive_data, channel->dvc_total_length); + stream_check_size(channel->receive_data, (int) channel->dvc_total_length); stream_write(channel->receive_data, stream_get_tail(s), length); } @@ -174,7 +177,7 @@ static void wts_read_drdynvc_data(rdpPeerChannel* channel, STREAM* s, uint32 len return; } stream_write(channel->receive_data, stream_get_tail(s), length); - if (stream_get_length(channel->receive_data) >= channel->dvc_total_length) + if (stream_get_length(channel->receive_data) >= (int) channel->dvc_total_length) { wts_queue_receive_data(channel, stream_get_head(channel->receive_data), channel->dvc_total_length); channel->dvc_total_length = 0; @@ -300,7 +303,7 @@ static void wts_write_drdynvc_create_request(STREAM *s, uint32 ChannelId, const wts_write_drdynvc_header(s, CREATE_REQUEST_PDU, ChannelId); len = strlen(ChannelName) + 1; - stream_check_size(s, len); + stream_check_size(s, (int) len); stream_write(s, ChannelName, len); } @@ -673,7 +676,7 @@ boolean WTSVirtualChannelWrite( stream_seek_uint8(s); cbChId = wts_write_variable_uint(s, channel->channel_id); - if (first && Length > stream_get_left(s)) + if (first && (Length > (uint32) stream_get_left(s))) { cbLen = wts_write_variable_uint(s, Length); item->buffer[0] = (DATA_FIRST_PDU << 4) | (cbLen << 2) | cbChId; diff --git a/libfreerdp-channels/wtsvc.h b/libfreerdp/channels/wtsvc.h similarity index 100% rename from libfreerdp-channels/wtsvc.h rename to libfreerdp/channels/wtsvc.h diff --git a/libfreerdp-codec/CMakeLists.txt b/libfreerdp/codec/CMakeLists.txt similarity index 59% rename from libfreerdp-codec/CMakeLists.txt rename to libfreerdp/codec/CMakeLists.txt index 78d7610ea..6a03e002e 100644 --- a/libfreerdp-codec/CMakeLists.txt +++ b/libfreerdp/codec/CMakeLists.txt @@ -44,30 +44,56 @@ set(FREERDP_CODEC_SRCS nsc_types.h mppc_dec.c mppc_enc.c -) + jpeg.c) -if(WITH_SSE2) - set(FREERDP_CODEC_SRCS ${FREERDP_CODEC_SRCS} +set(FREERDP_CODEC_SSE2_SRCS rfx_sse2.c rfx_sse2.h nsc_sse2.c - nsc_sse2.h -) - set_property(SOURCE rfx_sse2.c nsc_sse2.c PROPERTY COMPILE_FLAGS "-msse2") + nsc_sse2.h) + +set(FREERDP_CODEC_NEON_SRCS + rfx_neon.c + rfx_neon.h) + +if(WITH_SSE2) + set(FREERDP_CODEC_SRCS ${FREERDP_CODEC_SRCS} ${FREERDP_CODEC_SSE2_SRCS}) + + if(CMAKE_COMPILER_IS_GNUCC) + set_property(SOURCE rfx_sse2.c nsc_sse2.c PROPERTY COMPILE_FLAGS "-msse2") + endif() + + if(MSVC) + set_property(SOURCE rfx_sse2.c nsc_sse2.c PROPERTY COMPILE_FLAGS "/arch:SSE2") + endif() endif() if(WITH_NEON) - set(FREERDP_CODEC_SRCS ${FREERDP_CODEC_SRCS} - rfx_neon.c - rfx_neon.h -) + set(FREERDP_CODEC_SRCS ${FREERDP_CODEC_SRCS} ${FREERDP_CODEC_NEON_SRCS}) set_property(SOURCE rfx_neon.c PROPERTY COMPILE_FLAGS "-mfpu=neon -mfloat-abi=softfp") endif() -add_library(freerdp-codec ${FREERDP_CODEC_SRCS}) +if(WITH_JPEG) + set(FREERDP_JPEG_LIBS jpeg) +endif() + +if(WITH_MONOLITHIC_BUILD) + add_library(freerdp-codec OBJECT ${FREERDP_CODEC_SRCS}) +else() + add_library(freerdp-codec ${FREERDP_CODEC_SRCS}) +endif() set_target_properties(freerdp-codec PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -target_link_libraries(freerdp-codec freerdp-utils) -install(TARGETS freerdp-codec DESTINATION ${CMAKE_INSTALL_LIBDIR}) +set(FREERDP_CODEC_LIBS + ${FREERDP_JPEG_LIBS}) +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_LIBS ${FREERDP_LIBS} ${FREERDP_CODEC_LIBS} PARENT_SCOPE) +else() + set(FREERDP_CODEC_LIBS ${FREERDP_CODEC_LIBS} + freerdp-utils) + + target_link_libraries(freerdp-codec ${FREERDP_CODEC_LIBS}) + install(TARGETS freerdp-codec DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/libfreerdp-codec/bitmap.c b/libfreerdp/codec/bitmap.c similarity index 99% rename from libfreerdp-codec/bitmap.c rename to libfreerdp/codec/bitmap.c index 635a583aa..31152b160 100644 --- a/libfreerdp-codec/bitmap.c +++ b/libfreerdp/codec/bitmap.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-codec/color.c b/libfreerdp/codec/color.c similarity index 99% rename from libfreerdp-codec/color.c rename to libfreerdp/codec/color.c index a660d7717..82cd7adf8 100644 --- a/libfreerdp-codec/color.c +++ b/libfreerdp/codec/color.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-codec/include/bitmap.c b/libfreerdp/codec/include/bitmap.c similarity index 100% rename from libfreerdp-codec/include/bitmap.c rename to libfreerdp/codec/include/bitmap.c diff --git a/libfreerdp/codec/jpeg.c b/libfreerdp/codec/jpeg.c new file mode 100644 index 000000000..70dbc08ea --- /dev/null +++ b/libfreerdp/codec/jpeg.c @@ -0,0 +1,157 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Compressed jpeg + * + * Copyright 2012 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifdef WITH_JPEG + +#define HAVE_BOOLEAN +#include + +struct mydata_decomp +{ + char* data; + int data_bytes; +}; + +/*****************************************************************************/ +static void my_init_source(j_decompress_ptr cinfo) +{ +} + +/*****************************************************************************/ +static boolean my_fill_input_buffer(j_decompress_ptr cinfo) +{ + struct mydata_decomp* md; + + md = (struct mydata_decomp*)(cinfo->client_data); + cinfo->src->next_input_byte = (unsigned char*)(md->data); + cinfo->src->bytes_in_buffer = md->data_bytes; + return 1; +} + +/*****************************************************************************/ +static void my_skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ +} + +/*****************************************************************************/ +static boolean my_resync_to_restart(j_decompress_ptr cinfo, int desired) +{ + return 1; +} + +/*****************************************************************************/ +static void my_term_source(j_decompress_ptr cinfo) +{ +} + +/*****************************************************************************/ +static int +do_decompress(char* comp_data, int comp_data_bytes, + int* width, int* height, int* bpp, + char* decomp_data, int* decomp_data_bytes) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + struct jpeg_source_mgr src_mgr; + struct mydata_decomp md; + JSAMPROW row_pointer[1]; + + memset(&cinfo, 0, sizeof(cinfo)); + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + + memset(&src_mgr, 0, sizeof(src_mgr)); + cinfo.src = &src_mgr; + src_mgr.init_source = my_init_source; + src_mgr.fill_input_buffer = my_fill_input_buffer; + src_mgr.skip_input_data = my_skip_input_data; + src_mgr.resync_to_restart = my_resync_to_restart; + src_mgr.term_source = my_term_source; + + memset(&md, 0, sizeof(md)); + md.data = comp_data; + md.data_bytes = comp_data_bytes; + cinfo.client_data = &md; + + jpeg_read_header(&cinfo, 1); + + cinfo.out_color_space = JCS_RGB; + + *width = cinfo.image_width; + *height = cinfo.image_height; + *bpp = cinfo.num_components * 8; + + jpeg_start_decompress(&cinfo); + + while(cinfo.output_scanline < cinfo.image_height) + { + row_pointer[0] = (JSAMPROW) decomp_data; + jpeg_read_scanlines(&cinfo, row_pointer, 1); + decomp_data += cinfo.image_width * cinfo.num_components; + } + *decomp_data_bytes = cinfo.output_width * + cinfo.output_height * cinfo.num_components; + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + return 0; +} + +/* jpeg decompress */ +boolean +jpeg_decompress(uint8 * input, uint8 * output, int width, int height, int size, int bpp) +{ + int lwidth; + int lheight; + int lbpp; + int ldecomp_data_bytes; + + if (bpp != 24) + { + return 0; + } + if (do_decompress((char*)input, size, + &lwidth, &lheight, &lbpp, + (char*)output, &ldecomp_data_bytes) != 0) + { + return 0; + } + if (lwidth != width || lheight != height || lbpp != bpp) + { + return 0; + } + return 1; +} + +#else + +boolean +jpeg_decompress(uint8 * input, uint8 * output, int width, int height, int size, int bpp) +{ + return 0; +} + +#endif diff --git a/libfreerdp-codec/mppc_dec.c b/libfreerdp/codec/mppc_dec.c similarity index 99% rename from libfreerdp-codec/mppc_dec.c rename to libfreerdp/codec/mppc_dec.c index 4122ca6eb..0a846af3f 100644 --- a/libfreerdp-codec/mppc_dec.c +++ b/libfreerdp/codec/mppc_dec.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-codec/mppc_enc.c b/libfreerdp/codec/mppc_enc.c similarity index 99% rename from libfreerdp-codec/mppc_enc.c rename to libfreerdp/codec/mppc_enc.c index f2f21f90b..3efe88abe 100644 --- a/libfreerdp-codec/mppc_enc.c +++ b/libfreerdp/codec/mppc_enc.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-codec/nsc.c b/libfreerdp/codec/nsc.c similarity index 99% rename from libfreerdp-codec/nsc.c rename to libfreerdp/codec/nsc.c index 69db2e2ac..ac74dcc0c 100644 --- a/libfreerdp-codec/nsc.c +++ b/libfreerdp/codec/nsc.c @@ -18,10 +18,15 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include + #include #include diff --git a/libfreerdp-codec/nsc_encode.c b/libfreerdp/codec/nsc_encode.c similarity index 99% rename from libfreerdp-codec/nsc_encode.c rename to libfreerdp/codec/nsc_encode.c index 78fb208ff..7feb4879a 100644 --- a/libfreerdp-codec/nsc_encode.c +++ b/libfreerdp/codec/nsc_encode.c @@ -17,10 +17,15 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include + #include #include diff --git a/libfreerdp-codec/nsc_encode.h b/libfreerdp/codec/nsc_encode.h similarity index 100% rename from libfreerdp-codec/nsc_encode.h rename to libfreerdp/codec/nsc_encode.h diff --git a/libfreerdp-codec/nsc_sse2.c b/libfreerdp/codec/nsc_sse2.c similarity index 99% rename from libfreerdp-codec/nsc_sse2.c rename to libfreerdp/codec/nsc_sse2.c index 1dc198228..04868b11e 100644 --- a/libfreerdp-codec/nsc_sse2.c +++ b/libfreerdp/codec/nsc_sse2.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include diff --git a/libfreerdp-codec/nsc_sse2.h b/libfreerdp/codec/nsc_sse2.h similarity index 100% rename from libfreerdp-codec/nsc_sse2.h rename to libfreerdp/codec/nsc_sse2.h diff --git a/libfreerdp-codec/nsc_types.h b/libfreerdp/codec/nsc_types.h similarity index 97% rename from libfreerdp-codec/nsc_types.h rename to libfreerdp/codec/nsc_types.h index 96a5787ba..3982a9bfb 100644 --- a/libfreerdp-codec/nsc_types.h +++ b/libfreerdp/codec/nsc_types.h @@ -21,7 +21,10 @@ #ifndef __NSC_TYPES_H #define __NSC_TYPES_H +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include diff --git a/libfreerdp-codec/rfx.c b/libfreerdp/codec/rfx.c similarity index 99% rename from libfreerdp-codec/rfx.c rename to libfreerdp/codec/rfx.c index 45ce680ae..1e7478356 100644 --- a/libfreerdp-codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -17,10 +17,15 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include + #include #include #include diff --git a/libfreerdp-codec/rfx_bitstream.h b/libfreerdp/codec/rfx_bitstream.h similarity index 100% rename from libfreerdp-codec/rfx_bitstream.h rename to libfreerdp/codec/rfx_bitstream.h diff --git a/libfreerdp-codec/rfx_constants.h b/libfreerdp/codec/rfx_constants.h similarity index 100% rename from libfreerdp-codec/rfx_constants.h rename to libfreerdp/codec/rfx_constants.h diff --git a/libfreerdp-codec/rfx_decode.c b/libfreerdp/codec/rfx_decode.c similarity index 99% rename from libfreerdp-codec/rfx_decode.c rename to libfreerdp/codec/rfx_decode.c index 22cd4cd92..8a8f1de43 100644 --- a/libfreerdp-codec/rfx_decode.c +++ b/libfreerdp/codec/rfx_decode.c @@ -18,10 +18,16 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include + #include "rfx_types.h" #include "rfx_rlgr.h" #include "rfx_differential.h" diff --git a/libfreerdp-codec/rfx_decode.h b/libfreerdp/codec/rfx_decode.h similarity index 100% rename from libfreerdp-codec/rfx_decode.h rename to libfreerdp/codec/rfx_decode.h diff --git a/libfreerdp-codec/rfx_differential.c b/libfreerdp/codec/rfx_differential.c similarity index 96% rename from libfreerdp-codec/rfx_differential.c rename to libfreerdp/codec/rfx_differential.c index 7a1d49e25..ba972b6ee 100644 --- a/libfreerdp-codec/rfx_differential.c +++ b/libfreerdp/codec/rfx_differential.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include "rfx_differential.h" void rfx_differential_decode(sint16* buffer, int buffer_size) diff --git a/libfreerdp-codec/rfx_differential.h b/libfreerdp/codec/rfx_differential.h similarity index 100% rename from libfreerdp-codec/rfx_differential.h rename to libfreerdp/codec/rfx_differential.h diff --git a/libfreerdp-codec/rfx_dwt.c b/libfreerdp/codec/rfx_dwt.c similarity index 99% rename from libfreerdp-codec/rfx_dwt.c rename to libfreerdp/codec/rfx_dwt.c index e870b18a8..97df63bd7 100644 --- a/libfreerdp-codec/rfx_dwt.c +++ b/libfreerdp/codec/rfx_dwt.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-codec/rfx_dwt.h b/libfreerdp/codec/rfx_dwt.h similarity index 100% rename from libfreerdp-codec/rfx_dwt.h rename to libfreerdp/codec/rfx_dwt.h diff --git a/libfreerdp-codec/rfx_encode.c b/libfreerdp/codec/rfx_encode.c similarity index 99% rename from libfreerdp-codec/rfx_encode.c rename to libfreerdp/codec/rfx_encode.c index 451188ed8..d454f1558 100644 --- a/libfreerdp-codec/rfx_encode.c +++ b/libfreerdp/codec/rfx_encode.c @@ -18,9 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include "rfx_types.h" #include "rfx_rlgr.h" #include "rfx_differential.h" diff --git a/libfreerdp-codec/rfx_encode.h b/libfreerdp/codec/rfx_encode.h similarity index 100% rename from libfreerdp-codec/rfx_encode.h rename to libfreerdp/codec/rfx_encode.h diff --git a/libfreerdp-codec/rfx_neon.c b/libfreerdp/codec/rfx_neon.c similarity index 99% rename from libfreerdp-codec/rfx_neon.c rename to libfreerdp/codec/rfx_neon.c index 5a57a2f4b..1cbd7b7b7 100644 --- a/libfreerdp-codec/rfx_neon.c +++ b/libfreerdp/codec/rfx_neon.c @@ -17,6 +17,10 @@ limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #if defined(__ARM_NEON__) #include diff --git a/libfreerdp-codec/rfx_neon.h b/libfreerdp/codec/rfx_neon.h similarity index 100% rename from libfreerdp-codec/rfx_neon.h rename to libfreerdp/codec/rfx_neon.h diff --git a/libfreerdp-codec/rfx_pool.c b/libfreerdp/codec/rfx_pool.c similarity index 97% rename from libfreerdp-codec/rfx_pool.c rename to libfreerdp/codec/rfx_pool.c index 12e703c01..47e6065b6 100644 --- a/libfreerdp-codec/rfx_pool.c +++ b/libfreerdp/codec/rfx_pool.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include "rfx_pool.h" diff --git a/libfreerdp-codec/rfx_pool.h b/libfreerdp/codec/rfx_pool.h similarity index 100% rename from libfreerdp-codec/rfx_pool.h rename to libfreerdp/codec/rfx_pool.h diff --git a/libfreerdp-codec/rfx_quantization.c b/libfreerdp/codec/rfx_quantization.c similarity index 98% rename from libfreerdp-codec/rfx_quantization.c rename to libfreerdp/codec/rfx_quantization.c index 617818f34..81adb20f6 100644 --- a/libfreerdp-codec/rfx_quantization.c +++ b/libfreerdp/codec/rfx_quantization.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "rfx_quantization.h" static void rfx_quantization_decode_block(sint16* buffer, int buffer_size, uint32 factor) diff --git a/libfreerdp-codec/rfx_quantization.h b/libfreerdp/codec/rfx_quantization.h similarity index 100% rename from libfreerdp-codec/rfx_quantization.h rename to libfreerdp/codec/rfx_quantization.h diff --git a/libfreerdp-codec/rfx_rlgr.c b/libfreerdp/codec/rfx_rlgr.c similarity index 99% rename from libfreerdp-codec/rfx_rlgr.c rename to libfreerdp/codec/rfx_rlgr.c index b20c89bdf..7e92c475d 100644 --- a/libfreerdp-codec/rfx_rlgr.c +++ b/libfreerdp/codec/rfx_rlgr.c @@ -22,10 +22,16 @@ * [MS-RDPRFX] 3.1.8.1.7.3 RLGR1/RLGR3 Pseudocode */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include + #include "rfx_bitstream.h" #include "rfx_rlgr.h" diff --git a/libfreerdp-codec/rfx_rlgr.h b/libfreerdp/codec/rfx_rlgr.h similarity index 100% rename from libfreerdp-codec/rfx_rlgr.h rename to libfreerdp/codec/rfx_rlgr.h diff --git a/libfreerdp-codec/rfx_sse2.c b/libfreerdp/codec/rfx_sse2.c similarity index 99% rename from libfreerdp-codec/rfx_sse2.c rename to libfreerdp/codec/rfx_sse2.c index cdf92ae20..b9cc9fa04 100644 --- a/libfreerdp-codec/rfx_sse2.c +++ b/libfreerdp/codec/rfx_sse2.c @@ -18,9 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include @@ -40,7 +45,7 @@ static __inline void __attribute__((__gnu_inline__, __always_inline__, __artific _mm_prefetch_buffer(char * buffer, int num_bytes) { __m128i * buf = (__m128i*) buffer; - int i; + unsigned int i; for (i = 0; i < (num_bytes / sizeof(__m128i)); i+=(CACHE_LINE_BYTES / sizeof(__m128i))) { _mm_prefetch((char*)(&buf[i]), _MM_HINT_NTA); diff --git a/libfreerdp-codec/rfx_sse2.h b/libfreerdp/codec/rfx_sse2.h similarity index 100% rename from libfreerdp-codec/rfx_sse2.h rename to libfreerdp/codec/rfx_sse2.h diff --git a/libfreerdp-codec/rfx_types.h b/libfreerdp/codec/rfx_types.h similarity index 98% rename from libfreerdp-codec/rfx_types.h rename to libfreerdp/codec/rfx_types.h index a18034ed0..dd3f739ef 100644 --- a/libfreerdp-codec/rfx_types.h +++ b/libfreerdp/codec/rfx_types.h @@ -20,7 +20,10 @@ #ifndef __RFX_TYPES_H #define __RFX_TYPES_H +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include diff --git a/libfreerdp-core/CMakeLists.txt b/libfreerdp/core/CMakeLists.txt similarity index 63% rename from libfreerdp-core/CMakeLists.txt rename to libfreerdp/core/CMakeLists.txt index 325d35669..45661ed22 100644 --- a/libfreerdp-core/CMakeLists.txt +++ b/libfreerdp/core/CMakeLists.txt @@ -3,7 +3,7 @@ # # Copyright 2011 O.S. Systems Software Ltda. # Copyright 2011 Otavio Salvador -# Copyright 2011 Marc-Andre Moreau +# Copyright 2012 Marc-Andre Moreau # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ add_definitions(-DEXT_PATH="${FREERDP_EXTENSION_PATH}") include_directories(${OPENSSL_INCLUDE_DIR}) include_directories(${ZLIB_INCLUDE_DIRS}) -set(LIBFREERDP_CORE_SRCS +set(FREERDP_CORE_SRCS activation.c activation.h extension.c @@ -89,33 +89,46 @@ set(LIBFREERDP_CORE_SRCS listener.c listener.h peer.c - peer.h -) + peer.h) -add_library(freerdp-core ${LIBFREERDP_CORE_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(freerdp-core OBJECT ${FREERDP_CORE_SRCS}) +else() + add_library(freerdp-core ${FREERDP_CORE_SRCS}) +endif() set_target_properties(freerdp-core PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -if(WIN32) - target_link_libraries(freerdp-core ws2_32) +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_CORE_LIBS winpr) else() - target_link_libraries(freerdp-core ${ZLIB_LIBRARIES}) + set(FREERDP_CORE_LIBS + winpr-utils + winpr-rpc + winpr-sspi) + + if(NOT WIN32) + set(FREERDP_CORE_LIBS ${FREERDP_CORE_LIBS} winpr-registry) + endif() endif() -target_link_libraries(freerdp-core freerdp-utils) -target_link_libraries(freerdp-core freerdp-codec) -target_link_libraries(freerdp-core freerdp-locale) - -target_link_libraries(freerdp-core winpr-utils) -target_link_libraries(freerdp-core winpr-rpc) -target_link_libraries(freerdp-core winpr-sspi) - -if(NOT WIN32) - target_link_libraries(freerdp-core winpr-registry) +if(WIN32) + set(FREERDP_CORE_LIBS ${FREERDP_CORE_LIBS} ws2_32) +else() + set(FREERDP_CORE_LIBS ${FREERDP_CORE_LIBS} ${ZLIB_LIBRARIES}) endif() -target_link_libraries(freerdp-core freerdp-crypto) -target_link_libraries(freerdp-core ${OPENSSL_LIBRARIES}) - -install(TARGETS freerdp-core DESTINATION ${CMAKE_INSTALL_LIBDIR}) +set(FREERDP_CORE_LIBS ${FREERDP_CORE_LIBS} ${OPENSSL_LIBRARIES}) +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_LIBS ${FREERDP_LIBS} ${FREERDP_CORE_LIBS} PARENT_SCOPE) +else() + set(FREERDP_CORE_LIBS ${FREERDP_CORE_LIBS} + freerdp-utils + freerdp-codec + freerdp-crypto + freerdp-locale) + + target_link_libraries(freerdp-core ${FREERDP_CORE_LIBS}) + install(TARGETS freerdp-core DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/libfreerdp-core/activation.c b/libfreerdp/core/activation.c similarity index 99% rename from libfreerdp-core/activation.c rename to libfreerdp/core/activation.c index f93e75d10..8551bf8fd 100644 --- a/libfreerdp-core/activation.c +++ b/libfreerdp/core/activation.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "activation.h" /* diff --git a/libfreerdp-core/activation.h b/libfreerdp/core/activation.h similarity index 100% rename from libfreerdp-core/activation.h rename to libfreerdp/core/activation.h diff --git a/libfreerdp-core/capabilities.c b/libfreerdp/core/capabilities.c similarity index 97% rename from libfreerdp-core/capabilities.c rename to libfreerdp/core/capabilities.c index 0a1811f9c..7c5ed657c 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "capabilities.h" /* @@ -62,6 +66,9 @@ static const char* const CAPSET_TYPE_STRINGS[] = /* CODEC_GUID_NSCODEC 0xCA8D1BB9000F154F589FAE2D1A87E2D6 */ #define CODEC_GUID_NSCODEC "\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6" +/* CODEC_GUID_JPEG 0x430C9EED1BAF4CE6869ACB8B37B66237*/ +#define CODEC_GUID_JPEG "\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37" + void rdp_read_capability_set_header(STREAM* s, uint16* length, uint16* type) { stream_read_uint16(s, *type); /* capabilitySetType */ @@ -1521,6 +1528,12 @@ void rdp_write_nsc_client_capability_container(STREAM* s, rdpSettings* settings) stream_write_uint8(s, 3); /* colorLossLevel */ } +void rdp_write_jpeg_client_capability_container(STREAM* s, rdpSettings* settings) +{ + stream_write_uint16(s, 1); /* codecPropertiesLength */ + stream_write_uint8(s, settings->jpeg_quality); +} + /** * Write RemoteFX Server Capability Container.\n * @param s stream @@ -1532,6 +1545,12 @@ void rdp_write_rfx_server_capability_container(STREAM* s, rdpSettings* settings) stream_write_uint32(s, 0); /* reserved */ } +void rdp_write_jpeg_server_capability_container(STREAM* s, rdpSettings* settings) +{ + stream_write_uint16(s, 1); /* codecPropertiesLength */ + stream_write_uint8(s, 75); +} + /** * Write NSCODEC Server Capability Container.\n * @param s stream @@ -1563,6 +1582,8 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings) bitmapCodecCount++; if (settings->ns_codec) bitmapCodecCount++; + if (settings->jpeg_codec) + bitmapCodecCount++; stream_write_uint8(s, bitmapCodecCount); @@ -1595,6 +1616,20 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings) rdp_write_nsc_client_capability_container(s, settings); } } + if (settings->jpeg_codec) + { + stream_write(s, CODEC_GUID_JPEG, 16); + if (settings->server_mode) + { + stream_write_uint8(s, 0); /* codecID is defined by the client */ + rdp_write_jpeg_server_capability_container(s, settings); + } + else + { + stream_write_uint8(s, CODEC_ID_JPEG); /* codecID */ + rdp_write_jpeg_client_capability_container(s, settings); + } + } rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS); } @@ -1616,6 +1651,21 @@ void rdp_read_frame_acknowledge_capability_set(STREAM* s, uint16 length, rdpSett } } +void rdp_read_bitmap_cache_v3_codec_id_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint8(s); /* (1 byte) */ +} + +void rdp_write_bitmap_cache_v3_codec_id_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + + header = rdp_capability_set_start(s); + stream_write_uint8(s, settings->v3_codec_id); + rdp_capability_set_finish(s, header, 6); +} + + /** * Write frame acknowledge capability set.\n * @param s stream @@ -1625,10 +1675,12 @@ void rdp_read_frame_acknowledge_capability_set(STREAM* s, uint16 length, rdpSett void rdp_write_frame_acknowledge_capability_set(STREAM* s, rdpSettings* settings) { uint8* header; + uint32 frame_acknowledge; header = rdp_capability_set_start(s); - stream_write_uint32(s, settings->frame_acknowledge); /* (4 bytes) */ + frame_acknowledge = settings->frame_acknowledge; + stream_write_uint32(s, frame_acknowledge); /* (4 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE); } @@ -1768,6 +1820,10 @@ boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 number rdp_read_frame_acknowledge_capability_set(s, length, settings); break; + case 6: + rdp_read_bitmap_cache_v3_codec_id_capability_set(s, length, settings); + break; + default: printf("unknown capability type %d\n", type); break; @@ -2076,6 +2132,15 @@ void rdp_write_confirm_active(STREAM* s, rdpSettings* settings) } } + if (settings->received_caps[6]) + { + if (settings->v3_codec_id != 0) + { + numberCapabilities++; + rdp_write_bitmap_cache_v3_codec_id_capability_set(s, settings); + } + } + stream_get_mark(s, em); stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */ @@ -2098,4 +2163,3 @@ boolean rdp_send_confirm_active(rdpRdp* rdp) return rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id); } - diff --git a/libfreerdp-core/capabilities.h b/libfreerdp/core/capabilities.h similarity index 100% rename from libfreerdp-core/capabilities.h rename to libfreerdp/core/capabilities.h diff --git a/libfreerdp-core/certificate.c b/libfreerdp/core/certificate.c similarity index 99% rename from libfreerdp-core/certificate.c rename to libfreerdp/core/certificate.c index b08da6f88..75cf1088a 100644 --- a/libfreerdp-core/certificate.c +++ b/libfreerdp/core/certificate.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-core/certificate.h b/libfreerdp/core/certificate.h similarity index 100% rename from libfreerdp-core/certificate.h rename to libfreerdp/core/certificate.h diff --git a/libfreerdp-core/channel.c b/libfreerdp/core/channel.c similarity index 98% rename from libfreerdp-core/channel.c rename to libfreerdp/core/channel.c index e92a0a80c..824c9768d 100644 --- a/libfreerdp-core/channel.c +++ b/libfreerdp/core/channel.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-core/channel.h b/libfreerdp/core/channel.h similarity index 100% rename from libfreerdp-core/channel.h rename to libfreerdp/core/channel.h diff --git a/libfreerdp-core/connection.c b/libfreerdp/core/connection.c similarity index 96% rename from libfreerdp-core/connection.c rename to libfreerdp/core/connection.c index f82bb878e..d3ab2be59 100644 --- a/libfreerdp-core/connection.c +++ b/libfreerdp/core/connection.c @@ -17,10 +17,15 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "info.h" #include "input.h" #include "connection.h" +#include "transport.h" #include @@ -63,13 +68,16 @@ boolean rdp_client_connect(rdpRdp* rdp) { - boolean status; - uint32 selectedProtocol; rdpSettings* settings = rdp->settings; nego_init(rdp->nego); nego_set_target(rdp->nego, settings->hostname, settings->port); nego_set_cookie(rdp->nego, settings->username); + nego_set_send_preconnection_pdu(rdp->nego, settings->send_preconnection_pdu); + nego_set_preconnection_id(rdp->nego, settings->preconnection_id); + nego_set_preconnection_blob(rdp->nego, settings->preconnection_blob); + + nego_set_negotiation_enabled(rdp->nego, settings->security_layer_negotiation); nego_enable_rdp(rdp->nego, settings->rdp_security); if (!settings->ts_gateway) @@ -78,36 +86,23 @@ boolean rdp_client_connect(rdpRdp* rdp) nego_enable_tls(rdp->nego, settings->tls_security); } - if (nego_connect(rdp->nego) != true) + if (!nego_connect(rdp->nego)) { - printf("Error: protocol security negotiation failure\n"); + printf("Error: protocol security negotiation or connection failure\n"); return false; } - selectedProtocol = rdp->nego->selected_protocol; - - if ((selectedProtocol & PROTOCOL_TLS) || (selectedProtocol == PROTOCOL_RDP)) + if ((rdp->nego->selected_protocol & PROTOCOL_TLS) || (rdp->nego->selected_protocol == PROTOCOL_RDP)) { if ((settings->username != NULL) && ((settings->password != NULL) || (settings->password_cookie != NULL && settings->password_cookie->length > 0))) settings->autologon = true; } - status = false; - if (selectedProtocol & PROTOCOL_NLA) - status = transport_connect_nla(rdp->transport); - else if (selectedProtocol & PROTOCOL_TLS) - status = transport_connect_tls(rdp->transport); - else if (selectedProtocol == PROTOCOL_RDP) /* 0 */ - status = transport_connect_rdp(rdp->transport); - - if (status != true) - return false; - rdp_set_blocking_mode(rdp, false); rdp->state = CONNECTION_STATE_NEGO; rdp->finalize_sc_pdus = 0; - if (mcs_send_connect_initial(rdp->mcs) != true) + if (!mcs_send_connect_initial(rdp->mcs)) { if (!connectErrorCode) { diff --git a/libfreerdp-core/connection.h b/libfreerdp/core/connection.h similarity index 99% rename from libfreerdp-core/connection.h rename to libfreerdp/core/connection.h index eb5c0460f..8d05bedb9 100644 --- a/libfreerdp-core/connection.h +++ b/libfreerdp/core/connection.h @@ -25,7 +25,6 @@ #include "tpdu.h" #include "nego.h" #include "mcs.h" -#include "transport.h" #include "activation.h" #include diff --git a/libfreerdp-core/errinfo.c b/libfreerdp/core/errinfo.c similarity index 99% rename from libfreerdp-core/errinfo.c rename to libfreerdp/core/errinfo.c index 48b1ef228..d2f255d37 100644 --- a/libfreerdp-core/errinfo.c +++ b/libfreerdp/core/errinfo.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "errinfo.h" int connectErrorCode; diff --git a/libfreerdp-core/errinfo.h b/libfreerdp/core/errinfo.h similarity index 100% rename from libfreerdp-core/errinfo.h rename to libfreerdp/core/errinfo.h diff --git a/libfreerdp-core/extension.c b/libfreerdp/core/extension.c similarity index 96% rename from libfreerdp-core/extension.c rename to libfreerdp/core/extension.c index 44fd628c5..2d79c24e4 100644 --- a/libfreerdp-core/extension.c +++ b/libfreerdp/core/extension.c @@ -18,9 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include @@ -194,6 +199,12 @@ int extension_post_connect(rdpExtension* ext) return 0; } +void extension_load_and_init_plugins(rdpExtension* extension) +{ + extension_load_plugins(extension); + extension_init_plugins(extension); +} + rdpExtension* extension_new(freerdp* instance) { rdpExtension* extension = NULL; @@ -203,9 +214,6 @@ rdpExtension* extension_new(freerdp* instance) extension = xnew(rdpExtension); extension->instance = instance; - - extension_load_plugins(extension); - extension_init_plugins(extension); } return extension; diff --git a/libfreerdp-core/extension.h b/libfreerdp/core/extension.h similarity index 95% rename from libfreerdp-core/extension.h rename to libfreerdp/core/extension.h index 25273023f..176888ea3 100644 --- a/libfreerdp-core/extension.h +++ b/libfreerdp/core/extension.h @@ -48,6 +48,7 @@ FREERDP_API int extension_post_connect(rdpExtension* extension); FREERDP_API rdpExtension* extension_new(freerdp* instance); FREERDP_API void extension_free(rdpExtension* extension); +FREERDP_API void extension_load_and_init_plugins(rdpExtension* extension); #endif /* __EXTENSION_H */ diff --git a/libfreerdp-core/fastpath.c b/libfreerdp/core/fastpath.c similarity index 96% rename from libfreerdp-core/fastpath.c rename to libfreerdp/core/fastpath.c index a54330fcf..b55d62545 100644 --- a/libfreerdp-core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include @@ -42,6 +47,24 @@ #define FASTPATH_MAX_PACKET_SIZE 0x3FFF +#ifdef WITH_DEBUG_RDP +static const char* const FASTPATH_UPDATETYPE_STRINGS[] = +{ + "Orders", /* 0x0 */ + "Bitmap", /* 0x1 */ + "Palette", /* 0x2 */ + "Synchronize", /* 0x3 */ + "Surface Commands", /* 0x4 */ + "System Pointer Hidden", /* 0x5 */ + "System Pointer Default", /* 0x6 */ + "???", /* 0x7 */ + "Pointer Position", /* 0x8 */ + "Color Pointer", /* 0x9 */ + "Cached Pointer", /* 0xA */ + "New Pointer", /* 0xB */ +}; +#endif + /* * The fastpath header may be two or three bytes long. * This function assumes that at least two bytes are available in the stream @@ -170,6 +193,11 @@ static boolean fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uin rdpContext* context = fastpath->rdp->update->context; rdpPointerUpdate* pointer = update->pointer; +#ifdef WITH_DEBUG_RDP + DEBUG_RDP("recv Fast-Path %s Update (0x%X), length:%d", + updateCode < ARRAY_SIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] : "???", updateCode, size); +#endif + switch (updateCode) { case FASTPATH_UPDATETYPE_ORDERS: diff --git a/libfreerdp-core/fastpath.h b/libfreerdp/core/fastpath.h similarity index 100% rename from libfreerdp-core/fastpath.h rename to libfreerdp/core/fastpath.h diff --git a/libfreerdp-core/freerdp.c b/libfreerdp/core/freerdp.c similarity index 98% rename from libfreerdp-core/freerdp.c rename to libfreerdp/core/freerdp.c index 23fe98361..8c77fc01d 100644 --- a/libfreerdp-core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "rdp.h" #include "input.h" #include "update.h" @@ -54,7 +58,7 @@ boolean freerdp_connect(freerdp* instance) IFCALLRET(instance->PreConnect, status, instance); - rdp->extension = extension_new(instance); + extension_load_and_init_plugins(rdp->extension); extension_pre_connect(rdp->extension); if (status != true) diff --git a/libfreerdp-core/gcc.c b/libfreerdp/core/gcc.c similarity index 99% rename from libfreerdp-core/gcc.c rename to libfreerdp/core/gcc.c index 60033e993..e751a263a 100644 --- a/libfreerdp-core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include "gcc.h" diff --git a/libfreerdp-core/gcc.h b/libfreerdp/core/gcc.h similarity index 100% rename from libfreerdp-core/gcc.h rename to libfreerdp/core/gcc.h diff --git a/libfreerdp-core/graphics.c b/libfreerdp/core/graphics.c similarity index 99% rename from libfreerdp-core/graphics.c rename to libfreerdp/core/graphics.c index f62c20682..2d7105d0d 100644 --- a/libfreerdp-core/graphics.c +++ b/libfreerdp/core/graphics.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-core/http.c b/libfreerdp/core/http.c similarity index 99% rename from libfreerdp-core/http.c rename to libfreerdp/core/http.c index 88ad973e3..caee0da51 100644 --- a/libfreerdp-core/http.c +++ b/libfreerdp/core/http.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include "http.h" diff --git a/libfreerdp-core/http.h b/libfreerdp/core/http.h similarity index 100% rename from libfreerdp-core/http.h rename to libfreerdp/core/http.h diff --git a/libfreerdp-core/info.c b/libfreerdp/core/info.c similarity index 99% rename from libfreerdp-core/info.c rename to libfreerdp/core/info.c index d4cf8a0b9..e5a9d381d 100644 --- a/libfreerdp-core/info.c +++ b/libfreerdp/core/info.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "timezone.h" #include "info.h" diff --git a/libfreerdp-core/info.h b/libfreerdp/core/info.h similarity index 100% rename from libfreerdp-core/info.h rename to libfreerdp/core/info.h diff --git a/libfreerdp-core/input.c b/libfreerdp/core/input.c similarity index 99% rename from libfreerdp-core/input.c rename to libfreerdp/core/input.c index eb946b25a..8e5185dec 100644 --- a/libfreerdp-core/input.c +++ b/libfreerdp/core/input.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include "input.h" diff --git a/libfreerdp-core/input.h b/libfreerdp/core/input.h similarity index 100% rename from libfreerdp-core/input.h rename to libfreerdp/core/input.h diff --git a/libfreerdp-core/license.c b/libfreerdp/core/license.c similarity index 99% rename from libfreerdp-core/license.c rename to libfreerdp/core/license.c index 5f5a555ba..3090b048c 100644 --- a/libfreerdp-core/license.c +++ b/libfreerdp/core/license.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "redirection.h" #include "certificate.h" diff --git a/libfreerdp-core/license.h b/libfreerdp/core/license.h similarity index 100% rename from libfreerdp-core/license.h rename to libfreerdp/core/license.h diff --git a/libfreerdp-core/listener.c b/libfreerdp/core/listener.c similarity index 99% rename from libfreerdp-core/listener.c rename to libfreerdp/core/listener.c index 4d2f109bc..42a95f5d5 100644 --- a/libfreerdp-core/listener.c +++ b/libfreerdp/core/listener.c @@ -17,10 +17,15 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include + #include #ifndef _WIN32 diff --git a/libfreerdp-core/listener.h b/libfreerdp/core/listener.h similarity index 100% rename from libfreerdp-core/listener.h rename to libfreerdp/core/listener.h diff --git a/libfreerdp-core/mcs.c b/libfreerdp/core/mcs.c similarity index 99% rename from libfreerdp-core/mcs.c rename to libfreerdp/core/mcs.c index 5b927d1ae..0d6a5dda2 100644 --- a/libfreerdp-core/mcs.c +++ b/libfreerdp/core/mcs.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "gcc.h" #include "mcs.h" diff --git a/libfreerdp-core/mcs.h b/libfreerdp/core/mcs.h similarity index 100% rename from libfreerdp-core/mcs.h rename to libfreerdp/core/mcs.h diff --git a/libfreerdp-core/nego.c b/libfreerdp/core/nego.c similarity index 75% rename from libfreerdp-core/nego.c rename to libfreerdp/core/nego.c index f92d2edfc..6cb114fd9 100644 --- a/libfreerdp-core/nego.c +++ b/libfreerdp/core/nego.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -27,6 +31,8 @@ #include "nego.h" +#include "transport.h" + static const char* const NEGO_STATE_STRINGS[] = { "NEGO_STATE_INITIAL", @@ -44,6 +50,8 @@ static const char PROTOCOL_SECURITY_STRINGS[3][4] = "NLA" }; +boolean nego_security_connect(rdpNego* nego); + /** * Negotiate protocol security and connect. * @param nego @@ -61,7 +69,41 @@ boolean nego_connect(rdpNego* nego) else if (nego->enabled_protocols[PROTOCOL_RDP] > 0) nego->state = NEGO_STATE_RDP; else + { + DEBUG_NEGO("No security protocol is enabled"); nego->state = NEGO_STATE_FAIL; + } + + if (!nego->security_layer_negotiation_enabled) + { + DEBUG_NEGO("Security Layer Negotiation is disabled"); + /* attempt only the highest enabled protocol (see nego_attempt_*) */ + nego->enabled_protocols[PROTOCOL_NLA] = 0; + nego->enabled_protocols[PROTOCOL_TLS] = 0; + nego->enabled_protocols[PROTOCOL_RDP] = 0; + if(nego->state == NEGO_STATE_NLA) + { + nego->enabled_protocols[PROTOCOL_NLA] = 1; + nego->selected_protocol = PROTOCOL_NLA; + } + else if (nego->state == NEGO_STATE_TLS) + { + nego->enabled_protocols[PROTOCOL_TLS] = 1; + nego->selected_protocol = PROTOCOL_TLS; + } + else if (nego->state == NEGO_STATE_RDP) + { + nego->enabled_protocols[PROTOCOL_RDP] = 1; + nego->selected_protocol = PROTOCOL_RDP; + } + } + + if(!nego_send_preconnection_pdu(nego)) + { + DEBUG_NEGO("Failed to send preconnection information"); + nego->state = NEGO_STATE_FINAL; + return false; + } } do @@ -93,9 +135,48 @@ boolean nego_connect(rdpNego* nego) nego->transport->settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } + /* finally connect security layer (if not already done) */ + if(!nego_security_connect(nego)) + { + DEBUG_NEGO("Failed to connect with %s security", PROTOCOL_SECURITY_STRINGS[nego->selected_protocol]); + return false; + } + return true; } +/* connect to selected security layer */ +boolean nego_security_connect(rdpNego* nego) +{ + if(!nego->tcp_connected) + { + nego->security_connected = false; + } + else if (!nego->security_connected) + { + if (nego->selected_protocol == PROTOCOL_NLA) + { + DEBUG_NEGO("nego_security_connect with PROTOCOL_NLA"); + nego->security_connected = transport_connect_nla(nego->transport); + } + else if (nego->selected_protocol == PROTOCOL_TLS ) + { + DEBUG_NEGO("nego_security_connect with PROTOCOL_TLS"); + nego->security_connected = transport_connect_tls(nego->transport); + } + else if (nego->selected_protocol == PROTOCOL_RDP) + { + DEBUG_NEGO("nego_security_connect with PROTOCOL_RDP"); + nego->security_connected = transport_connect_rdp(nego->transport); + } + else + { + DEBUG_NEGO("cannot connect security layer because no protocol has been selected yet."); + } + } + return nego->security_connected; +} + /** * Connect TCP layer. * @param nego @@ -104,21 +185,25 @@ boolean nego_connect(rdpNego* nego) boolean nego_tcp_connect(rdpNego* nego) { - if (nego->tcp_connected == 0) - { - if (transport_connect(nego->transport, nego->hostname, nego->port) == false) - { - nego->tcp_connected = 0; - return false; - } - else - { - nego->tcp_connected = 1; - return true; - } - } + if (!nego->tcp_connected) + nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port); + return nego->tcp_connected; +} - return true; +/** + * Connect TCP layer. For direct approach, connect security layer as well. + * @param nego + * @return + */ + +boolean nego_transport_connect(rdpNego* nego) +{ + nego_tcp_connect(nego); + + if (nego->tcp_connected && !nego->security_layer_negotiation_enabled) + return nego_security_connect(nego); + + return nego->tcp_connected; } /** @@ -127,15 +212,71 @@ boolean nego_tcp_connect(rdpNego* nego) * @return */ -int nego_tcp_disconnect(rdpNego* nego) +int nego_transport_disconnect(rdpNego* nego) { if (nego->tcp_connected) transport_disconnect(nego->transport); nego->tcp_connected = 0; + nego->security_connected = 0; return 1; } +/** + * Send preconnection information if enabled. + * @param nego + * @return + */ + +boolean nego_send_preconnection_pdu(rdpNego* nego) +{ + STREAM* s; + uint32 cbSize; + UNICONV* uniconv; + uint16 cchPCB_times2 = 0; + char* wszPCB = NULL; + + if (!nego->send_preconnection_pdu) + return true; + + DEBUG_NEGO("Sending preconnection PDU"); + + if (!nego_tcp_connect(nego)) + return false; + + /* it's easier to always send the version 2 PDU, and it's just 2 bytes overhead */ + cbSize = PRECONNECTION_PDU_V2_MIN_SIZE; + + if (nego->preconnection_blob) + { + size_t size; + uniconv = freerdp_uniconv_new(); + wszPCB = freerdp_uniconv_out(uniconv, nego->preconnection_blob, &size); + cchPCB_times2 = (uint16) size; + freerdp_uniconv_free(uniconv); + cchPCB_times2 += 2; /* zero-termination */ + cbSize += cchPCB_times2; + } + + s = transport_send_stream_init(nego->transport, cbSize); + stream_write_uint32(s, cbSize); /* cbSize */ + stream_write_uint32(s, 0); /* Flags */ + stream_write_uint32(s, PRECONNECTION_PDU_V2); /* Version */ + stream_write_uint32(s, nego->preconnection_id); /* Id */ + stream_write_uint16(s, cchPCB_times2 / 2); /* cchPCB */ + + if (wszPCB) + { + stream_write(s, wszPCB, cchPCB_times2); /* wszPCB */ + xfree(wszPCB); + } + + if (transport_write(nego->transport, s) < 0) + return false; + + return true; +} + /** * Attempt negotiating NLA + TLS security. * @param nego @@ -147,7 +288,7 @@ void nego_attempt_nla(rdpNego* nego) DEBUG_NEGO("Attempting NLA security"); - if (!nego_tcp_connect(nego)) + if (!nego_transport_connect(nego)) { nego->state = NEGO_STATE_FAIL; return; @@ -168,7 +309,7 @@ void nego_attempt_nla(rdpNego* nego) DEBUG_NEGO("state: %s", NEGO_STATE_STRINGS[nego->state]); if (nego->state != NEGO_STATE_FINAL) { - nego_tcp_disconnect(nego); + nego_transport_disconnect(nego); if (nego->enabled_protocols[PROTOCOL_TLS] > 0) nego->state = NEGO_STATE_TLS; @@ -190,7 +331,7 @@ void nego_attempt_tls(rdpNego* nego) DEBUG_NEGO("Attempting TLS security"); - if (!nego_tcp_connect(nego)) + if (!nego_transport_connect(nego)) { nego->state = NEGO_STATE_FAIL; return; @@ -210,7 +351,7 @@ void nego_attempt_tls(rdpNego* nego) if (nego->state != NEGO_STATE_FINAL) { - nego_tcp_disconnect(nego); + nego_transport_disconnect(nego); if (nego->enabled_protocols[PROTOCOL_RDP] > 0) nego->state = NEGO_STATE_RDP; @@ -230,7 +371,7 @@ void nego_attempt_rdp(rdpNego* nego) DEBUG_NEGO("Attempting RDP security"); - if (!nego_tcp_connect(nego)) + if (!nego_transport_connect(nego)) { nego->state = NEGO_STATE_FAIL; return; @@ -261,7 +402,7 @@ boolean nego_recv_response(rdpNego* nego) if (transport_read(nego->transport, s) < 0) return false; - return nego_recv(nego->transport, s, nego->transport->recv_extra); + return nego_recv(nego->transport, s, nego); } /** @@ -704,6 +845,18 @@ void nego_set_target(rdpNego* nego, char* hostname, int port) nego->port = port; } +/** + * Enable security layer negotiation. + * @param nego pointer to the negotiation structure + * @param enable_rdp whether to enable security layer negotiation (true for enabled, false for disabled) + */ + +void nego_set_negotiation_enabled(rdpNego* nego, boolean security_layer_negotiation_enabled) +{ + DEBUG_NEGO("Enabling security layer negotiation: %s", security_layer_negotiation_enabled ? "true" : "false"); + nego->security_layer_negotiation_enabled = security_layer_negotiation_enabled; +} + /** * Enable RDP security protocol. * @param nego pointer to the negotiation structure @@ -761,3 +914,36 @@ void nego_set_cookie(rdpNego* nego, char* cookie) { nego->cookie = cookie; } + +/** + * Enable / disable preconnection PDU. + * @param nego + * @param send_pcpdu + */ + +void nego_set_send_preconnection_pdu(rdpNego* nego, boolean send_pcpdu) +{ + nego->send_preconnection_pdu = send_pcpdu; +} + +/** + * Set preconnection id. + * @param nego + * @param id + */ + +void nego_set_preconnection_id(rdpNego* nego, uint32 id) +{ + nego->preconnection_id = id; +} + +/** + * Set preconnection blob. + * @param nego + * @param blob + */ + +void nego_set_preconnection_blob(rdpNego* nego, char* blob) +{ + nego->preconnection_blob = blob; +} diff --git a/libfreerdp-core/nego.h b/libfreerdp/core/nego.h similarity index 83% rename from libfreerdp-core/nego.h rename to libfreerdp/core/nego.h index 800b3b48c..cf30c94e9 100644 --- a/libfreerdp-core/nego.h +++ b/libfreerdp/core/nego.h @@ -68,24 +68,40 @@ enum RDP_NEG_MSG #define EXTENDED_CLIENT_DATA_SUPPORTED 0x01 +#define PRECONNECTION_PDU_V1_SIZE 16 +#define PRECONNECTION_PDU_V2_MIN_SIZE (PRECONNECTION_PDU_V1_SIZE+2) + +#define PRECONNECTION_PDU_V1 1 +#define PRECONNECTION_PDU_V2 2 + struct rdp_nego { int port; uint32 flags; char* hostname; char* cookie; - NEGO_STATE state; - int tcp_connected; rdpBlob* routing_token; + boolean send_preconnection_pdu; + uint32 preconnection_id; + char* preconnection_blob; + + NEGO_STATE state; + boolean tcp_connected; + boolean security_connected; + uint32 selected_protocol; uint32 requested_protocols; + boolean security_layer_negotiation_enabled; uint8 enabled_protocols[3]; + rdpTransport* transport; }; typedef struct rdp_nego rdpNego; boolean nego_connect(rdpNego* nego); +boolean nego_send_preconnection_pdu(rdpNego* nego); + void nego_attempt_nla(rdpNego* nego); void nego_attempt_tls(rdpNego* nego); void nego_attempt_rdp(rdpNego* nego); @@ -105,11 +121,15 @@ rdpNego* nego_new(struct rdp_transport * transport); void nego_free(rdpNego* nego); void nego_init(rdpNego* nego); void nego_set_target(rdpNego* nego, char* hostname, int port); +void nego_set_negotiation_enabled(rdpNego* nego, boolean security_layer_negotiation_enabled); void nego_enable_rdp(rdpNego* nego, boolean enable_rdp); void nego_enable_nla(rdpNego* nego, boolean enable_nla); void nego_enable_tls(rdpNego* nego, boolean enable_tls); void nego_set_routing_token(rdpNego* nego, rdpBlob* routing_token); void nego_set_cookie(rdpNego* nego, char* cookie); +void nego_set_send_preconnection_pdu(rdpNego* nego, boolean send_pcpdu); +void nego_set_preconnection_id(rdpNego* nego, uint32 id); +void nego_set_preconnection_blob(rdpNego* nego, char* blob); #ifdef WITH_DEBUG_NEGO #define DEBUG_NEGO(fmt, ...) DEBUG_CLASS(NEGO, fmt, ## __VA_ARGS__) diff --git a/libfreerdp-core/orders.c b/libfreerdp/core/orders.c similarity index 99% rename from libfreerdp-core/orders.c rename to libfreerdp/core/orders.c index 6c3380531..7256f2500 100644 --- a/libfreerdp-core/orders.c +++ b/libfreerdp/core/orders.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "window.h" #include #include diff --git a/libfreerdp-core/orders.h b/libfreerdp/core/orders.h similarity index 100% rename from libfreerdp-core/orders.h rename to libfreerdp/core/orders.h diff --git a/libfreerdp-core/peer.c b/libfreerdp/core/peer.c similarity index 99% rename from libfreerdp-core/peer.c rename to libfreerdp/core/peer.c index c33ff2bc4..353275e26 100644 --- a/libfreerdp-core/peer.c +++ b/libfreerdp/core/peer.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "certificate.h" #include diff --git a/libfreerdp-core/peer.h b/libfreerdp/core/peer.h similarity index 100% rename from libfreerdp-core/peer.h rename to libfreerdp/core/peer.h diff --git a/libfreerdp-core/rdp.c b/libfreerdp/core/rdp.c similarity index 99% rename from libfreerdp-core/rdp.c rename to libfreerdp/core/rdp.c index 6e48916a3..ad5c99f22 100644 --- a/libfreerdp-core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "rdp.h" #include "info.h" @@ -915,7 +919,8 @@ rdpRdp* rdp_new(freerdp* instance) if (instance != NULL) instance->settings = rdp->settings; - + + rdp->extension = extension_new(instance); rdp->transport = transport_new(rdp->settings); rdp->license = license_new(rdp); rdp->input = input_new(rdp); diff --git a/libfreerdp-core/rdp.h b/libfreerdp/core/rdp.h similarity index 99% rename from libfreerdp-core/rdp.h rename to libfreerdp/core/rdp.h index 16d779466..b327f8bce 100644 --- a/libfreerdp-core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -20,7 +20,10 @@ #ifndef __RDP_H #define __RDP_H +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include "mcs.h" #include "tpkt.h" #include "fastpath.h" diff --git a/libfreerdp-core/redirection.c b/libfreerdp/core/redirection.c similarity index 99% rename from libfreerdp-core/redirection.c rename to libfreerdp/core/redirection.c index 1139699d9..8fe1f7659 100644 --- a/libfreerdp-core/redirection.c +++ b/libfreerdp/core/redirection.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "connection.h" #include "redirection.h" diff --git a/libfreerdp-core/redirection.h b/libfreerdp/core/redirection.h similarity index 100% rename from libfreerdp-core/redirection.h rename to libfreerdp/core/redirection.h diff --git a/libfreerdp-core/rpc.c b/libfreerdp/core/rpc.c similarity index 99% rename from libfreerdp-core/rpc.c rename to libfreerdp/core/rpc.c index 874667488..c2080a874 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp/core/rpc.c @@ -18,7 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-core/rpc.h b/libfreerdp/core/rpc.h similarity index 100% rename from libfreerdp-core/rpc.h rename to libfreerdp/core/rpc.h diff --git a/libfreerdp-core/rts.c b/libfreerdp/core/rts.c similarity index 99% rename from libfreerdp-core/rts.c rename to libfreerdp/core/rts.c index a1032ab26..f14fd66f3 100644 --- a/libfreerdp-core/rts.c +++ b/libfreerdp/core/rts.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "rts.h" /** diff --git a/libfreerdp-core/rts.h b/libfreerdp/core/rts.h similarity index 99% rename from libfreerdp-core/rts.h rename to libfreerdp/core/rts.h index b7ce7ae2b..449c0e2b3 100644 --- a/libfreerdp-core/rts.h +++ b/libfreerdp/core/rts.h @@ -22,7 +22,9 @@ #include "rpc.h" +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include #include diff --git a/libfreerdp-core/security.c b/libfreerdp/core/security.c similarity index 99% rename from libfreerdp-core/security.c rename to libfreerdp/core/security.c index 9571f0011..0ce305e9f 100644 --- a/libfreerdp-core/security.c +++ b/libfreerdp/core/security.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "security.h" /* 0x36 repeated 40 times */ diff --git a/libfreerdp-core/security.h b/libfreerdp/core/security.h similarity index 100% rename from libfreerdp-core/security.h rename to libfreerdp/core/security.h diff --git a/libfreerdp-core/settings.c b/libfreerdp/core/settings.c similarity index 88% rename from libfreerdp-core/settings.c rename to libfreerdp/core/settings.c index 4540ed91c..4f38d5973 100644 --- a/libfreerdp-core/settings.c +++ b/libfreerdp/core/settings.c @@ -17,9 +17,13 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include "certificate.h" #include "capabilities.h" + #include #ifdef HAVE_UNISTD_H @@ -33,7 +37,7 @@ static const char client_dll[] = "C:\\Windows\\System32\\mstscax.dll"; -void settings_load_hkey_local_machine(rdpSettings* settings) +void settings_client_load_hkey_local_machine(rdpSettings* settings) { HKEY hKey; LONG status; @@ -41,7 +45,7 @@ void settings_load_hkey_local_machine(rdpSettings* settings) DWORD dwSize; DWORD dwValue; - status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Client"), 0, KEY_READ, &hKey); + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Client"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); if (status != ERROR_SUCCESS) return; @@ -76,6 +80,39 @@ void settings_load_hkey_local_machine(rdpSettings* settings) RegCloseKey(hKey); } +void settings_server_load_hkey_local_machine(rdpSettings* settings) +{ + HKEY hKey; + LONG status; + DWORD dwType; + DWORD dwSize; + DWORD dwValue; + + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + + if (status != ERROR_SUCCESS) + return; + + if (RegQueryValueEx(hKey, _T("NlaSecurity"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + settings->nla_security = dwValue ? 1 : 0; + + if (RegQueryValueEx(hKey, _T("TlsSecurity"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + settings->tls_security = dwValue ? 1 : 0; + + if (RegQueryValueEx(hKey, _T("RdpSecurity"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + settings->rdp_security = dwValue ? 1 : 0; + + RegCloseKey(hKey); +} + +void settings_load_hkey_local_machine(rdpSettings* settings) +{ + if (settings->server_mode) + settings_server_load_hkey_local_machine(settings); + else + settings_client_load_hkey_local_machine(settings); +} + rdpSettings* settings_new(void* instance) { rdpSettings* settings; @@ -86,6 +123,11 @@ rdpSettings* settings_new(void* instance) { settings->instance = instance; + /* Server instances are NULL */ + + if (!settings->instance) + settings->server_mode = true; + settings->width = 1024; settings->height = 768; settings->workarea = false; @@ -97,6 +139,7 @@ rdpSettings* settings_new(void* instance) settings->nla_security = true; settings->tls_security = true; settings->rdp_security = true; + settings->security_layer_negotiation = true; settings->client_build = 2600; settings->kbd_type = 4; /* @msdn{cc240510} 'IBM enhanced (101- or 102-key) keyboard' */ settings->kbd_subtype = 0; @@ -201,7 +244,7 @@ rdpSettings* settings_new(void* instance) settings->offscreen_bitmap_cache = true; settings->offscreen_bitmap_cache_size = 7680; - settings->offscreen_bitmap_cache_entries = 100; + settings->offscreen_bitmap_cache_entries = 2000; settings->draw_nine_grid_cache_size = 2560; settings->draw_nine_grid_cache_entries = 256; diff --git a/libfreerdp-core/surface.c b/libfreerdp/core/surface.c similarity index 98% rename from libfreerdp-core/surface.c rename to libfreerdp/core/surface.c index 32b62cbd6..0826f26e6 100644 --- a/libfreerdp-core/surface.c +++ b/libfreerdp/core/surface.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include "surface.h" diff --git a/libfreerdp-core/surface.h b/libfreerdp/core/surface.h similarity index 100% rename from libfreerdp-core/surface.h rename to libfreerdp/core/surface.h diff --git a/libfreerdp-core/tcp.c b/libfreerdp/core/tcp.c similarity index 99% rename from libfreerdp-core/tcp.c rename to libfreerdp/core/tcp.c index 7a40175eb..49b6f80b5 100644 --- a/libfreerdp-core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-core/tcp.h b/libfreerdp/core/tcp.h similarity index 100% rename from libfreerdp-core/tcp.h rename to libfreerdp/core/tcp.h diff --git a/libfreerdp-core/timezone.c b/libfreerdp/core/timezone.c similarity index 74% rename from libfreerdp-core/timezone.c rename to libfreerdp/core/timezone.c index 97e67bb45..071a59735 100644 --- a/libfreerdp-core/timezone.c +++ b/libfreerdp/core/timezone.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "timezone.h" /** @@ -55,6 +59,10 @@ void rdp_write_system_time(STREAM* s, SYSTEM_TIME* system_time) stream_write_uint16(s, system_time->wMinute); /* wMinute */ stream_write_uint16(s, system_time->wSecond); /* wSecond */ stream_write_uint16(s, system_time->wMilliseconds); /* wMilliseconds */ + DEBUG_TIMEZONE("Time: y=%d,m=%d,dow=%d,d=%d, %02d:%02d:%02d.%03d", + system_time->wYear, system_time->wMonth, system_time->wDayOfWeek, + system_time->wDay, system_time->wHour, system_time->wMinute, + system_time->wSecond, system_time->wMilliseconds); } /** @@ -106,6 +114,9 @@ boolean rdp_read_client_time_zone(STREAM* s, rdpSettings* settings) void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings) { + uint32 bias; + sint32 sbias; + uint32 bias2c; size_t length; uint8* standardName; uint8* daylightName; @@ -128,21 +139,56 @@ void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings) if (daylightNameLength > 62) daylightNameLength = 62; - stream_write_uint32(s, clientTimeZone->bias); /* Bias */ + /* UTC = LocalTime + Bias <-> Bias = UTC - LocalTime */ + + /* Translate from biases used throughout libfreerdp-locale/timezone.c + * to what RDP expects, which is minutes *west* of UTC. + * Though MS-RDPBCGR specifies bias as unsigned, two's complement + * (a negative integer) works fine for zones east of UTC. + */ + + if (clientTimeZone->bias <= 720) + bias = -1 * clientTimeZone->bias; + else + bias = 1440 - clientTimeZone->bias; + + stream_write_uint32(s, bias); /* Bias */ /* standardName (64 bytes) */ stream_write(s, standardName, standardNameLength); stream_write_zero(s, 64 - standardNameLength); rdp_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */ - stream_write_uint32(s, clientTimeZone->standardBias); /* StandardBias */ + DEBUG_TIMEZONE("bias=%d stdName='%s' dlName='%s'", + bias, clientTimeZone->standardName, clientTimeZone->daylightName); + + sbias = clientTimeZone->standardBias - clientTimeZone->bias; + + if (sbias < 0) + bias2c = (uint32) sbias; + else + bias2c = ~((uint32) sbias) + 1; + + /* Note that StandardBias is ignored if no valid standardDate is provided. */ + stream_write_uint32(s, bias2c); /* StandardBias */ + DEBUG_TIMEZONE("StandardBias=%d", bias2c); /* daylightName (64 bytes) */ stream_write(s, daylightName, daylightNameLength); stream_write_zero(s, 64 - daylightNameLength); rdp_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */ - stream_write_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */ + + sbias = clientTimeZone->daylightBias - clientTimeZone->bias; + + if (sbias < 0) + bias2c = (uint32) sbias; + else + bias2c = ~((uint32) sbias) + 1; + + /* Note that DaylightBias is ignored if no valid daylightDate is provided. */ + stream_write_uint32(s, bias2c); /* DaylightBias */ + DEBUG_TIMEZONE("DaylightBias=%d", bias2c); xfree(standardName); xfree(daylightName); diff --git a/libfreerdp-core/timezone.h b/libfreerdp/core/timezone.h similarity index 84% rename from libfreerdp-core/timezone.h rename to libfreerdp/core/timezone.h index f91c9ce87..79ef076fc 100644 --- a/libfreerdp-core/timezone.h +++ b/libfreerdp/core/timezone.h @@ -22,6 +22,10 @@ #include "rdp.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -32,4 +36,10 @@ void rdp_get_client_time_zone(STREAM* s, rdpSettings* settings); boolean rdp_read_client_time_zone(STREAM* s, rdpSettings* settings); void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings); +#ifdef WITH_DEBUG_TIMEZONE +#define DEBUG_TIMEZONE(fmt, ...) DEBUG_CLASS(TIMEZONE, fmt, ## __VA_ARGS__) +#else +#define DEBUG_TIMEZONE(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + #endif /* __TIMEZONE_H */ diff --git a/libfreerdp-core/tpdu.c b/libfreerdp/core/tpdu.c similarity index 98% rename from libfreerdp-core/tpdu.c rename to libfreerdp/core/tpdu.c index c1e0ffac3..8a3002123 100644 --- a/libfreerdp-core/tpdu.c +++ b/libfreerdp/core/tpdu.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include "tpdu.h" diff --git a/libfreerdp-core/tpdu.h b/libfreerdp/core/tpdu.h similarity index 100% rename from libfreerdp-core/tpdu.h rename to libfreerdp/core/tpdu.h diff --git a/libfreerdp-core/tpkt.c b/libfreerdp/core/tpkt.c similarity index 98% rename from libfreerdp-core/tpkt.c rename to libfreerdp/core/tpkt.c index 449a2aecf..6f5e287aa 100644 --- a/libfreerdp-core/tpkt.c +++ b/libfreerdp/core/tpkt.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "tpdu.h" #include "tpkt.h" diff --git a/libfreerdp-core/tpkt.h b/libfreerdp/core/tpkt.h similarity index 100% rename from libfreerdp-core/tpkt.h rename to libfreerdp/core/tpkt.h diff --git a/libfreerdp-core/transport.c b/libfreerdp/core/transport.c similarity index 99% rename from libfreerdp-core/transport.c rename to libfreerdp/core/transport.c index d6b164d33..4b2051e31 100644 --- a/libfreerdp-core/transport.c +++ b/libfreerdp/core/transport.c @@ -17,10 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-core/transport.h b/libfreerdp/core/transport.h similarity index 100% rename from libfreerdp-core/transport.h rename to libfreerdp/core/transport.h diff --git a/libfreerdp-core/tsg.c b/libfreerdp/core/tsg.c similarity index 99% rename from libfreerdp-core/tsg.c rename to libfreerdp/core/tsg.c index 6e4aaea89..1c738e936 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp/core/tsg.c @@ -18,7 +18,9 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include #include diff --git a/libfreerdp-core/tsg.h b/libfreerdp/core/tsg.h similarity index 100% rename from libfreerdp-core/tsg.h rename to libfreerdp/core/tsg.h diff --git a/libfreerdp-core/update.c b/libfreerdp/core/update.c similarity index 99% rename from libfreerdp-core/update.c rename to libfreerdp/core/update.c index 222458d43..bcb4ff1f6 100644 --- a/libfreerdp-core/update.c +++ b/libfreerdp/core/update.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "update.h" #include "surface.h" #include diff --git a/libfreerdp-core/update.h b/libfreerdp/core/update.h similarity index 100% rename from libfreerdp-core/update.h rename to libfreerdp/core/update.h diff --git a/libfreerdp-core/window.c b/libfreerdp/core/window.c similarity index 99% rename from libfreerdp-core/window.c rename to libfreerdp/core/window.c index 35058197e..a0de29fab 100644 --- a/libfreerdp-core/window.c +++ b/libfreerdp/core/window.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-core/window.h b/libfreerdp/core/window.h similarity index 100% rename from libfreerdp-core/window.h rename to libfreerdp/core/window.h diff --git a/libfreerdp-crypto/CMakeLists.txt b/libfreerdp/crypto/CMakeLists.txt similarity index 56% rename from libfreerdp-crypto/CMakeLists.txt rename to libfreerdp/crypto/CMakeLists.txt index a2f6822fc..554f7336e 100644 --- a/libfreerdp-crypto/CMakeLists.txt +++ b/libfreerdp/crypto/CMakeLists.txt @@ -27,21 +27,40 @@ set(FREERDP_CRYPTO_SRCS crypto.c tls.c) -add_library(freerdp-crypto ${FREERDP_CRYPTO_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(freerdp-crypto OBJECT ${FREERDP_CRYPTO_SRCS}) +else() + add_library(freerdp-crypto ${FREERDP_CRYPTO_SRCS}) +endif() include_directories(${OPENSSL_INCLUDE_DIR}) include_directories(${ZLIB_INCLUDE_DIRS}) set_target_properties(freerdp-crypto PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -if(WIN32) - target_link_libraries(freerdp-crypto ws2_32) +set(FREERDP_CRYPTO_LIBS + ${OPENSSL_LIBRARIES}) + +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_CRYPTO_LIBS ${FREERDP_CRYPTO_LIBS} winpr) else() - target_link_libraries(freerdp-crypto ${ZLIB_LIBRARIES}) + set(FREERDP_CRYPTO_LIBS ${FREERDP_CRYPTO_LIBS} winpr-sspi) + + if(NOT WIN32) + set(FREERDP_CRYPTO_LIBS ${FREERDP_CRYPTO_LIBS} winpr-library) + endif() endif() -target_link_libraries(freerdp-crypto winpr-sspi) -target_link_libraries(freerdp-crypto freerdp-utils) -target_link_libraries(freerdp-crypto ${OPENSSL_LIBRARIES}) +if(WIN32) + set(FREERDP_CRYPTO_LIBS ${FREERDP_CRYPTO_LIBS} ws2_32) +else() + set(FREERDP_CRYPTO_LIBS ${FREERDP_CRYPTO_LIBS} ${ZLIB_LIBRARIES}) +endif() -install(TARGETS freerdp-crypto DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_LIBS ${FREERDP_LIBS} ${FREERDP_CRYPTO_LIBS} PARENT_SCOPE) +else() + set(FREERDP_CRYPTO_LIBS ${FREERDP_CRYPTO_LIBS} freerdp-utils) + target_link_libraries(freerdp-crypto ${FREERDP_CRYPTO_LIBS}) + install(TARGETS freerdp-crypto DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/libfreerdp-crypto/ber.c b/libfreerdp/crypto/ber.c similarity index 99% rename from libfreerdp-crypto/ber.c rename to libfreerdp/crypto/ber.c index 0b30879ce..3fe817a40 100644 --- a/libfreerdp-crypto/ber.c +++ b/libfreerdp/crypto/ber.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include void ber_read_length(STREAM* s, int* length) diff --git a/libfreerdp-crypto/certificate.c b/libfreerdp/crypto/certificate.c similarity index 99% rename from libfreerdp-crypto/certificate.c rename to libfreerdp/crypto/certificate.c index da08ff7cf..61e0ab0f3 100644 --- a/libfreerdp-crypto/certificate.c +++ b/libfreerdp/crypto/certificate.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-crypto/crypto.c b/libfreerdp/crypto/crypto.c similarity index 99% rename from libfreerdp-crypto/crypto.c rename to libfreerdp/crypto/crypto.c index b6a73cc46..d5b0a7d54 100644 --- a/libfreerdp-crypto/crypto.c +++ b/libfreerdp/crypto/crypto.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include CryptoSha1 crypto_sha1_init(void) @@ -316,7 +320,7 @@ char* crypto_cert_fingerprint(X509* xcert) for (i = 0; i < (int) (fp_len - 1); i++) { sprintf(p, "%02x:", fp[i]); - p = &fp_buffer[i * 3]; + p = &fp_buffer[(i + 1) * 3]; } sprintf(p, "%02x", fp[i]); diff --git a/libfreerdp-crypto/der.c b/libfreerdp/crypto/der.c similarity index 97% rename from libfreerdp-crypto/der.c rename to libfreerdp/crypto/der.c index 395b94ec3..441496d83 100644 --- a/libfreerdp-crypto/der.c +++ b/libfreerdp/crypto/der.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include int _der_skip_length(int length) diff --git a/libfreerdp-crypto/er.c b/libfreerdp/crypto/er.c similarity index 99% rename from libfreerdp-crypto/er.c rename to libfreerdp/crypto/er.c index 3307b6ecd..efcc6a46c 100644 --- a/libfreerdp-crypto/er.c +++ b/libfreerdp/crypto/er.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-crypto/nla.c b/libfreerdp/crypto/nla.c similarity index 95% rename from libfreerdp-crypto/nla.c rename to libfreerdp/crypto/nla.c index b071168df..e98663b37 100644 --- a/libfreerdp-crypto/nla.c +++ b/libfreerdp/crypto/nla.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #ifndef _WIN32 @@ -29,6 +33,9 @@ #include #include #include +#include +#include +#include /** * TSRequest ::= SEQUENCE { @@ -393,20 +400,43 @@ int credssp_server_authenticate(rdpCredssp* credssp) #ifdef WITH_NATIVE_SSPI { HMODULE hSSPI; - INIT_SECURITY_INTERFACE InitSecurityInterface; - PSecurityFunctionTable pSecurityInterface = NULL; + INIT_SECURITY_INTERFACE pInitSecurityInterface; hSSPI = LoadLibrary(_T("secur32.dll")); #ifdef UNICODE - InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW"); + pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW"); #else - InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA"); + pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA"); #endif - credssp->table = (*InitSecurityInterface)(); + credssp->table = (*pInitSecurityInterface)(); } #else - credssp->table = InitSecurityInterface(); + if (credssp->SspiModule) + { + HMODULE hSSPI; + INIT_SECURITY_INTERFACE pInitSecurityInterface; + + hSSPI = LoadLibrary(credssp->SspiModule); + + if (!hSSPI) + { + _tprintf(_T("Failed to load SSPI module: %s\n"), credssp->SspiModule); + return 0; + } + +#ifdef UNICODE + pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW"); +#else + pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA"); +#endif + + credssp->table = (*pInitSecurityInterface)(); + } + else + { + credssp->table = InitSecurityInterface(); + } #endif status = credssp->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &pPackageInfo); @@ -448,7 +478,6 @@ int credssp_server_authenticate(rdpCredssp* credssp) fContextReq |= ASC_REQ_CONNECTION; fContextReq |= ASC_REQ_USE_SESSION_KEY; - fContextReq |= ASC_REQ_CONFIDENTIALITY; fContextReq |= ASC_REQ_REPLAY_DETECT; fContextReq |= ASC_REQ_SEQUENCE_DETECT; @@ -514,6 +543,14 @@ int credssp_server_authenticate(rdpCredssp* credssp) if (credssp->table->CompleteAuthToken != NULL) credssp->table->CompleteAuthToken(&credssp->context, &output_buffer_desc); + if (status == SEC_I_COMPLETE_NEEDED) + status = SEC_E_OK; + else if (status == SEC_I_COMPLETE_AND_CONTINUE) + status = SEC_I_CONTINUE_NEEDED; + } + + if (status == SEC_E_OK) + { have_pub_key_auth = true; if (credssp->table->QueryContextAttributes(&credssp->context, SECPKG_ATTR_SIZES, &credssp->ContextSizes) != SEC_E_OK) @@ -533,11 +570,6 @@ int credssp_server_authenticate(rdpCredssp* credssp) credssp->negoToken.cbBuffer = 0; credssp_encrypt_public_key_echo(credssp); - - if (status == SEC_I_COMPLETE_NEEDED) - status = SEC_E_OK; - else if (status == SEC_I_COMPLETE_AND_CONTINUE) - status = SEC_I_CONTINUE_NEEDED; } if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED)) @@ -1224,6 +1256,11 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTls* tls, rdpSettings* settings) if (credssp != NULL) { + HKEY hKey; + LONG status; + DWORD dwType; + DWORD dwSize; + credssp->instance = instance; credssp->settings = settings; credssp->server = settings->server_mode; @@ -1233,6 +1270,29 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTls* tls, rdpSettings* settings) ZeroMemory(&credssp->negoToken, sizeof(SecBuffer)); ZeroMemory(&credssp->pubKeyAuth, sizeof(SecBuffer)); ZeroMemory(&credssp->authInfo, sizeof(SecBuffer)); + + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), + 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + + if (status == ERROR_SUCCESS) + { + status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType, NULL, &dwSize); + + if (status == ERROR_SUCCESS) + { + credssp->SspiModule = (LPTSTR) malloc(dwSize + sizeof(TCHAR)); + + status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType, + (BYTE*) credssp->SspiModule, &dwSize); + + if (status == ERROR_SUCCESS) + { + _tprintf(_T("Using SSPI Module: %s\n"), credssp->SspiModule); + RegCloseKey(hKey); + } + } + } + } return credssp; diff --git a/libfreerdp-crypto/per.c b/libfreerdp/crypto/per.c similarity index 99% rename from libfreerdp-crypto/per.c rename to libfreerdp/crypto/per.c index 919e64f26..34d723647 100644 --- a/libfreerdp-crypto/per.c +++ b/libfreerdp/crypto/per.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include /** diff --git a/libfreerdp-crypto/tls.c b/libfreerdp/crypto/tls.c similarity index 99% rename from libfreerdp-crypto/tls.c rename to libfreerdp/crypto/tls.c index e577ea6b3..b4e8720ac 100644 --- a/libfreerdp-crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -278,7 +282,8 @@ boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_fi boolean tls_disconnect(rdpTls* tls) { - SSL_shutdown(tls->ssl); + if (tls->ssl) + SSL_shutdown(tls->ssl); return true; } diff --git a/libfreerdp-gdi/16bpp.c b/libfreerdp/gdi/16bpp.c similarity index 99% rename from libfreerdp-gdi/16bpp.c rename to libfreerdp/gdi/16bpp.c index 46ca0df69..fee35ef76 100644 --- a/libfreerdp-gdi/16bpp.c +++ b/libfreerdp/gdi/16bpp.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-gdi/32bpp.c b/libfreerdp/gdi/32bpp.c similarity index 99% rename from libfreerdp-gdi/32bpp.c rename to libfreerdp/gdi/32bpp.c index 0d5fbd228..570bb2e1c 100644 --- a/libfreerdp-gdi/32bpp.c +++ b/libfreerdp/gdi/32bpp.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-gdi/8bpp.c b/libfreerdp/gdi/8bpp.c similarity index 99% rename from libfreerdp-gdi/8bpp.c rename to libfreerdp/gdi/8bpp.c index bddf3277e..f4fce0f9f 100644 --- a/libfreerdp-gdi/8bpp.c +++ b/libfreerdp/gdi/8bpp.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-gdi/CMakeLists.txt b/libfreerdp/gdi/CMakeLists.txt similarity index 67% rename from libfreerdp-gdi/CMakeLists.txt rename to libfreerdp/gdi/CMakeLists.txt index 599134821..2513b0673 100644 --- a/libfreerdp-gdi/CMakeLists.txt +++ b/libfreerdp/gdi/CMakeLists.txt @@ -17,6 +17,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + set(FREERDP_GDI_SRCS 8bpp.c 16bpp.c @@ -36,12 +38,25 @@ set(FREERDP_GDI_SRCS gdi.c gdi.h) -add_library(freerdp-gdi ${FREERDP_GDI_SRCS}) - -target_link_libraries(freerdp-gdi freerdp-core) -target_link_libraries(freerdp-gdi freerdp-cache) -target_link_libraries(freerdp-gdi freerdp-codec) +if(WITH_MONOLITHIC_BUILD) + add_library(freerdp-gdi OBJECT ${FREERDP_GDI_SRCS}) +else() + add_library(freerdp-gdi ${FREERDP_GDI_SRCS}) +endif() set_target_properties(freerdp-gdi PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -install(TARGETS freerdp-gdi DESTINATION ${CMAKE_INSTALL_LIBDIR}) +set(FREERDP_GDI_LIBS) + +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_LIBS ${FREERDP_LIBS} ${FREERDP_GDI_LIBS} PARENT_SCOPE) +else() + set(FREERDP_GDI_LIBS ${FREERDP_GDI_LIBS} + freerdp-core + freerdp-cache + freerdp-codec) + + target_link_libraries(freerdp-gdi ${FREERDP_GDI_LIBS}) + install(TARGETS freerdp-gdi DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + diff --git a/libfreerdp-gdi/bitmap.c b/libfreerdp/gdi/bitmap.c similarity index 99% rename from libfreerdp-gdi/bitmap.c rename to libfreerdp/gdi/bitmap.c index a1f980a39..d9d326c44 100644 --- a/libfreerdp-gdi/bitmap.c +++ b/libfreerdp/gdi/bitmap.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-gdi/brush.c b/libfreerdp/gdi/brush.c similarity index 97% rename from libfreerdp-gdi/brush.c rename to libfreerdp/gdi/brush.c index d77702e8c..74f991e2f 100644 --- a/libfreerdp-gdi/brush.c +++ b/libfreerdp/gdi/brush.c @@ -19,6 +19,10 @@ /* GDI Brush Functions: http://msdn.microsoft.com/en-us/library/dd183395/ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-gdi/clipping.c b/libfreerdp/gdi/clipping.c similarity index 98% rename from libfreerdp-gdi/clipping.c rename to libfreerdp/gdi/clipping.c index c805a43c0..7c3b71672 100644 --- a/libfreerdp-gdi/clipping.c +++ b/libfreerdp/gdi/clipping.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include diff --git a/libfreerdp-gdi/dc.c b/libfreerdp/gdi/dc.c similarity index 99% rename from libfreerdp-gdi/dc.c rename to libfreerdp/gdi/dc.c index 63a754e68..24efc4dc9 100644 --- a/libfreerdp-gdi/dc.c +++ b/libfreerdp/gdi/dc.c @@ -19,9 +19,14 @@ /* Device Context Functions: http://msdn.microsoft.com/en-us/library/dd183554 */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-gdi/drawing.c b/libfreerdp/gdi/drawing.c similarity index 98% rename from libfreerdp-gdi/drawing.c rename to libfreerdp/gdi/drawing.c index 98f50c316..2a62055f9 100644 --- a/libfreerdp-gdi/drawing.c +++ b/libfreerdp/gdi/drawing.c @@ -19,6 +19,10 @@ /* GDI Drawing Functions: http://msdn.microsoft.com/en-us/library/dd162760/ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-gdi/gdi.c b/libfreerdp/gdi/gdi.c similarity index 99% rename from libfreerdp-gdi/gdi.c rename to libfreerdp/gdi/gdi.c index 99b9829ae..c97a2005c 100644 --- a/libfreerdp-gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-gdi/gdi.h b/libfreerdp/gdi/gdi.h similarity index 97% rename from libfreerdp-gdi/gdi.h rename to libfreerdp/gdi/gdi.h index edf8950dc..99fa73683 100644 --- a/libfreerdp-gdi/gdi.h +++ b/libfreerdp/gdi/gdi.h @@ -20,7 +20,6 @@ #ifndef __GDI_CORE_H #define __GDI_CORE_H -#include "config.h" #include "graphics.h" gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, uint8* data); diff --git a/libfreerdp-gdi/graphics.c b/libfreerdp/gdi/graphics.c similarity index 78% rename from libfreerdp-gdi/graphics.c rename to libfreerdp/gdi/graphics.c index 04816334c..bef0c6e61 100644 --- a/libfreerdp-gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -17,11 +17,17 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include #include +#include +#include #include #include #include @@ -87,9 +93,17 @@ void gdi_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) } void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, - uint8* data, int width, int height, int bpp, int length, boolean compressed) + uint8* data, int width, int height, int bpp, int length, + boolean compressed, int codec_id) { uint16 size; + RFX_MESSAGE* msg; + uint8* src; + uint8* dst; + int yindex; + int xindex; + rdpGdi* gdi; + boolean status; size = width * height * (bpp + 7) / 8; @@ -98,21 +112,59 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, else bitmap->data = (uint8*) xrealloc(bitmap->data, size); - if (compressed) + switch (codec_id) { - boolean status; - - status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); - - if (status != true) - { - printf("Bitmap Decompression Failed\n"); - } - } - else - { - freerdp_image_flip(data, bitmap->data, width, height, bpp); + case CODEC_ID_NSCODEC: + printf("gdi_Bitmap_Decompress: nsc not done\n"); + break; + case CODEC_ID_REMOTEFX: + gdi = context->gdi; + rfx_context_set_pixel_format(gdi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); + msg = rfx_process_message(gdi->rfx_context, data, length); + if (msg == NULL) + { + printf("gdi_Bitmap_Decompress: rfx Decompression Failed\n"); + } + else + { + for (yindex = 0; yindex < height; yindex++) + { + src = msg->tiles[0]->data + yindex * 64 * 4; + dst = bitmap->data + yindex * width * 3; + for (xindex = 0; xindex < width; xindex++) + { + *(dst++) = *(src++); + *(dst++) = *(src++); + *(dst++) = *(src++); + src++; + } + } + rfx_message_free(gdi->rfx_context, msg); + } + break; + case CODEC_ID_JPEG: +#ifdef WITH_JPEG + if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp)) + { + printf("gdi_Bitmap_Decompress: jpeg Decompression Failed\n"); + } +#endif + break; + default: + if (compressed) + { + status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); + if (status == false) + { + printf("gdi_Bitmap_Decompress: Bitmap Decompression Failed\n"); + } + } + else + { + freerdp_image_flip(data, bitmap->data, width, height, bpp); + } + break; } bitmap->width = width; @@ -236,4 +288,3 @@ void gdi_register_graphics(rdpGraphics* graphics) graphics_register_glyph(graphics, glyph); xfree(glyph); } - diff --git a/libfreerdp-gdi/graphics.h b/libfreerdp/gdi/graphics.h similarity index 91% rename from libfreerdp-gdi/graphics.h rename to libfreerdp/gdi/graphics.h index 3940a44be..930c5e860 100644 --- a/libfreerdp-gdi/graphics.h +++ b/libfreerdp/gdi/graphics.h @@ -28,7 +28,8 @@ HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int width, int height, int bpp, uint8 void gdi_Bitmap_New(rdpContext* context, rdpBitmap* bitmap); void gdi_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap); void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, - uint8* data, int width, int height, int bpp, int length, boolean compressed); + uint8* data, int width, int height, int bpp, int length, + boolean compressed, int codec_id); void gdi_register_graphics(rdpGraphics* graphics); #endif /* __GDI_GRAPHICS_H */ diff --git a/libfreerdp-gdi/include/line.c b/libfreerdp/gdi/include/line.c similarity index 100% rename from libfreerdp-gdi/include/line.c rename to libfreerdp/gdi/include/line.c diff --git a/libfreerdp-gdi/line.c b/libfreerdp/gdi/line.c similarity index 98% rename from libfreerdp-gdi/line.c rename to libfreerdp/gdi/line.c index 014e90431..fafc73d69 100644 --- a/libfreerdp-gdi/line.c +++ b/libfreerdp/gdi/line.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-gdi/palette.c b/libfreerdp/gdi/palette.c similarity index 98% rename from libfreerdp-gdi/palette.c rename to libfreerdp/gdi/palette.c index 86ecf3b07..2db3f722f 100644 --- a/libfreerdp-gdi/palette.c +++ b/libfreerdp/gdi/palette.c @@ -19,6 +19,10 @@ /* GDI Palette Functions: http://msdn.microsoft.com/en-us/library/dd183454/ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-gdi/pen.c b/libfreerdp/gdi/pen.c similarity index 97% rename from libfreerdp-gdi/pen.c rename to libfreerdp/gdi/pen.c index 7c662c918..beee3ef72 100644 --- a/libfreerdp-gdi/pen.c +++ b/libfreerdp/gdi/pen.c @@ -19,6 +19,10 @@ /* GDI Pen Functions: http://msdn.microsoft.com/en-us/library/dd162790 */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-gdi/region.c b/libfreerdp/gdi/region.c similarity index 99% rename from libfreerdp-gdi/region.c rename to libfreerdp/gdi/region.c index b2520e9bf..c6d59de61 100644 --- a/libfreerdp-gdi/region.c +++ b/libfreerdp/gdi/region.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-gdi/shape.c b/libfreerdp/gdi/shape.c similarity index 98% rename from libfreerdp-gdi/shape.c rename to libfreerdp/gdi/shape.c index 4ae449abe..894b04530 100644 --- a/libfreerdp-gdi/shape.c +++ b/libfreerdp/gdi/shape.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include diff --git a/libfreerdp-locale/CMakeLists.txt b/libfreerdp/locale/CMakeLists.txt similarity index 77% rename from libfreerdp-locale/CMakeLists.txt rename to libfreerdp/locale/CMakeLists.txt index 0d7b2a498..8e9c27035 100644 --- a/libfreerdp-locale/CMakeLists.txt +++ b/libfreerdp/locale/CMakeLists.txt @@ -47,7 +47,7 @@ if(CMAKE_SYSTEM_NAME MATCHES Solaris) set(WITH_SUN true) endif() -set(FREERDP_LOCALE_LINK_LIBRARIES freerdp-utils) +set(FREERDP_LOCALE_LIBS) if(NOT WIN32) find_suggested_package(X11) @@ -55,7 +55,7 @@ if(NOT WIN32) add_definitions(-DWITH_X11) include_directories(${X11_INCLUDE_DIRS}) set(FREERDP_LOCALE_SRCS ${FREERDP_LOCALE_SRCS} ${FREERDP_LOCALE_X11_SRCS}) - set(FREERDP_LOCALE_LINK_LIBRARIES ${FREERDP_LOCALE_LINK_LIBRARIES} ${X11_LIBRARIES}) + set(FREERDP_LOCALE_LIBS ${FREERDP_LOCALE_LIBS} ${X11_LIBRARIES}) if(WITH_SUN) add_definitions(-DWITH_SUN) set(FREERDP_LOCALE_SRCS ${FREERDP_LOCALE_SRCS} ${FREERDP_LOCALE_SUN_SRCS}) @@ -66,17 +66,25 @@ if(NOT WIN32) add_definitions(-DWITH_XKBFILE) include_directories(${XKBFILE_INCLUDE_DIRS}) set(FREERDP_LOCALE_SRCS ${FREERDP_LOCALE_SRCS} ${FREERDP_LOCALE_XKBFILE_SRCS}) - set(FREERDP_LOCALE_LINK_LIBRARIES ${FREERDP_LOCALE_LINK_LIBRARIES} ${XKBFILE_LIBRARIES}) + set(FREERDP_LOCALE_LIBS ${FREERDP_LOCALE_LIBS} ${XKBFILE_LIBRARIES}) else() set(FREERDP_LOCALE_SRCS ${FREERDP_LOCALE_SRCS} ${FREERDP_LOCALE_X11_KEYMAP_SRCS}) endif() endif() endif() -add_library(freerdp-locale ${FREERDP_LOCALE_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(freerdp-locale OBJECT ${FREERDP_LOCALE_SRCS}) +else() + add_library(freerdp-locale ${FREERDP_LOCALE_SRCS}) +endif() set_target_properties(freerdp-locale PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -target_link_libraries(freerdp-locale ${FREERDP_LOCALE_LINK_LIBRARIES}) - -install(TARGETS freerdp-locale DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_LIBS ${FREERDP_LIBS} ${FREERDP_LOCALE_LIBS} PARENT_SCOPE) +else() + set(FREERDP_LOCALE_LIBS ${FREERDP_LOCALE_LIBS} freerdp-utils) + target_link_libraries(freerdp-locale ${FREERDP_LOCALE_LIBS}) + install(TARGETS freerdp-locale DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/libfreerdp-locale/keyboard.c b/libfreerdp/locale/keyboard.c similarity index 98% rename from libfreerdp-locale/keyboard.c rename to libfreerdp/locale/keyboard.c index a42876206..2e563e787 100644 --- a/libfreerdp-locale/keyboard.c +++ b/libfreerdp/locale/keyboard.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-locale/keyboard_keymap.c b/libfreerdp/locale/keyboard_keymap.c similarity index 99% rename from libfreerdp-locale/keyboard_keymap.c rename to libfreerdp/locale/keyboard_keymap.c index 67fca77c2..5e74e2795 100644 --- a/libfreerdp-locale/keyboard_keymap.c +++ b/libfreerdp/locale/keyboard_keymap.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "keyboard_keymap.h" #include @@ -24,7 +28,6 @@ #include #include -#include "config.h" #include "liblocale.h" #include diff --git a/libfreerdp-locale/keyboard_keymap.h b/libfreerdp/locale/keyboard_keymap.h similarity index 100% rename from libfreerdp-locale/keyboard_keymap.h rename to libfreerdp/locale/keyboard_keymap.h diff --git a/libfreerdp-locale/keyboard_layout.c b/libfreerdp/locale/keyboard_layout.c similarity index 99% rename from libfreerdp-locale/keyboard_layout.c rename to libfreerdp/locale/keyboard_layout.c index 202759ab5..52d2a1934 100644 --- a/libfreerdp-locale/keyboard_layout.c +++ b/libfreerdp/locale/keyboard_layout.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include "liblocale.h" #include diff --git a/libfreerdp-locale/keyboard_sun.c b/libfreerdp/locale/keyboard_sun.c similarity index 99% rename from libfreerdp-locale/keyboard_sun.c rename to libfreerdp/locale/keyboard_sun.c index 19a49a4b9..aa41e1cf6 100644 --- a/libfreerdp-locale/keyboard_sun.c +++ b/libfreerdp/locale/keyboard_sun.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-locale/keyboard_sun.h b/libfreerdp/locale/keyboard_sun.h similarity index 100% rename from libfreerdp-locale/keyboard_sun.h rename to libfreerdp/locale/keyboard_sun.h diff --git a/libfreerdp-locale/keyboard_x11.c b/libfreerdp/locale/keyboard_x11.c similarity index 99% rename from libfreerdp-locale/keyboard_x11.c rename to libfreerdp/locale/keyboard_x11.c index 7f73e2ba0..55737d697 100644 --- a/libfreerdp-locale/keyboard_x11.c +++ b/libfreerdp/locale/keyboard_x11.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-locale/keyboard_x11.h b/libfreerdp/locale/keyboard_x11.h similarity index 100% rename from libfreerdp-locale/keyboard_x11.h rename to libfreerdp/locale/keyboard_x11.h diff --git a/libfreerdp-locale/keyboard_xkbfile.c b/libfreerdp/locale/keyboard_xkbfile.c similarity index 99% rename from libfreerdp-locale/keyboard_xkbfile.c rename to libfreerdp/locale/keyboard_xkbfile.c index 73dca77f3..2d13a8d30 100644 --- a/libfreerdp-locale/keyboard_xkbfile.c +++ b/libfreerdp/locale/keyboard_xkbfile.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "keyboard_xkbfile.h" #include diff --git a/libfreerdp-locale/keyboard_xkbfile.h b/libfreerdp/locale/keyboard_xkbfile.h similarity index 100% rename from libfreerdp-locale/keyboard_xkbfile.h rename to libfreerdp/locale/keyboard_xkbfile.h diff --git a/libfreerdp-locale/liblocale.h b/libfreerdp/locale/liblocale.h similarity index 82% rename from libfreerdp-locale/liblocale.h rename to libfreerdp/locale/liblocale.h index e1449b84d..27c0987c9 100644 --- a/libfreerdp-locale/liblocale.h +++ b/libfreerdp/locale/liblocale.h @@ -20,7 +20,10 @@ #ifndef __LIBLOCALE_H #define __LIBLOCALE_H +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #ifdef WITH_DEBUG_KBD @@ -29,4 +32,10 @@ #define DEBUG_KBD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #endif +#ifdef WITH_DEBUG_TIMEZONE +#define DEBUG_TIMEZONE(fmt, ...) DEBUG_CLASS(TIMEZONE, fmt, ## __VA_ARGS__) +#else +#define DEBUG_TIMEZONE(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + #endif /* __LIBLOCALE_H */ diff --git a/libfreerdp-locale/locale.c b/libfreerdp/locale/locale.c similarity index 99% rename from libfreerdp-locale/locale.c rename to libfreerdp/locale/locale.c index 2a6c71707..82362ef78 100644 --- a/libfreerdp-locale/locale.c +++ b/libfreerdp/locale/locale.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include "liblocale.h" #include diff --git a/libfreerdp-locale/timezone.c b/libfreerdp/locale/timezone.c similarity index 57% rename from libfreerdp-locale/timezone.c rename to libfreerdp/locale/timezone.c index a788855d7..0508fb5c1 100644 --- a/libfreerdp-locale/timezone.c +++ b/libfreerdp/locale/timezone.c @@ -17,11 +17,15 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include -#include "config.h" +#include "liblocale.h" #include #include @@ -30,6 +34,7 @@ /* Time Zone Redirection table generated with TimeZones.cs script */ + struct _SYSTEM_TIME_ENTRY { uint16 wYear; @@ -68,1032 +73,1034 @@ typedef struct _TIME_ZONE_ENTRY TIME_ZONE_ENTRY; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_3[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633032352000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633032244000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_4[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_5[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633032352000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633032244000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_7[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_8[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633032352000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633032244000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_10[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633032352000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633032244000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_11[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_14[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633032352000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633032244000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_15[] = { - { 633031488000000000ULL, 632716992000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633032352000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 633031380000000000ULL, 632716884000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633032244000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_17[] = { - { 633663072000000000ULL, 288000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634925376000000000ULL, 634610016000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635240736000000000ULL, 634926240000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635556096000000000ULL, 635241600000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635871456000000000ULL, 635556960000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636187680000000000ULL, 635872320000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636503040000000000ULL, 636188544000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 9, 6, 1, 23, 59 }, }, - { 636818400000000000ULL, 636503904000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637133760000000000ULL, 636819264000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637449984000000000ULL, 637134624000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 3155378400000000000ULL, 637450848000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, } + { 633662964000000000ULL, 180000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634925268000000000ULL, 634609908000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635240628000000000ULL, 634926132000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635555988000000000ULL, 635241492000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635871348000000000ULL, 635556852000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636187572000000000ULL, 635872212000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636502932000000000ULL, 636188436000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 9, 6, 1, 23, 59 }, }, + { 636818292000000000ULL, 636503796000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637133652000000000ULL, 636819156000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637449876000000000ULL, 637134516000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 3155378292000000000ULL, 637450740000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_18[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633032352000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633032244000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_19[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 2, 0, 1, 2, 0 }, { 0, 11, 0, 1, 0, 0 }, }, - { 633346848000000000ULL, 633032352000000000ULL, 60, { 0, 2, 0, 1, 0, 0 }, { 0, 10, 0, 1, 0, 0 }, }, - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 2, 0, 1, 0, 0 }, { 0, 10, 6, 1, 23, 59 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634925376000000000ULL, 634610016000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635240736000000000ULL, 634926240000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635556096000000000ULL, 635241600000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635871456000000000ULL, 635556960000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636187680000000000ULL, 635872320000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636503040000000000ULL, 636188544000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636818400000000000ULL, 636503904000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637133760000000000ULL, 636819264000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637449984000000000ULL, 637134624000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637765344000000000ULL, 637450848000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 638080704000000000ULL, 637766208000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 638396064000000000ULL, 638081568000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 638712288000000000ULL, 638396928000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639027648000000000ULL, 638713152000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639343008000000000ULL, 639028512000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639658368000000000ULL, 639343872000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639974592000000000ULL, 639659232000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 640289952000000000ULL, 639975456000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 640605312000000000ULL, 640290816000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 640920672000000000ULL, 640606176000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 641236896000000000ULL, 640921536000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 641552256000000000ULL, 641237760000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 641867616000000000ULL, 641553120000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 642182976000000000ULL, 641868480000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 642499200000000000ULL, 642183840000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 642814560000000000ULL, 642500064000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 643129920000000000ULL, 642815424000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 643445280000000000ULL, 643130784000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 3155378400000000000ULL, 643446144000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 2, 0, 1, 2, 0 }, { 0, 11, 0, 1, 0, 0 }, }, + { 633346740000000000ULL, 633032244000000000ULL, 60, { 0, 2, 0, 1, 0, 0 }, { 0, 10, 0, 1, 0, 0 }, }, + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 2, 0, 1, 0, 0 }, { 0, 10, 6, 1, 23, 59 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634925268000000000ULL, 634609908000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635240628000000000ULL, 634926132000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635555988000000000ULL, 635241492000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635871348000000000ULL, 635556852000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636187572000000000ULL, 635872212000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636502932000000000ULL, 636188436000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636818292000000000ULL, 636503796000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637133652000000000ULL, 636819156000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637449876000000000ULL, 637134516000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637765236000000000ULL, 637450740000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 638080596000000000ULL, 637766100000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 638395956000000000ULL, 638081460000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 638712180000000000ULL, 638396820000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639027540000000000ULL, 638713044000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639342900000000000ULL, 639028404000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639658260000000000ULL, 639343764000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639974484000000000ULL, 639659124000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 640289844000000000ULL, 639975348000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 640605204000000000ULL, 640290708000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 640920564000000000ULL, 640606068000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 641236788000000000ULL, 640921428000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 641552148000000000ULL, 641237652000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 641867508000000000ULL, 641553012000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 642182868000000000ULL, 641868372000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 642499092000000000ULL, 642183732000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 642814452000000000ULL, 642499956000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 643129812000000000ULL, 642815316000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 643445172000000000ULL, 643130676000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 3155378292000000000ULL, 643446036000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_21[] = { - { 633346848000000000ULL, 288000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 5, 6, 1, 23, 59 }, { 0, 8, 6, 1, 23, 59 }, }, - { 3155378400000000000ULL, 634610016000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, } + { 633346740000000000ULL, 180000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 4, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 5, 6, 1, 23, 59 }, { 0, 8, 6, 1, 23, 59 }, }, + { 3155378292000000000ULL, 634609908000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_22[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 0, 1 }, { 0, 4, 0, 1, 0, 1 }, }, - { 633346848000000000ULL, 633032352000000000ULL, 60, { 0, 11, 0, 1, 0, 1 }, { 0, 3, 0, 1, 0, 1 }, }, - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 11, 0, 1, 0, 1 }, { 0, 3, 0, 1, 0, 1 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 11, 0, 1, 0, 1 }, { 0, 3, 0, 1, 0, 1 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 11, 0, 1, 0, 1 }, { 0, 3, 0, 1, 0, 1 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 0, 1 }, }, - { 3155378400000000000ULL, 634610016000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 0, 1 }, { 0, 4, 0, 1, 0, 1 }, }, + { 633346740000000000ULL, 633032244000000000ULL, 60, { 0, 11, 0, 1, 0, 1 }, { 0, 3, 0, 1, 0, 1 }, }, + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 11, 0, 1, 0, 1 }, { 0, 3, 0, 1, 0, 1 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 11, 0, 1, 0, 1 }, { 0, 3, 0, 1, 0, 1 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 11, 0, 1, 0, 1 }, { 0, 3, 0, 1, 0, 1 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 0, 1 }, }, + { 3155378292000000000ULL, 634609908000000000ULL, 60, { 0, 11, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_23[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 2, 0, 1, 2, 0 }, { 0, 11, 0, 1, 0, 0 }, }, - { 633346848000000000ULL, 633032352000000000ULL, 60, { 0, 2, 0, 1, 0, 0 }, { 0, 10, 0, 1, 0, 0 }, }, - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 2, 0, 1, 0, 0 }, { 0, 10, 6, 1, 23, 59 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634925376000000000ULL, 634610016000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635240736000000000ULL, 634926240000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635556096000000000ULL, 635241600000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635871456000000000ULL, 635556960000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636187680000000000ULL, 635872320000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636503040000000000ULL, 636188544000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636818400000000000ULL, 636503904000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637133760000000000ULL, 636819264000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637449984000000000ULL, 637134624000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637765344000000000ULL, 637450848000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 638080704000000000ULL, 637766208000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 638396064000000000ULL, 638081568000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 638712288000000000ULL, 638396928000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639027648000000000ULL, 638713152000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639343008000000000ULL, 639028512000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639658368000000000ULL, 639343872000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639974592000000000ULL, 639659232000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 640289952000000000ULL, 639975456000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 640605312000000000ULL, 640290816000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 640920672000000000ULL, 640606176000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 641236896000000000ULL, 640921536000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 641552256000000000ULL, 641237760000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 641867616000000000ULL, 641553120000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 642182976000000000ULL, 641868480000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 642499200000000000ULL, 642183840000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 642814560000000000ULL, 642500064000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 643129920000000000ULL, 642815424000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 643445280000000000ULL, 643130784000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 3155378400000000000ULL, 643446144000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 2, 0, 1, 2, 0 }, { 0, 11, 0, 1, 0, 0 }, }, + { 633346740000000000ULL, 633032244000000000ULL, 60, { 0, 2, 0, 1, 0, 0 }, { 0, 10, 0, 1, 0, 0 }, }, + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 2, 0, 1, 0, 0 }, { 0, 10, 6, 1, 23, 59 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634925268000000000ULL, 634609908000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635240628000000000ULL, 634926132000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635555988000000000ULL, 635241492000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635871348000000000ULL, 635556852000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636187572000000000ULL, 635872212000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636502932000000000ULL, 636188436000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636818292000000000ULL, 636503796000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637133652000000000ULL, 636819156000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637449876000000000ULL, 637134516000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637765236000000000ULL, 637450740000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 638080596000000000ULL, 637766100000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 638395956000000000ULL, 638081460000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 638712180000000000ULL, 638396820000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639027540000000000ULL, 638713044000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639342900000000000ULL, 639028404000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639658260000000000ULL, 639343764000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639974484000000000ULL, 639659124000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 640289844000000000ULL, 639975348000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 640605204000000000ULL, 640290708000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 640920564000000000ULL, 640606068000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 641236788000000000ULL, 640921428000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 641552148000000000ULL, 641237652000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 641867508000000000ULL, 641553012000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 642182868000000000ULL, 641868372000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 642499092000000000ULL, 642183732000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 642814452000000000ULL, 642499956000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 643129812000000000ULL, 642815316000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 643445172000000000ULL, 643130676000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 3155378292000000000ULL, 643446036000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_24[] = { - { 633346848000000000ULL, 633032352000000000ULL, 60, { 0, 1, 1, 1, 0, 0 }, { 0, 12, 0, 1, 0, 0 }, }, - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 3, 0, 1, 0, 0 }, { 0, 10, 6, 1, 23, 59 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 1, 4, 1, 0, 0 }, } + { 633346740000000000ULL, 633032244000000000ULL, 60, { 0, 1, 1, 1, 0, 0 }, { 0, 12, 0, 1, 0, 0 }, }, + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 3, 0, 1, 0, 0 }, { 0, 10, 6, 1, 23, 59 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 3, 6, 1, 23, 59 }, { 0, 1, 4, 1, 0, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_26[] = { - { 633663072000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 634925376000000000ULL, 634610016000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 635240736000000000ULL, 634926240000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 635556096000000000ULL, 635241600000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 635871456000000000ULL, 635556960000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 636187680000000000ULL, 635872320000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 636503040000000000ULL, 636188544000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 636818400000000000ULL, 636503904000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 637133760000000000ULL, 636819264000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 637449984000000000ULL, 637134624000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, - { 3155378400000000000ULL, 637450848000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, } + { 633662964000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 634925268000000000ULL, 634609908000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 635240628000000000ULL, 634926132000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 635555988000000000ULL, 635241492000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 635871348000000000ULL, 635556852000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 636187572000000000ULL, 635872212000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 636502932000000000ULL, 636188436000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 636818292000000000ULL, 636503796000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 637133652000000000ULL, 636819156000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 637449876000000000ULL, 637134516000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, }, + { 3155378292000000000ULL, 637450740000000000ULL, 60, { 0, 10, 6, 1, 23, 0 }, { 0, 3, 6, 1, 22, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_27[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 3, 0, 1, 2, 0 }, { 0, 9, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633032352000000000ULL, 60, { 0, 3, 0, 1, 2, 0 }, { 0, 10, 0, 1, 2, 0 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 3, 0, 1, 2, 0 }, { 0, 9, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633032244000000000ULL, 60, { 0, 3, 0, 1, 2, 0 }, { 0, 10, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_28[] = { - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 1, 6, 1, 0, 0 }, { 0, 10, 6, 1, 23, 59 }, }, - { 634925376000000000ULL, 634610016000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635240736000000000ULL, 634926240000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635556096000000000ULL, 635241600000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 635871456000000000ULL, 635556960000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636187680000000000ULL, 635872320000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636503040000000000ULL, 636188544000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 636818400000000000ULL, 636503904000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637133760000000000ULL, 636819264000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637449984000000000ULL, 637134624000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 637765344000000000ULL, 637450848000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 638080704000000000ULL, 637766208000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 638396064000000000ULL, 638081568000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 638712288000000000ULL, 638396928000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639027648000000000ULL, 638713152000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639343008000000000ULL, 639028512000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639658368000000000ULL, 639343872000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 639974592000000000ULL, 639659232000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 640289952000000000ULL, 639975456000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 640605312000000000ULL, 640290816000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 640920672000000000ULL, 640606176000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 641236896000000000ULL, 640921536000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 641552256000000000ULL, 641237760000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 641867616000000000ULL, 641553120000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 642182976000000000ULL, 641868480000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 642499200000000000ULL, 642183840000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 642814560000000000ULL, 642500064000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 643129920000000000ULL, 642815424000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 643445280000000000ULL, 643130784000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, - { 3155378400000000000ULL, 643446144000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, } + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 1, 6, 1, 0, 0 }, { 0, 10, 6, 1, 23, 59 }, }, + { 634925268000000000ULL, 634609908000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635240628000000000ULL, 634926132000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635555988000000000ULL, 635241492000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 635871348000000000ULL, 635556852000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636187572000000000ULL, 635872212000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636502932000000000ULL, 636188436000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 636818292000000000ULL, 636503796000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637133652000000000ULL, 636819156000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637449876000000000ULL, 637134516000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 637765236000000000ULL, 637450740000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 638080596000000000ULL, 637766100000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 638395956000000000ULL, 638081460000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 638712180000000000ULL, 638396820000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639027540000000000ULL, 638713044000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639342900000000000ULL, 639028404000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639658260000000000ULL, 639343764000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 639974484000000000ULL, 639659124000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 640289844000000000ULL, 639975348000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 640605204000000000ULL, 640290708000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 640920564000000000ULL, 640606068000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 641236788000000000ULL, 640921428000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 641552148000000000ULL, 641237652000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 641867508000000000ULL, 641553012000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 642182868000000000ULL, 641868372000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 642499092000000000ULL, 642183732000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 642814452000000000ULL, 642499956000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 643129812000000000ULL, 642815316000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 643445172000000000ULL, 643130676000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, }, + { 3155378292000000000ULL, 643446036000000000ULL, 60, { 0, 2, 6, 1, 23, 59 }, { 0, 10, 6, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_30[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_31[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_33[] = { - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 8, 0, 1, 23, 59 }, { 0, 5, 6, 1, 23, 59 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 8, 4, 1, 23, 59 }, { 0, 5, 0, 1, 23, 59 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 8, 6, 1, 23, 59 }, { 0, 5, 6, 1, 23, 59 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 7, 6, 1, 23, 59 }, { 0, 4, 6, 1, 23, 59 }, } + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 8, 0, 1, 23, 59 }, { 0, 5, 6, 1, 23, 59 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 8, 4, 1, 23, 59 }, { 0, 5, 0, 1, 23, 59 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 8, 6, 1, 23, 59 }, { 0, 5, 6, 1, 23, 59 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 7, 6, 1, 23, 59 }, { 0, 4, 6, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_35[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 3, 0, 1, 1, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 3, 0, 1, 1, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_37[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_38[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_39[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_40[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_42[] = { - { 634293792000000000ULL, 288000000000ULL, -60, { 0, 9, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 634294656000000000ULL, 60, { 0, 4, 0, 1, 2, 0 }, { 0, 9, 0, 1, 2, 0 }, } + { 634293684000000000ULL, 180000000000ULL, -60, { 0, 9, 0, 1, 2, 0 }, { 0, 4, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 634294548000000000ULL, 60, { 0, 4, 0, 1, 2, 0 }, { 0, 9, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_43[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 9, 5, 1, 1, 0 }, { 0, 3, 4, 1, 0, 0 }, }, - { 3155378400000000000ULL, 633032352000000000ULL, 60, { 0, 10, 5, 1, 1, 0 }, { 0, 3, 4, 1, 23, 59 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 9, 5, 1, 1, 0 }, { 0, 3, 4, 1, 0, 0 }, }, + { 3155378292000000000ULL, 633032244000000000ULL, 60, { 0, 10, 5, 1, 1, 0 }, { 0, 3, 4, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_44[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 3, 0, 1, 3, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 3, 0, 1, 3, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_45[] = { - { 633978432000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 0, 0 }, { 0, 3, 0, 1, 0, 0 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 634925376000000000ULL, 634610016000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 635240736000000000ULL, 634926240000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 635556096000000000ULL, 635241600000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 635871456000000000ULL, 635556960000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 636187680000000000ULL, 635872320000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 636503040000000000ULL, 636188544000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 636818400000000000ULL, 636503904000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 637133760000000000ULL, 636819264000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 637449984000000000ULL, 637134624000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, - { 3155378400000000000ULL, 637450848000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, } + { 633978324000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 0, 0 }, { 0, 3, 0, 1, 0, 0 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 634925268000000000ULL, 634609908000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 635240628000000000ULL, 634926132000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 635555988000000000ULL, 635241492000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 635871348000000000ULL, 635556852000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 636187572000000000ULL, 635872212000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 636502932000000000ULL, 636188436000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 636818292000000000ULL, 636503796000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 637133652000000000ULL, 636819156000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 637449876000000000ULL, 637134516000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, }, + { 3155378292000000000ULL, 637450740000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_46[] = { - { 632716128000000000ULL, 288000000000ULL, 60, { 0, 9, 4, 1, 23, 59 }, { 0, 4, 5, 1, 0, 0 }, }, - { 633031488000000000ULL, 632716992000000000ULL, 60, { 0, 9, 4, 1, 23, 59 }, { 0, 4, 5, 1, 0, 0 }, }, - { 633346848000000000ULL, 633032352000000000ULL, 60, { 0, 9, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 8, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 8, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 9, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, } + { 632716020000000000ULL, 180000000000ULL, 60, { 0, 9, 4, 1, 23, 59 }, { 0, 4, 5, 1, 0, 0 }, }, + { 633031380000000000ULL, 632716884000000000ULL, 60, { 0, 9, 4, 1, 23, 59 }, { 0, 4, 5, 1, 0, 0 }, }, + { 633346740000000000ULL, 633032244000000000ULL, 60, { 0, 9, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 8, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 8, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 9, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_47[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 9, 3, 1, 23, 59 }, { 0, 3, 5, 1, 23, 59 }, }, - { 633346848000000000ULL, 633032352000000000ULL, 60, { 0, 11, 4, 1, 23, 59 }, { 0, 3, 4, 1, 23, 59 }, }, - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 10, 5, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 3, 4, 1, 23, 59 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 3, 4, 1, 23, 59 }, }, - { 634925376000000000ULL, 634610016000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, - { 635240736000000000ULL, 634926240000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, - { 635556096000000000ULL, 635241600000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, - { 635871456000000000ULL, 635556960000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, - { 636187680000000000ULL, 635872320000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 3, 4, 1, 23, 59 }, }, - { 3155378400000000000ULL, 636188544000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 9, 3, 1, 23, 59 }, { 0, 3, 5, 1, 23, 59 }, }, + { 633346740000000000ULL, 633032244000000000ULL, 60, { 0, 11, 4, 1, 23, 59 }, { 0, 3, 4, 1, 23, 59 }, }, + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 10, 5, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 3, 4, 1, 23, 59 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 3, 4, 1, 23, 59 }, }, + { 634925268000000000ULL, 634609908000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, + { 635240628000000000ULL, 634926132000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, + { 635555988000000000ULL, 635241492000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, + { 635871348000000000ULL, 635556852000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, }, + { 636187572000000000ULL, 635872212000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 3, 4, 1, 23, 59 }, }, + { 3155378292000000000ULL, 636188436000000000ULL, 60, { 0, 10, 4, 1, 23, 59 }, { 0, 4, 4, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_49[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 3, 0, 1, 3, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 3, 0, 1, 3, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_50[] = { - { 634293792000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 3, 0, 1, 3, 0 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 3, 1, 1, 3, 0 }, }, - { 3155378400000000000ULL, 634610016000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 3, 0, 1, 3, 0 }, } + { 634293684000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 3, 0, 1, 3, 0 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 3, 1, 1, 3, 0 }, }, + { 3155378292000000000ULL, 634609908000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 3, 0, 1, 3, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_51[] = { - { 632716128000000000ULL, 632401632000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 5, 1, 2, 0 }, }, - { 633031488000000000ULL, 632716992000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 633346848000000000ULL, 633032352000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 5, 1, 2, 0 }, }, - { 634925376000000000ULL, 634610016000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 635240736000000000ULL, 634926240000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 635556096000000000ULL, 635241600000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 635871456000000000ULL, 635556960000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 636187680000000000ULL, 635872320000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 5, 1, 2, 0 }, }, - { 636503040000000000ULL, 636188544000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 636818400000000000ULL, 636503904000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 637133760000000000ULL, 636819264000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 637449984000000000ULL, 637134624000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 637765344000000000ULL, 637450848000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, - { 638080704000000000ULL, 637766208000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 5, 1, 2, 0 }, } + { 632716020000000000ULL, 632401524000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 5, 1, 2, 0 }, }, + { 633031380000000000ULL, 632716884000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 633346740000000000ULL, 633032244000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 5, 1, 2, 0 }, }, + { 634925268000000000ULL, 634609908000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 635240628000000000ULL, 634926132000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 635555988000000000ULL, 635241492000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 635871348000000000ULL, 635556852000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 636187572000000000ULL, 635872212000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 5, 1, 2, 0 }, }, + { 636502932000000000ULL, 636188436000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 636818292000000000ULL, 636503796000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 637133652000000000ULL, 636819156000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 637449876000000000ULL, 637134516000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 637765236000000000ULL, 637450740000000000ULL, 60, { 0, 9, 0, 1, 2, 0 }, { 0, 3, 5, 1, 2, 0 }, }, + { 638080596000000000ULL, 637766100000000000ULL, 60, { 0, 10, 0, 1, 2, 0 }, { 0, 4, 5, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_52[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_53[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 4, 0, 1, 3, 0 }, }, - { 633346848000000000ULL, 633032352000000000ULL, 60, { 0, 10, 1, 1, 4, 0 }, { 0, 4, 0, 1, 3, 0 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 4, 0 }, { 0, 4, 0, 1, 3, 0 }, }, + { 633346740000000000ULL, 633032244000000000ULL, 60, { 0, 10, 1, 1, 4, 0 }, { 0, 4, 0, 1, 3, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_54[] = { - { 634293792000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 634293684000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_57[] = { - { 632716128000000000ULL, 288000000000ULL, 60, { 0, 9, 2, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, }, - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 9, 6, 1, 23, 59 }, { 0, 3, 4, 1, 23, 59 }, }, - { 3155378400000000000ULL, 633663936000000000ULL, 60, { 0, 9, 1, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, } + { 632716020000000000ULL, 180000000000ULL, 60, { 0, 9, 2, 1, 2, 0 }, { 0, 3, 0, 1, 2, 0 }, }, + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 9, 6, 1, 23, 59 }, { 0, 3, 4, 1, 23, 59 }, }, + { 3155378292000000000ULL, 633663828000000000ULL, 60, { 0, 9, 1, 1, 23, 59 }, { 0, 3, 6, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_59[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 5, 0 }, { 0, 3, 0, 1, 4, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 5, 0 }, { 0, 3, 0, 1, 4, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_60[] = { - { 634293792000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 634293684000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_61[] = { - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 1, 2, 1, 0, 0 }, { 0, 10, 0, 1, 2, 0 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 3, 0, 1, 2, 0 }, { 0, 1, 4, 1, 0, 0 }, } + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 1, 2, 1, 0, 0 }, { 0, 10, 0, 1, 2, 0 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 3, 0, 1, 2, 0 }, { 0, 1, 4, 1, 0, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_63[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_65[] = { - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 10, 5, 1, 23, 59 }, { 0, 5, 6, 1, 23, 59 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 4, 2, 1, 23, 59 }, } + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 10, 5, 1, 23, 59 }, { 0, 5, 6, 1, 23, 59 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 10, 6, 1, 23, 59 }, { 0, 4, 2, 1, 23, 59 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_71[] = { - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 12, 4, 1, 23, 59 }, { 0, 6, 5, 1, 23, 0 }, } + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 12, 4, 1, 23, 59 }, { 0, 6, 5, 1, 23, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_72[] = { - { 634293792000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 634293684000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_75[] = { - { 634293792000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 634293684000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_77[] = { - { 634293792000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 634293684000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_79[] = { - { 633031488000000000ULL, 632716992000000000ULL, 60, { 0, 1, 0, 1, 0, 0 }, { 0, 12, 0, 1, 2, 0 }, }, - { 633346848000000000ULL, 633032352000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, - { 633663072000000000ULL, 633347712000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 1, 4, 1, 0, 0 }, } + { 633031380000000000ULL, 632716884000000000ULL, 60, { 0, 1, 0, 1, 0, 0 }, { 0, 12, 0, 1, 2, 0 }, }, + { 633346740000000000ULL, 633032244000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, + { 633662964000000000ULL, 633347604000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 1, 4, 1, 0, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_82[] = { - { 634293792000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 634293684000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_85[] = { - { 633346848000000000ULL, 288000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633347712000000000ULL, 60, { 0, 4, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, } + { 633346740000000000ULL, 180000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633347604000000000ULL, 60, { 0, 4, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_88[] = { - { 633346848000000000ULL, 288000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633347712000000000ULL, 60, { 0, 4, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, } + { 633346740000000000ULL, 180000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633347604000000000ULL, 60, { 0, 4, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_90[] = { - { 633346848000000000ULL, 288000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633347712000000000ULL, 60, { 0, 4, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, } + { 633346740000000000ULL, 180000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633347604000000000ULL, 60, { 0, 4, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_91[] = { - { 634293792000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 634293684000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_93[] = { - { 634293792000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 634293684000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_94[] = { - { 633031488000000000ULL, 288000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, - { 633346848000000000ULL, 633032352000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 9, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 633347712000000000ULL, 60, { 0, 4, 0, 1, 3, 0 }, { 0, 9, 0, 1, 2, 0 }, } + { 633031380000000000ULL, 180000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, + { 633346740000000000ULL, 633032244000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 9, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 633347604000000000ULL, 60, { 0, 4, 0, 1, 3, 0 }, { 0, 9, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_96[] = { - { 633978432000000000ULL, 633663936000000000ULL, 60, { 0, 1, 4, 1, 0, 0 }, { 0, 11, 0, 1, 2, 0 }, }, - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, - { 634609152000000000ULL, 634294656000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, - { 634925376000000000ULL, 634610016000000000ULL, 60, { 0, 1, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, - { 3155378400000000000ULL, 634926240000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, } + { 633978324000000000ULL, 633663828000000000ULL, 60, { 0, 1, 4, 1, 0, 0 }, { 0, 11, 0, 1, 2, 0 }, }, + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, + { 634609044000000000ULL, 634294548000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, + { 634925268000000000ULL, 634609908000000000ULL, 60, { 0, 1, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, }, + { 3155378292000000000ULL, 634926132000000000ULL, 60, { 0, 3, 0, 1, 3, 0 }, { 0, 10, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_97[] = { - { 634293792000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 634293684000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_98[] = { - { 3155378400000000000ULL, 288000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } + { 3155378292000000000ULL, 180000000000ULL, 60, { 0, 10, 0, 1, 3, 0 }, { 0, 3, 0, 1, 2, 0 }, } }; static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_100[] = { - { 634293792000000000ULL, 633979296000000000ULL, 60, { 0, 1, 5, 1, 0, 0 }, { 0, 9, 6, 1, 23, 59 }, }, - { 3155378400000000000ULL, 634294656000000000ULL, 60, { 0, 4, 0, 1, 1, 0 }, { 0, 9, 0, 1, 0, 0 }, } + { 634293684000000000ULL, 633979188000000000ULL, 60, { 0, 1, 5, 1, 0, 0 }, { 0, 9, 6, 1, 23, 59 }, }, + { 3155378292000000000ULL, 634294548000000000ULL, 60, { 0, 4, 0, 1, 1, 0 }, { 0, 9, 0, 1, 0, 0 }, } }; static const TIME_ZONE_ENTRY TimeZoneTable[] = { { - "Dateline Standard Time", 1440, false, "Dateline Standard Time", - "Dateline Standard Time", "Dateline Standard Time", + "Dateline Standard Time", 720, false, "(UTC-12:00) International Date Line West", + "Dateline Standard Time", "Dateline Daylight Time", NULL, 0 }, { - "UTC-11", 1380, false, "UTC-11", + "UTC-11", 780, false, "(UTC-11:00) Coordinated Universal Time-11", "UTC-11", "UTC-11", NULL, 0 }, { - "Hawaiian Standard Time", 1320, false, "Hawaiian Standard Time", - "Hawaiian Standard Time", "Hawaiian Standard Time", + "Hawaiian Standard Time", 840, false, "(UTC-10:00) Hawaii", + "Hawaiian Standard Time", "Hawaiian Daylight Time", NULL, 0 }, { - "Alaskan Standard Time", 1260, true, "Alaskan Standard Time", - "Alaskan Standard Time", "Alaskan Standard Time", + "Alaskan Standard Time", 900, true, "(UTC-09:00) Alaska", + "Alaskan Standard Time", "Alaskan Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_3, 2 }, { - "Pacific Standard Time (Mexico)", 1200, true, "Pacific Standard Time (Mexico)", - "Pacific Standard Time (Mexico)", "Pacific Standard Time (Mexico)", + "Pacific Standard Time (Mexico)", 960, true, "(UTC-08:00) Baja California", + "Pacific Standard Time (Mexico)", "Pacific Daylight Time (Mexico)", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_4, 1 }, { - "Pacific Standard Time", 1200, true, "Pacific Standard Time", - "Pacific Standard Time", "Pacific Standard Time", + "Pacific Standard Time", 960, true, "(UTC-08:00) Pacific Time (US & Canada)", + "Pacific Standard Time", "Pacific Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_5, 2 }, { - "US Mountain Standard Time", 1140, false, "US Mountain Standard Time", - "US Mountain Standard Time", "US Mountain Standard Time", + "US Mountain Standard Time", 1020, false, "(UTC-07:00) Arizona", + "US Mountain Standard Time", "US Mountain Daylight Time", NULL, 0 }, { - "Mountain Standard Time (Mexico)", 1140, true, "Mountain Standard Time (Mexico)", - "Mountain Standard Time (Mexico)", "Mountain Standard Time (Mexico)", + "Mountain Standard Time (Mexico)", 1020, true, "(UTC-07:00) Chihuahua, La Paz, Mazatlan", + "Mountain Standard Time (Mexico)", "Mountain Daylight Time (Mexico)", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_7, 1 }, { - "Mountain Standard Time", 1140, true, "Mountain Standard Time", - "Mountain Standard Time", "Mountain Standard Time", + "Mountain Standard Time", 1020, true, "(UTC-07:00) Mountain Time (US & Canada)", + "Mountain Standard Time", "Mountain Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_8, 2 }, { - "Central America Standard Time", 1080, false, "Central America Standard Time", - "Central America Standard Time", "Central America Standard Time", + "Central America Standard Time", 1080, false, "(UTC-06:00) Central America", + "Central America Standard Time", "Central America Daylight Time", NULL, 0 }, { - "Central Standard Time", 1080, true, "Central Standard Time", - "Central Standard Time", "Central Standard Time", + "Central Standard Time", 1080, true, "(UTC-06:00) Central Time (US & Canada)", + "Central Standard Time", "Central Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_10, 2 }, { - "Central Standard Time (Mexico)", 1080, true, "Central Standard Time (Mexico)", - "Central Standard Time (Mexico)", "Central Standard Time (Mexico)", + "Central Standard Time (Mexico)", 1080, true, "(UTC-06:00) Guadalajara, Mexico City, Monterrey", + "Central Standard Time (Mexico)", "Central Daylight Time (Mexico)", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_11, 1 }, { - "Canada Central Standard Time", 1080, false, "Canada Central Standard Time", - "Canada Central Standard Time", "Canada Central Standard Time", + "Canada Central Standard Time", 1080, false, "(UTC-06:00) Saskatchewan", + "Canada Central Standard Time", "Canada Central Daylight Time", NULL, 0 }, { - "SA Pacific Standard Time", 1020, false, "SA Pacific Standard Time", - "SA Pacific Standard Time", "SA Pacific Standard Time", + "SA Pacific Standard Time", 1140, false, "(UTC-05:00) Bogota, Lima, Quito", + "SA Pacific Standard Time", "SA Pacific Daylight Time", NULL, 0 }, { - "Eastern Standard Time", 1020, true, "Eastern Standard Time", - "Eastern Standard Time", "Eastern Standard Time", + "Eastern Standard Time", 1140, true, "(UTC-05:00) Eastern Time (US & Canada)", + "Eastern Standard Time", "Eastern Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_14, 2 }, { - "US Eastern Standard Time", 1020, true, "US Eastern Standard Time", - "US Eastern Standard Time", "US Eastern Standard Time", + "US Eastern Standard Time", 1140, true, "(UTC-05:00) Indiana (East)", + "US Eastern Standard Time", "US Eastern Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_15, 2 }, { - "Venezuela Standard Time", 930, false, "Venezuela Standard Time", - "Venezuela Standard Time", "Venezuela Standard Time", + "Venezuela Standard Time", 1170, false, "(UTC-04:30) Caracas", + "Venezuela Standard Time", "Venezuela Daylight Time", NULL, 0 }, { - "Paraguay Standard Time", 960, true, "Paraguay Standard Time", - "Paraguay Standard Time", "Paraguay Standard Time", + "Paraguay Standard Time", 1200, true, "(UTC-04:00) Asuncion", + "Paraguay Standard Time", "Paraguay Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_17, 14 }, { - "Atlantic Standard Time", 960, true, "Atlantic Standard Time", - "Atlantic Standard Time", "Atlantic Standard Time", + "Atlantic Standard Time", 1200, true, "(UTC-04:00) Atlantic Time (Canada)", + "Atlantic Standard Time", "Atlantic Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_18, 2 }, { - "Central Brazilian Standard Time", 960, true, "Central Brazilian Standard Time", - "Central Brazilian Standard Time", "Central Brazilian Standard Time", + "Central Brazilian Standard Time", 1200, true, "(UTC-04:00) Cuiaba", + "Central Brazilian Standard Time", "Central Brazilian Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_19, 35 }, { - "SA Western Standard Time", 960, false, "SA Western Standard Time", - "SA Western Standard Time", "SA Western Standard Time", + "SA Western Standard Time", 1200, false, "(UTC-04:00) Georgetown, La Paz, Manaus, San Juan", + "SA Western Standard Time", "SA Western Daylight Time", NULL, 0 }, { - "Pacific SA Standard Time", 960, true, "Pacific SA Standard Time", - "Pacific SA Standard Time", "Pacific SA Standard Time", + "Pacific SA Standard Time", 1200, true, "(UTC-04:00) Santiago", + "Pacific SA Standard Time", "Pacific SA Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_21, 6 }, { - "Newfoundland Standard Time", 870, true, "Newfoundland Standard Time", - "Newfoundland Standard Time", "Newfoundland Standard Time", + "Newfoundland Standard Time", 1230, true, "(UTC-03:30) Newfoundland", + "Newfoundland Standard Time", "Newfoundland Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_22, 7 }, { - "E. South America Standard Time", 900, true, "E. South America Standard Time", - "E. South America Standard Time", "E. South America Standard Time", + "E. South America Standard Time", 1260, true, "(UTC-03:00) Brasilia", + "E. South America Standard Time", "E. South America Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_23, 35 }, { - "Argentina Standard Time", 900, true, "Argentina Standard Time", - "Argentina Standard Time", "Argentina Standard Time", + "Argentina Standard Time", 1260, true, "(UTC-03:00) Buenos Aires", + "Argentina Standard Time", "Argentina Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_24, 3 }, { - "SA Eastern Standard Time", 900, false, "SA Eastern Standard Time", - "SA Eastern Standard Time", "SA Eastern Standard Time", + "SA Eastern Standard Time", 1260, false, "(UTC-03:00) Cayenne, Fortaleza", + "SA Eastern Standard Time", "SA Eastern Daylight Time", NULL, 0 }, { - "Greenland Standard Time", 900, true, "Greenland Standard Time", - "Greenland Standard Time", "Greenland Standard Time", + "Greenland Standard Time", 1260, true, "(UTC-03:00) Greenland", + "Greenland Standard Time", "Greenland Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_26, 14 }, { - "Montevideo Standard Time", 900, true, "Montevideo Standard Time", - "Montevideo Standard Time", "Montevideo Standard Time", + "Montevideo Standard Time", 1260, true, "(UTC-03:00) Montevideo", + "Montevideo Standard Time", "Montevideo Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_27, 2 }, { - "Bahia Standard Time", 900, true, "Bahia Standard Time", - "Bahia Standard Time", "Bahia Standard Time", + "Bahia Standard Time", 1260, true, "(UTC-03:00) Salvador", + "Bahia Standard Time", "Bahia Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_28, 30 }, { - "UTC-02", 840, false, "UTC-02", + "UTC-02", 1320, false, "(UTC-02:00) Coordinated Universal Time-02", "UTC-02", "UTC-02", NULL, 0 }, { - "Mid-Atlantic Standard Time", 840, true, "Mid-Atlantic Standard Time", - "Mid-Atlantic Standard Time", "Mid-Atlantic Standard Time", + "Mid-Atlantic Standard Time", 1320, true, "(UTC-02:00) Mid-Atlantic", + "Mid-Atlantic Standard Time", "Mid-Atlantic Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_30, 1 }, { - "Azores Standard Time", 780, true, "Azores Standard Time", - "Azores Standard Time", "Azores Standard Time", + "Azores Standard Time", 1380, true, "(UTC-01:00) Azores", + "Azores Standard Time", "Azores Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_31, 1 }, { - "Cape Verde Standard Time", 780, false, "Cape Verde Standard Time", - "Cape Verde Standard Time", "Cape Verde Standard Time", + "Cape Verde Standard Time", 1380, false, "(UTC-01:00) Cape Verde Is.", + "Cape Verde Standard Time", "Cape Verde Daylight Time", NULL, 0 }, { - "Morocco Standard Time", 0, true, "Morocco Standard Time", - "Morocco Standard Time", "Morocco Standard Time", + "Morocco Standard Time", 0, true, "(UTC) Casablanca", + "Morocco Standard Time", "Morocco Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_33, 4 }, { - "UTC", 0, false, "UTC", + "UTC", 0, false, "(UTC) Coordinated Universal Time", "Coordinated Universal Time", "Coordinated Universal Time", NULL, 0 }, { - "GMT Standard Time", 0, true, "GMT Standard Time", - "GMT Standard Time", "GMT Standard Time", + "GMT Standard Time", 0, true, "(UTC) Dublin, Edinburgh, Lisbon, London", + "GMT Standard Time", "GMT Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_35, 1 }, { - "Greenwich Standard Time", 0, false, "Greenwich Standard Time", - "Greenwich Standard Time", "Greenwich Standard Time", + "Greenwich Standard Time", 0, false, "(UTC) Monrovia, Reykjavik", + "Greenwich Standard Time", "Greenwich Daylight Time", NULL, 0 }, { - "W. Europe Standard Time", 60, true, "W. Europe Standard Time", - "W. Europe Standard Time", "W. Europe Standard Time", + "W. Europe Standard Time", 60, true, "(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna", + "W. Europe Standard Time", "W. Europe Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_37, 1 }, { - "Central Europe Standard Time", 60, true, "Central Europe Standard Time", - "Central Europe Standard Time", "Central Europe Standard Time", + "Central Europe Standard Time", 60, true, "(UTC+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague", + "Central Europe Standard Time", "Central Europe Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_38, 1 }, { - "Romance Standard Time", 60, true, "Romance Standard Time", - "Romance Standard Time", "Romance Standard Time", + "Romance Standard Time", 60, true, "(UTC+01:00) Brussels, Copenhagen, Madrid, Paris", + "Romance Standard Time", "Romance Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_39, 1 }, { - "Central European Standard Time", 60, true, "Central European Standard Time", - "Central European Standard Time", "Central European Standard Time", + "Central European Standard Time", 60, true, "(UTC+01:00) Sarajevo, Skopje, Warsaw, Zagreb", + "Central European Standard Time", "Central European Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_40, 1 }, { - "W. Central Africa Standard Time", 60, false, "W. Central Africa Standard Time", - "W. Central Africa Standard Time", "W. Central Africa Standard Time", + "W. Central Africa Standard Time", 60, false, "(UTC+01:00) West Central Africa", + "W. Central Africa Standard Time", "W. Central Africa Daylight Time", NULL, 0 }, { - "Namibia Standard Time", 60, true, "Namibia Standard Time", - "Namibia Standard Time", "Namibia Standard Time", + "Namibia Standard Time", 60, true, "(UTC+01:00) Windhoek", + "Namibia Standard Time", "Namibia Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_42, 2 }, { - "Jordan Standard Time", 120, true, "Jordan Standard Time", - "Jordan Standard Time", "Jordan Standard Time", + "Jordan Standard Time", 120, true, "(UTC+02:00) Amman", + "Jordan Standard Time", "Jordan Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_43, 2 }, { - "GTB Standard Time", 120, true, "GTB Standard Time", - "GTB Standard Time", "GTB Standard Time", + "GTB Standard Time", 120, true, "(UTC+02:00) Athens, Bucharest, Istanbul", + "GTB Standard Time", "GTB Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_44, 1 }, { - "Middle East Standard Time", 120, true, "Middle East Standard Time", - "Middle East Standard Time", "Middle East Standard Time", + "Middle East Standard Time", 120, true, "(UTC+02:00) Beirut", + "Middle East Standard Time", "Middle East Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_45, 13 }, { - "Egypt Standard Time", 120, true, "Egypt Standard Time", - "Egypt Standard Time", "Egypt Standard Time", + "Egypt Standard Time", 120, true, "(UTC+02:00) Cairo", + "Egypt Standard Time", "Egypt Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_46, 6 }, { - "Syria Standard Time", 120, true, "Syria Standard Time", - "Syria Standard Time", "Syria Standard Time", + "Syria Standard Time", 120, true, "(UTC+02:00) Damascus", + "Syria Standard Time", "Syria Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_47, 12 }, { - "South Africa Standard Time", 120, false, "South Africa Standard Time", - "South Africa Standard Time", "South Africa Standard Time", + "South Africa Standard Time", 120, false, "(UTC+02:00) Harare, Pretoria", + "South Africa Standard Time", "South Africa Daylight Time", NULL, 0 }, { - "FLE Standard Time", 120, true, "FLE Standard Time", - "FLE Standard Time", "FLE Standard Time", + "FLE Standard Time", 120, true, "(UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius", + "FLE Standard Time", "FLE Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_49, 1 }, { - "Turkey Standard Time", 120, true, "Turkey Standard Time", - "Turkey Standard Time", "Turkey Standard Time", + "Turkey Standard Time", 120, true, "(UTC+02:00) Istanbul", + "Turkey Standard Time", "Turkey Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_50, 3 }, { - "Israel Standard Time", 120, true, "Israel Standard Time", - "Jerusalem Standard Time", "Jerusalem Standard Time", + "Israel Standard Time", 120, true, "(UTC+02:00) Jerusalem", + "Jerusalem Standard Time", "Jerusalem Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_51, 18 }, { - "E. Europe Standard Time", 120, true, "E. Europe Standard Time", - "E. Europe Standard Time", "E. Europe Standard Time", + "E. Europe Standard Time", 120, true, "(UTC+02:00) Nicosia", + "E. Europe Standard Time", "E. Europe Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_52, 1 }, { - "Arabic Standard Time", 180, true, "Arabic Standard Time", - "Arabic Standard Time", "Arabic Standard Time", + "Arabic Standard Time", 180, true, "(UTC+03:00) Baghdad", + "Arabic Standard Time", "Arabic Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_53, 2 }, { - "Kaliningrad Standard Time", 180, true, "Kaliningrad Standard Time", - "Kaliningrad Standard Time", "Kaliningrad Standard Time", + "Kaliningrad Standard Time", 180, true, "(UTC+03:00) Kaliningrad, Minsk", + "Kaliningrad Standard Time", "Kaliningrad Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_54, 1 }, { - "Arab Standard Time", 180, false, "Arab Standard Time", - "Arab Standard Time", "Arab Standard Time", + "Arab Standard Time", 180, false, "(UTC+03:00) Kuwait, Riyadh", + "Arab Standard Time", "Arab Daylight Time", NULL, 0 }, { - "E. Africa Standard Time", 180, false, "E. Africa Standard Time", - "E. Africa Standard Time", "E. Africa Standard Time", + "E. Africa Standard Time", 180, false, "(UTC+03:00) Nairobi", + "E. Africa Standard Time", "E. Africa Daylight Time", NULL, 0 }, { - "Iran Standard Time", 210, true, "Iran Standard Time", - "Iran Standard Time", "Iran Standard Time", + "Iran Standard Time", 210, true, "(UTC+03:30) Tehran", + "Iran Standard Time", "Iran Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_57, 3 }, { - "Arabian Standard Time", 240, false, "Arabian Standard Time", - "Arabian Standard Time", "Arabian Standard Time", + "Arabian Standard Time", 240, false, "(UTC+04:00) Abu Dhabi, Muscat", + "Arabian Standard Time", "Arabian Daylight Time", NULL, 0 }, { - "Azerbaijan Standard Time", 240, true, "Azerbaijan Standard Time", - "Azerbaijan Standard Time", "Azerbaijan Standard Time", + "Azerbaijan Standard Time", 240, true, "(UTC+04:00) Baku", + "Azerbaijan Standard Time", "Azerbaijan Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_59, 1 }, { - "Russian Standard Time", 240, true, "Russian Standard Time", - "Russian Standard Time", "Russian Standard Time", + "Russian Standard Time", 240, true, "(UTC+04:00) Moscow, St. Petersburg, Volgograd", + "Russian Standard Time", "Russian Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_60, 1 }, { - "Mauritius Standard Time", 240, true, "Mauritius Standard Time", - "Mauritius Standard Time", "Mauritius Standard Time", + "Mauritius Standard Time", 240, true, "(UTC+04:00) Port Louis", + "Mauritius Standard Time", "Mauritius Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_61, 2 }, { - "Georgian Standard Time", 240, false, "Georgian Standard Time", - "Georgian Standard Time", "Georgian Standard Time", + "Georgian Standard Time", 240, false, "(UTC+04:00) Tbilisi", + "Georgian Standard Time", "Georgian Daylight Time", NULL, 0 }, { - "Caucasus Standard Time", 240, true, "Caucasus Standard Time", - "Caucasus Standard Time", "Caucasus Standard Time", + "Caucasus Standard Time", 240, true, "(UTC+04:00) Yerevan", + "Caucasus Standard Time", "Caucasus Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_63, 1 }, { - "Afghanistan Standard Time", 270, false, "Afghanistan Standard Time", - "Afghanistan Standard Time", "Afghanistan Standard Time", + "Afghanistan Standard Time", 270, false, "(UTC+04:30) Kabul", + "Afghanistan Standard Time", "Afghanistan Daylight Time", NULL, 0 }, { - "Pakistan Standard Time", 300, true, "Pakistan Standard Time", - "Pakistan Standard Time", "Pakistan Standard Time", + "Pakistan Standard Time", 300, true, "(UTC+05:00) Islamabad, Karachi", + "Pakistan Standard Time", "Pakistan Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_65, 2 }, { - "West Asia Standard Time", 300, false, "West Asia Standard Time", - "West Asia Standard Time", "West Asia Standard Time", + "West Asia Standard Time", 300, false, "(UTC+05:00) Tashkent", + "West Asia Standard Time", "West Asia Daylight Time", NULL, 0 }, { - "India Standard Time", 330, false, "India Standard Time", - "India Standard Time", "India Standard Time", + "India Standard Time", 330, false, "(UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi", + "India Standard Time", "India Daylight Time", NULL, 0 }, { - "Sri Lanka Standard Time", 330, false, "Sri Lanka Standard Time", - "Sri Lanka Standard Time", "Sri Lanka Standard Time", + "Sri Lanka Standard Time", 330, false, "(UTC+05:30) Sri Jayawardenepura", + "Sri Lanka Standard Time", "Sri Lanka Daylight Time", NULL, 0 }, { - "Nepal Standard Time", 345, false, "Nepal Standard Time", - "Nepal Standard Time", "Nepal Standard Time", + "Nepal Standard Time", 345, false, "(UTC+05:45) Kathmandu", + "Nepal Standard Time", "Nepal Daylight Time", NULL, 0 }, { - "Central Asia Standard Time", 360, false, "Central Asia Standard Time", - "Central Asia Standard Time", "Central Asia Standard Time", + "Central Asia Standard Time", 360, false, "(UTC+06:00) Astana", + "Central Asia Standard Time", "Central Asia Daylight Time", NULL, 0 }, { - "Bangladesh Standard Time", 360, true, "Bangladesh Standard Time", - "Bangladesh Standard Time", "Bangladesh Standard Time", + "Bangladesh Standard Time", 360, true, "(UTC+06:00) Dhaka", + "Bangladesh Standard Time", "Bangladesh Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_71, 1 }, { - "Ekaterinburg Standard Time", 360, true, "Ekaterinburg Standard Time", - "Ekaterinburg Standard Time", "Ekaterinburg Standard Time", + "Ekaterinburg Standard Time", 360, true, "(UTC+06:00) Ekaterinburg", + "Ekaterinburg Standard Time", "Ekaterinburg Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_72, 1 }, { - "Myanmar Standard Time", 390, false, "Myanmar Standard Time", - "Myanmar Standard Time", "Myanmar Standard Time", + "Myanmar Standard Time", 390, false, "(UTC+06:30) Yangon (Rangoon)", + "Myanmar Standard Time", "Myanmar Daylight Time", NULL, 0 }, { - "SE Asia Standard Time", 420, false, "SE Asia Standard Time", - "SE Asia Standard Time", "SE Asia Standard Time", + "SE Asia Standard Time", 420, false, "(UTC+07:00) Bangkok, Hanoi, Jakarta", + "SE Asia Standard Time", "SE Asia Daylight Time", NULL, 0 }, { - "N. Central Asia Standard Time", 420, true, "N. Central Asia Standard Time", - "N. Central Asia Standard Time", "N. Central Asia Standard Time", + "N. Central Asia Standard Time", 420, true, "(UTC+07:00) Novosibirsk", + "N. Central Asia Standard Time", "N. Central Asia Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_75, 1 }, { - "China Standard Time", 480, false, "China Standard Time", - "China Standard Time", "China Standard Time", + "China Standard Time", 480, false, "(UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi", + "China Standard Time", "China Daylight Time", NULL, 0 }, { - "North Asia Standard Time", 480, true, "North Asia Standard Time", - "North Asia Standard Time", "North Asia Standard Time", + "North Asia Standard Time", 480, true, "(UTC+08:00) Krasnoyarsk", + "North Asia Standard Time", "North Asia Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_77, 1 }, { - "Singapore Standard Time", 480, false, "Singapore Standard Time", - "Malay Peninsula Standard Time", "Malay Peninsula Standard Time", + "Singapore Standard Time", 480, false, "(UTC+08:00) Kuala Lumpur, Singapore", + "Malay Peninsula Standard Time", "Malay Peninsula Daylight Time", NULL, 0 }, { - "W. Australia Standard Time", 480, true, "W. Australia Standard Time", - "W. Australia Standard Time", "W. Australia Standard Time", + "W. Australia Standard Time", 480, true, "(UTC+08:00) Perth", + "W. Australia Standard Time", "W. Australia Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_79, 4 }, { - "Taipei Standard Time", 480, false, "Taipei Standard Time", - "Taipei Standard Time", "Taipei Standard Time", + "Taipei Standard Time", 480, false, "(UTC+08:00) Taipei", + "Taipei Standard Time", "Taipei Daylight Time", NULL, 0 }, { - "Ulaanbaatar Standard Time", 480, false, "Ulaanbaatar Standard Time", - "Ulaanbaatar Standard Time", "Ulaanbaatar Standard Time", + "Ulaanbaatar Standard Time", 480, false, "(UTC+08:00) Ulaanbaatar", + "Ulaanbaatar Standard Time", "Ulaanbaatar Daylight Time", NULL, 0 }, { - "North Asia East Standard Time", 540, true, "North Asia East Standard Time", - "North Asia East Standard Time", "North Asia East Standard Time", + "North Asia East Standard Time", 540, true, "(UTC+09:00) Irkutsk", + "North Asia East Standard Time", "North Asia East Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_82, 1 }, { - "Tokyo Standard Time", 540, false, "Tokyo Standard Time", - "Tokyo Standard Time", "Tokyo Standard Time", + "Tokyo Standard Time", 540, false, "(UTC+09:00) Osaka, Sapporo, Tokyo", + "Tokyo Standard Time", "Tokyo Daylight Time", NULL, 0 }, { - "Korea Standard Time", 540, false, "Korea Standard Time", - "Korea Standard Time", "Korea Standard Time", + "Korea Standard Time", 540, false, "(UTC+09:00) Seoul", + "Korea Standard Time", "Korea Daylight Time", NULL, 0 }, { - "Cen. Australia Standard Time", 570, true, "Cen. Australia Standard Time", - "Cen. Australia Standard Time", "Cen. Australia Standard Time", + "Cen. Australia Standard Time", 570, true, "(UTC+09:30) Adelaide", + "Cen. Australia Standard Time", "Cen. Australia Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_85, 2 }, { - "AUS Central Standard Time", 570, false, "AUS Central Standard Time", - "AUS Central Standard Time", "AUS Central Standard Time", + "AUS Central Standard Time", 570, false, "(UTC+09:30) Darwin", + "AUS Central Standard Time", "AUS Central Daylight Time", NULL, 0 }, { - "E. Australia Standard Time", 600, false, "E. Australia Standard Time", - "E. Australia Standard Time", "E. Australia Standard Time", + "E. Australia Standard Time", 600, false, "(UTC+10:00) Brisbane", + "E. Australia Standard Time", "E. Australia Daylight Time", NULL, 0 }, { - "AUS Eastern Standard Time", 600, true, "AUS Eastern Standard Time", - "AUS Eastern Standard Time", "AUS Eastern Standard Time", + "AUS Eastern Standard Time", 600, true, "(UTC+10:00) Canberra, Melbourne, Sydney", + "AUS Eastern Standard Time", "AUS Eastern Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_88, 2 }, { - "West Pacific Standard Time", 600, false, "West Pacific Standard Time", - "West Pacific Standard Time", "West Pacific Standard Time", + "West Pacific Standard Time", 600, false, "(UTC+10:00) Guam, Port Moresby", + "West Pacific Standard Time", "West Pacific Daylight Time", NULL, 0 }, { - "Tasmania Standard Time", 600, true, "Tasmania Standard Time", - "Tasmania Standard Time", "Tasmania Standard Time", + "Tasmania Standard Time", 600, true, "(UTC+10:00) Hobart", + "Tasmania Standard Time", "Tasmania Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_90, 2 }, { - "Yakutsk Standard Time", 600, true, "Yakutsk Standard Time", - "Yakutsk Standard Time", "Yakutsk Standard Time", + "Yakutsk Standard Time", 600, true, "(UTC+10:00) Yakutsk", + "Yakutsk Standard Time", "Yakutsk Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_91, 1 }, { - "Central Pacific Standard Time", 660, false, "Central Pacific Standard Time", - "Central Pacific Standard Time", "Central Pacific Standard Time", + "Central Pacific Standard Time", 660, false, "(UTC+11:00) Solomon Is., New Caledonia", + "Central Pacific Standard Time", "Central Pacific Daylight Time", NULL, 0 }, { - "Vladivostok Standard Time", 660, true, "Vladivostok Standard Time", - "Vladivostok Standard Time", "Vladivostok Standard Time", + "Vladivostok Standard Time", 660, true, "(UTC+11:00) Vladivostok", + "Vladivostok Standard Time", "Vladivostok Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_93, 1 }, { - "New Zealand Standard Time", 720, true, "New Zealand Standard Time", - "New Zealand Standard Time", "New Zealand Standard Time", + "New Zealand Standard Time", 720, true, "(UTC+12:00) Auckland, Wellington", + "New Zealand Standard Time", "New Zealand Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_94, 3 }, { - "UTC+12", 720, false, "UTC+12", + "UTC+12", 720, false, "(UTC+12:00) Coordinated Universal Time+12", "UTC+12", "UTC+12", NULL, 0 }, { - "Fiji Standard Time", 720, true, "Fiji Standard Time", - "Fiji Standard Time", "Fiji Standard Time", + "Fiji Standard Time", 720, true, "(UTC+12:00) Fiji", + "Fiji Standard Time", "Fiji Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_96, 5 }, { - "Magadan Standard Time", 720, true, "Magadan Standard Time", - "Magadan Standard Time", "Magadan Standard Time", + "Magadan Standard Time", 720, true, "(UTC+12:00) Magadan", + "Magadan Standard Time", "Magadan Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_97, 1 }, { - "Kamchatka Standard Time", 720, true, "Kamchatka Standard Time", - "Kamchatka Standard Time", "Kamchatka Standard Time", + "Kamchatka Standard Time", 720, true, "(UTC+12:00) Petropavlovsk-Kamchatsky - Old", + "Kamchatka Standard Time", "Kamchatka Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_98, 1 }, { - "Tonga Standard Time", 780, false, "Tonga Standard Time", - "Tonga Standard Time", "Tonga Standard Time", + "Tonga Standard Time", 780, false, "(UTC+13:00) Nuku'alofa", + "Tonga Standard Time", "Tonga Daylight Time", NULL, 0 }, { - "Samoa Standard Time", 780, true, "Samoa Standard Time", - "Samoa Standard Time", "Samoa Standard Time", + "Samoa Standard Time", 780, true, "(UTC+13:00) Samoa", + "Samoa Standard Time", "Samoa Daylight Time", (TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_100, 2 } }; +/* Table generated with WindowsZones.cs */ + struct _WINDOWS_TZID_ENTRY { const char* windows; @@ -1261,13 +1268,14 @@ const WINDOWS_TZID_ENTRY WindowsTimeZoneIdTable[] = { "GTB Standard Time", "Europe/Athens" }, { "GTB Standard Time", "Europe/Bucharest" }, { "GTB Standard Time", "Europe/Chisinau" }, + { "GTB Standard Time", "Europe/Istanbul" }, { "Hawaiian Standard Time", "Etc/GMT+10" }, { "Hawaiian Standard Time", "Pacific/Fakaofo" }, { "Hawaiian Standard Time", "Pacific/Honolulu" }, { "Hawaiian Standard Time", "Pacific/Johnston" }, { "Hawaiian Standard Time", "Pacific/Rarotonga" }, { "Hawaiian Standard Time", "Pacific/Tahiti" }, - { "India Standard Time", "Asia/Calcutta" }, + { "India Standard Time", "Asia/Calcutta Asia/Kolkata" }, { "Iran Standard Time", "Asia/Tehran" }, { "Israel Standard Time", "Asia/Jerusalem" }, { "Jordan Standard Time", "Asia/Amman" }, @@ -1296,7 +1304,7 @@ const WINDOWS_TZID_ENTRY WindowsTimeZoneIdTable[] = { "N. Central Asia Standard Time", "Asia/Novosibirsk Asia/Novokuznetsk Asia/Omsk" }, { "N. Central Asia Standard Time", "Asia/Novosibirsk" }, { "Namibia Standard Time", "Africa/Windhoek" }, - { "Nepal Standard Time", "Asia/Katmandu" }, + { "Nepal Standard Time", "Asia/Katmandu Asia/Kathmandu" }, { "New Zealand Standard Time", "Antarctica/South_Pole Antarctica/McMurdo" }, { "New Zealand Standard Time", "Pacific/Auckland" }, { "Newfoundland Standard Time", "America/St_Johns" }, @@ -1306,7 +1314,7 @@ const WINDOWS_TZID_ENTRY WindowsTimeZoneIdTable[] = { "Pacific SA Standard Time", "Antarctica/Palmer" }, { "Pacific Standard Time (Mexico)", "America/Santa_Isabel" }, { "Pacific Standard Time", "America/Los_Angeles" }, - { "Pacific Standard Time", "America/Tijuana" }, + { "Pacific Standard Time", "America/Tijuana America/Ensenada" }, { "Pacific Standard Time", "America/Vancouver America/Dawson America/Whitehorse" }, { "Pacific Standard Time", "PST8PDT" }, { "Pakistan Standard Time", "Asia/Karachi" }, @@ -1358,13 +1366,13 @@ const WINDOWS_TZID_ENTRY WindowsTimeZoneIdTable[] = { "SA Western Standard Time", "America/St_Vincent" }, { "SA Western Standard Time", "America/Tortola" }, { "SA Western Standard Time", "Etc/GMT+4" }, - { "Samoa Standard Time", "Pacific/Apia" }, + { "Samoa Standard Time", "Pacific/Apia Pacific/Samoa" }, { "SE Asia Standard Time", "Antarctica/Davis" }, { "SE Asia Standard Time", "Asia/Bangkok" }, { "SE Asia Standard Time", "Asia/Hovd" }, { "SE Asia Standard Time", "Asia/Jakarta Asia/Pontianak" }, { "SE Asia Standard Time", "Asia/Phnom_Penh" }, - { "SE Asia Standard Time", "Asia/Saigon" }, + { "SE Asia Standard Time", "Asia/Saigon Asia/Ho_Chi_Minh" }, { "SE Asia Standard Time", "Asia/Vientiane" }, { "SE Asia Standard Time", "Etc/GMT-7" }, { "SE Asia Standard Time", "Indian/Christmas" }, @@ -1400,7 +1408,7 @@ const WINDOWS_TZID_ENTRY WindowsTimeZoneIdTable[] = { "Tonga Standard Time", "Etc/GMT-13" }, { "Tonga Standard Time", "Pacific/Enderbury" }, { "Tonga Standard Time", "Pacific/Tongatapu" }, - { "Turkey Standard Time", "Europe/Istanbul" }, + /* { "Turkey Standard Time", "Europe/Istanbul" }, */ { "Ulaanbaatar Standard Time", "Asia/Ulaanbaatar Asia/Choibalsan" }, { "Ulaanbaatar Standard Time", "Asia/Ulaanbaatar" }, { "US Eastern Standard Time", "America/Indianapolis " @@ -1481,10 +1489,13 @@ const WINDOWS_TZID_ENTRY WindowsTimeZoneIdTable[] = char* freerdp_get_unix_timezone_identifier() { +#ifndef _WIN32 FILE* fp; + ssize_t len; char* tz_env; size_t length; char* tzid = NULL; + char buf[1024]; tz_env = getenv("TZ"); @@ -1515,10 +1526,48 @@ char* freerdp_get_unix_timezone_identifier() if (tzid[length - 1] == '\n') tzid[length - 1] = '\0'; - fclose(fp) ; + fclose(fp); + + return tzid; } + /* + * On linux distros such as Redhat or Archlinux, a symlink at /etc/localtime + * will point to /usr/share/zoneinfo/region/place where region/place could be + * America/Montreal for example. + */ + + if ((len = readlink("/etc/localtime", buf, sizeof(buf) - 1)) != -1) + { + int num = 0; + int pos = len; + + buf[len] = '\0'; + + /* find the position of the 2nd to last "/" */ + + while (num < 2) + { + if (pos == 0) + break; + + pos -= 1; + + if (buf[pos] == '/') + num++; + } + + tzid = (char*) xmalloc(len - pos + 1); + strncpy(tzid, buf + pos + 1, len - pos); + + return tzid; + } + + printf("Unable to detect time zone\n"); return tzid; +#else + return 0; +#endif } boolean freerdp_match_unix_timezone_identifier_with_list(const char* tzid, const char* list) @@ -1559,24 +1608,23 @@ TIME_ZONE_ENTRY* freerdp_detect_windows_time_zone(uint32 bias) for (i = 0; i < ARRAY_SIZE(TimeZoneTable); i++) { - if (bias == TimeZoneTable[i].Bias) + for (j = 0; j < ARRAY_SIZE(WindowsTimeZoneIdTable); j++) { - for (j = 0; j < ARRAY_SIZE(WindowsTimeZoneIdTable); j++) - { - if (strcmp(TimeZoneTable[i].Id, WindowsTimeZoneIdTable[j].windows) != 0) - continue; + if (strcmp(TimeZoneTable[i].Id, WindowsTimeZoneIdTable[j].windows) != 0) + continue; - if (freerdp_match_unix_timezone_identifier_with_list(tzid, WindowsTimeZoneIdTable[j].tzid)) - { - timezone = (TIME_ZONE_ENTRY*) xmalloc(sizeof(TIME_ZONE_ENTRY)); - memcpy((void*) timezone, (void*) &TimeZoneTable[i], sizeof(TIME_ZONE_ENTRY)); - xfree(tzid); - return timezone; - } + if (freerdp_match_unix_timezone_identifier_with_list(tzid, WindowsTimeZoneIdTable[j].tzid)) + { + timezone = (TIME_ZONE_ENTRY*) xmalloc(sizeof(TIME_ZONE_ENTRY)); + memcpy((void*) timezone, (void*) &TimeZoneTable[i], sizeof(TIME_ZONE_ENTRY)); + timezone->Bias = bias; + xfree(tzid); + return timezone; } } } + printf("Unable to find a match for unix timezone: %s\n", tzid); xfree(tzid); return NULL; } @@ -1592,27 +1640,29 @@ TIME_ZONE_RULE_ENTRY* freerdp_get_current_time_zone_rule(TIME_ZONE_RULE_ENTRY* r { if ((rules[i].TicksStart <= windows_time) && (windows_time >= rules[i].TicksEnd)) { + /*printf("Got rule %d from table at %p with count %u\n", i, rules, count);*/ return &rules[i]; } } + printf("Unable to get current timezone rule\n"); return NULL; } void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone) { time_t t; - struct tm* local_time; TIME_ZONE_ENTRY* tz; + struct tm* local_time; time(&t); local_time = localtime(&t); #ifdef HAVE_TM_GMTOFF if (local_time->tm_gmtoff >= 0) - clientTimeZone->bias = (uint32) (-1 * local_time->tm_gmtoff / 60); + clientTimeZone->bias = (uint32) (local_time->tm_gmtoff / 60); else - clientTimeZone->bias = (uint32) ((-1 * local_time->tm_gmtoff) / 60); + clientTimeZone->bias = (uint32) (1440 + (sint32) (local_time->tm_gmtoff / 60)); #elif sun if (local_time->tm_isdst > 0) clientTimeZone->bias = (uint32) (altzone / 3600); @@ -1621,7 +1671,6 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone) #else clientTimeZone->bias = 0; #endif - if (local_time->tm_isdst > 0) { clientTimeZone->standardBias = clientTimeZone->bias - 60; @@ -1632,11 +1681,18 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone) clientTimeZone->standardBias = clientTimeZone->bias; clientTimeZone->daylightBias = clientTimeZone->bias + 60; } + DEBUG_TIMEZONE("sbias=%d, bias=%d, stdBias=%d, dlBias=%d", + sbias, clientTimeZone->bias, clientTimeZone->standardBias, + clientTimeZone->daylightBias); tz = freerdp_detect_windows_time_zone(clientTimeZone->bias); if (tz!= NULL) { + DEBUG_TIMEZONE("tz: Id='%s' Bias=%d DST=%d dn='%s' sn='%s' dln='%s'", + tz->Id, tz->Bias, tz->SupportsDST, tz->DisplayName, + tz->StandardName, tz->DaylightName); + /* Not printed: RuleTable, RuleTableCount */ clientTimeZone->bias = tz->Bias; sprintf(clientTimeZone->standardName, "%s", tz->StandardName); sprintf(clientTimeZone->daylightName, "%s", tz->DaylightName); @@ -1646,6 +1702,7 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone) TIME_ZONE_RULE_ENTRY* rule; rule = freerdp_get_current_time_zone_rule(tz->RuleTable, tz->RuleTableCount); + /* issue #574 -- temporarily disabled this block as it seems to be setting the wrong time if (rule != NULL) { clientTimeZone->standardBias = 0; @@ -1669,6 +1726,7 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone) clientTimeZone->daylightDate.wSecond = rule->DaylightDate.wSecond; clientTimeZone->daylightDate.wMilliseconds = rule->DaylightDate.wMilliseconds; } + */ } xfree(tz); @@ -1676,6 +1734,7 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone) else { /* could not detect timezone, fallback to using GMT */ + DEBUG_TIMEZONE("tz not found, using GMT."); sprintf(clientTimeZone->standardName, "%s", "GMT Standard Time"); sprintf(clientTimeZone->daylightName, "%s", "GMT Daylight Time"); } diff --git a/libfreerdp-locale/virtual_key_codes.c b/libfreerdp/locale/virtual_key_codes.c similarity index 99% rename from libfreerdp-locale/virtual_key_codes.c rename to libfreerdp/locale/virtual_key_codes.c index a011451f0..7e8b7cf86 100644 --- a/libfreerdp-locale/virtual_key_codes.c +++ b/libfreerdp/locale/virtual_key_codes.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-locale/xkb_layout_ids.c b/libfreerdp/locale/xkb_layout_ids.c similarity index 99% rename from libfreerdp-locale/xkb_layout_ids.c rename to libfreerdp/locale/xkb_layout_ids.c index 696350ca1..d2b18b8eb 100644 --- a/libfreerdp-locale/xkb_layout_ids.c +++ b/libfreerdp/locale/xkb_layout_ids.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "xkb_layout_ids.h" #include diff --git a/libfreerdp-locale/xkb_layout_ids.h b/libfreerdp/locale/xkb_layout_ids.h similarity index 100% rename from libfreerdp-locale/xkb_layout_ids.h rename to libfreerdp/locale/xkb_layout_ids.h diff --git a/libfreerdp-rail/CMakeLists.txt b/libfreerdp/rail/CMakeLists.txt similarity index 68% rename from libfreerdp-rail/CMakeLists.txt rename to libfreerdp/rail/CMakeLists.txt index b8648524e..728441ae3 100644 --- a/libfreerdp-rail/CMakeLists.txt +++ b/libfreerdp/rail/CMakeLists.txt @@ -24,10 +24,20 @@ set(FREERDP_RAIL_SRCS rail.c librail.h) -add_library(freerdp-rail ${FREERDP_RAIL_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(freerdp-rail OBJECT ${FREERDP_RAIL_SRCS}) +else() + add_library(freerdp-rail ${FREERDP_RAIL_SRCS}) +endif() set_target_properties(freerdp-rail PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -target_link_libraries(freerdp-rail freerdp-utils) +set(FREERDP_RAIL_LIBS) -install(TARGETS freerdp-rail DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_LIBS ${FREERDP_LIBS} ${FREERDP_RAIL_LIBS} PARENT_SCOPE) +else() + set(FREERDP_RAIL_LIBS ${FREERDP_RAIL_LIBS} freerdp-utils) + target_link_libraries(freerdp-rail ${FREERDP_RAIL_LIBS}) + install(TARGETS freerdp-rail DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/libfreerdp-rail/icon.c b/libfreerdp/rail/icon.c similarity index 98% rename from libfreerdp-rail/icon.c rename to libfreerdp/rail/icon.c index 3a9e167f1..bbca5a7ad 100644 --- a/libfreerdp-rail/icon.c +++ b/libfreerdp/rail/icon.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-rail/librail.h b/libfreerdp/rail/librail.h similarity index 97% rename from libfreerdp-rail/librail.h rename to libfreerdp/rail/librail.h index 08f1f6863..68d9c8b49 100644 --- a/libfreerdp-rail/librail.h +++ b/libfreerdp/rail/librail.h @@ -20,7 +20,10 @@ #ifndef __LIBRAIL_H #define __LIBRAIL_H +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #ifdef WITH_DEBUG_RAIL diff --git a/libfreerdp-rail/rail.c b/libfreerdp/rail/rail.c similarity index 86% rename from libfreerdp-rail/rail.c rename to libfreerdp/rail/rail.c index 89decc0c8..d0aeb6a12 100644 --- a/libfreerdp-rail/rail.c +++ b/libfreerdp/rail/rail.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -99,11 +103,24 @@ static void rail_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderI } +//This is used to switch FreeRDP back to showing the full desktop under remote app mode +//to handle cases where the screen is locked, etc. The rail server informs us that it is +//no longer monitoring the desktop. Once the desktop becomes monitored again. The full desktop +//window will be automatically destroyed and we will switch back into remote app mode. static void rail_NonMonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) { + rdpWindow* window; + rdpRail* rail = context->rail; + window = window_list_get_by_id(rail->list, orderInfo->windowId); + + IFCALL(rail->rail_DesktopNonMonitored, rail, window); + + window_list_clear(rail->list); } + + void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update) { rdpWindowUpdate* window = update->window; diff --git a/libfreerdp-rail/window.c b/libfreerdp/rail/window.c similarity index 99% rename from libfreerdp-rail/window.c rename to libfreerdp/rail/window.c index 7b39fa13b..208e560c9 100644 --- a/libfreerdp-rail/window.c +++ b/libfreerdp/rail/window.c @@ -17,7 +17,12 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include + #include #include #include diff --git a/libfreerdp-rail/window_list.c b/libfreerdp/rail/window_list.c similarity index 85% rename from libfreerdp-rail/window_list.c rename to libfreerdp/rail/window_list.c index 340801170..027c8e4c2 100644 --- a/libfreerdp-rail/window_list.c +++ b/libfreerdp/rail/window_list.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -97,6 +101,16 @@ void window_list_create(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDO { rdpWindow* window; + /* See if the window already exists */ + window = window_list_get_by_id(list, orderInfo->windowId); + + /* If the window already exists, just update the existing window */ + if (window != NULL) + { + window_list_update(list, orderInfo, window_state); + return; + } + window = (rdpWindow*) xzalloc(sizeof(rdpWindow)); if (window == NULL) @@ -175,6 +189,20 @@ void window_list_delete(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo) rail_DestroyWindow(list->rail, window); } +void window_list_clear(rdpWindowList* list) +{ + rdpWindow* current = list->head; + + while (current != NULL) + { + list->head = current->next; + rail_DestroyWindow(list->rail, current); + current = list->head; + } + + list->tail = NULL; +} + rdpWindowList* window_list_new(rdpRail* rail) { rdpWindowList* list; diff --git a/libfreerdp-utils/CMakeLists.txt b/libfreerdp/utils/CMakeLists.txt similarity index 70% rename from libfreerdp-utils/CMakeLists.txt rename to libfreerdp/utils/CMakeLists.txt index f1b3e3335..4f748c40e 100644 --- a/libfreerdp-utils/CMakeLists.txt +++ b/libfreerdp/utils/CMakeLists.txt @@ -51,17 +51,29 @@ set(FREERDP_UTILS_SRCS unicode.c wait_obj.c) -add_library(freerdp-utils ${FREERDP_UTILS_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(freerdp-utils OBJECT ${FREERDP_UTILS_SRCS}) +else() + add_library(freerdp-utils ${FREERDP_UTILS_SRCS}) +endif() set_target_properties(freerdp-utils PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -target_link_libraries(freerdp-utils ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) +set(FREERDP_UTILS_LIBS + ${CMAKE_THREAD_LIBS_INIT} + ${CMAKE_DL_LIBS}) if(WIN32) - target_link_libraries(freerdp-utils ws2_32) -endif() -if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) - target_link_libraries(freerdp-utils rt) + set(FREERDP_UTILS_LIBS ${FREERDP_UTILS_LIBS} ws2_32) endif() -install(TARGETS freerdp-utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) + set(FREERDP_UTILS_LIBS ${FREERDP_UTILS_LIBS} rt) +endif() + +if(WITH_MONOLITHIC_BUILD) + set(FREERDP_LIBS ${FREERDP_LIBS} ${FREERDP_UTILS_LIBS} PARENT_SCOPE) +else() + target_link_libraries(freerdp-utils ${FREERDP_UTILS_LIBS}) + install(TARGETS freerdp-utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/libfreerdp-utils/args.c b/libfreerdp/utils/args.c similarity index 88% rename from libfreerdp-utils/args.c rename to libfreerdp/utils/args.c index 1a5b39125..481b45eaf 100644 --- a/libfreerdp-utils/args.c +++ b/libfreerdp/utils/args.c @@ -18,39 +18,52 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include + #include +#include #include #include #include +#include - -void freerdp_parse_hostname(rdpSettings* settings, char* hostname) { +void freerdp_parse_hostname(rdpSettings* settings, char* hostname) +{ char* p; + if (hostname[0] == '[' && (p = strchr(hostname, ']')) - && (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':')))) { - /* Either "[...]" or "[...]:..." with at most one : after the brackets */ + && (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':')))) + { + /* Either "[...]" or "[...]:..." with at most one : after the brackets */ settings->hostname = xstrdup(hostname + 1); - if ((p = strchr((char*)settings->hostname, ']'))) { + + if ((p = strchr((char*)settings->hostname, ']'))) + { *p = 0; + if (p[1] == ':') settings->port = atoi(p + 2); } - } else { + } + else + { /* Port number is cut off and used if exactly one : in the string */ settings->hostname = xstrdup(hostname); - if ((p = strchr((char*)settings->hostname, ':')) && !strchr(p + 1, ':')) { + + if ((p = strchr((char*)settings->hostname, ':')) && !strchr(p + 1, ':')) + { *p = 0; settings->port = atoi(p + 1); } } } - - /** * Parse command-line arguments and update rdpSettings members accordingly. * @param settings pointer to rdpSettings struct to be updated. @@ -112,16 +125,22 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, " --gdi: graphics rendering (hw, sw)\n" " --no-osb: disable offscreen bitmaps\n" " --no-bmp-cache: disable bitmap cache\n" + " --bcv3: codec for bitmap cache v3 (rfx, nsc, jpeg)\n" " --plugin: load a virtual channel plugin\n" " --rfx: enable RemoteFX\n" " --rfx-mode: RemoteFX operational flags (v[ideo], i[mage]), default is video\n" " --frame-ack: number of frames pending to be acknowledged, default is 2 (disable with 0)\n" " --nsc: enable NSCodec (experimental)\n" +#ifdef WITH_JPEG + " --jpeg: enable jpeg codec, uses 75 quality\n" + " --jpegex: enable jpeg and set quality(1..99)\n" +#endif " --disable-wallpaper: disables wallpaper\n" " --composition: enable desktop composition\n" " --disable-full-window-drag: disables full window drag\n" " --disable-menu-animations: disables menu animations\n" " --disable-theming: disables theming\n" + " --no-nego: disable negotiation of security layer and enforce highest enabled security protocol\n" " --no-rdp: disable Standard RDP encryption\n" " --no-tls: disable TLS encryption\n" " --no-nla: disable network level authentication\n" @@ -132,6 +151,8 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, " --tsg: Terminal Server Gateway ( )\n" " --kbd-list: list all keyboard layout ids used by -k\n" " --no-salted-checksum: disable salted checksums with Standard RDP encryption\n" + " --pcid: preconnection id\n" + " --pcb: preconnection blob\n" " --version: print version information\n" "\n", argv[0]); return FREERDP_ARGS_PARSE_HELP; /* TODO: What is the correct return? */ @@ -382,6 +403,61 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, return FREERDP_ARGS_PARSE_FAILURE; } } + else if (strcmp("--bcv3", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing codec name\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->bitmap_cache_v3 = true; + if (strcmp("rfx", argv[index]) == 0) + { + printf("setting rfx\n"); + settings->v3_codec_id = CODEC_ID_REMOTEFX; + settings->rfx_codec = true; + } + else if (strcmp("nsc", argv[index]) == 0) + { + printf("setting codec nsc\n"); + settings->v3_codec_id = CODEC_ID_NSCODEC; + settings->ns_codec = true; + } +#ifdef WITH_JPEG + else if (strcmp("jpeg", argv[index]) == 0) + { + printf("setting codec jpeg\n"); + settings->v3_codec_id = CODEC_ID_JPEG; + settings->jpeg_codec = true; + if (settings->jpeg_quality == 0) + settings->jpeg_quality = 75; + } +#endif + else + { + printf("bad codec name\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + } +#ifdef WITH_JPEG + else if (strcmp("--jpeg", argv[index]) == 0) + { + settings->jpeg_codec = true; + settings->jpeg_quality = 75; + } + else if (strcmp("--jpegex", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing codec name\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->jpeg_codec = true; + settings->jpeg_quality = atoi(argv[index]); + } +#endif else if (strcmp("--rfx", argv[index]) == 0) { settings->rfx_codec = true; @@ -579,6 +655,10 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, return FREERDP_ARGS_PARSE_FAILURE; } } + else if (strcmp("--no-nego", argv[index]) == 0) + { + settings->security_layer_negotiation = false; + } else if (strcmp("--tsg", argv[index]) == 0) { settings->ts_gateway = true; @@ -698,9 +778,31 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, { settings->salted_checksum = false; } + else if (strcmp("--pcid", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing preconnection id value\n"); + return -1; + } + settings->send_preconnection_pdu = true; + settings->preconnection_id = atoi(argv[index]); + } + else if (strcmp("--pcb", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing preconnection blob value\n"); + return -1; + } + settings->send_preconnection_pdu = true; + settings->preconnection_blob = xstrdup(argv[index]); + } else if (strcmp("--version", argv[index]) == 0) { - printf("This is FreeRDP version %s\n", FREERDP_VERSION_FULL); + printf("This is FreeRDP version %s (git %s)\n", FREERDP_VERSION_FULL, GIT_REVISION); return FREERDP_ARGS_PARSE_VERSION; } else if (argv[index][0] != '-') @@ -764,10 +866,8 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, } /* password */ if (NULL == settings->password) { - char input[512]; - printf("password: "); - scanf("%511s", input); - settings->password = xstrdup(input); + settings->password = xmalloc(512 * sizeof(char)); + freerdp_passphrase_read("password: ", settings->password, 512, settings->from_stdin); } /* domain */ if (NULL == settings->domain) { diff --git a/libfreerdp-utils/bitmap.c b/libfreerdp/utils/bitmap.c similarity index 97% rename from libfreerdp-utils/bitmap.c rename to libfreerdp/utils/bitmap.c index bbcfbdb7e..e77d56a62 100644 --- a/libfreerdp-utils/bitmap.c +++ b/libfreerdp/utils/bitmap.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-utils/blob.c b/libfreerdp/utils/blob.c similarity index 96% rename from libfreerdp-utils/blob.c rename to libfreerdp/utils/blob.c index 1c2eef069..045da60b1 100644 --- a/libfreerdp-utils/blob.c +++ b/libfreerdp/utils/blob.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-utils/dsp.c b/libfreerdp/utils/dsp.c similarity index 99% rename from libfreerdp-utils/dsp.c rename to libfreerdp/utils/dsp.c index e1b7a138b..c89c900cf 100644 --- a/libfreerdp-utils/dsp.c +++ b/libfreerdp/utils/dsp.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-utils/event.c b/libfreerdp/utils/event.c similarity index 98% rename from libfreerdp-utils/event.c rename to libfreerdp/utils/event.c index b3f0cdc71..f559b3f21 100644 --- a/libfreerdp-utils/event.c +++ b/libfreerdp/utils/event.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-utils/file.c b/libfreerdp/utils/file.c similarity index 99% rename from libfreerdp-utils/file.c rename to libfreerdp/utils/file.c index f1985da0e..fa3e47ce8 100644 --- a/libfreerdp-utils/file.c +++ b/libfreerdp/utils/file.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-utils/hexdump.c b/libfreerdp/utils/hexdump.c similarity index 96% rename from libfreerdp-utils/hexdump.c rename to libfreerdp/utils/hexdump.c index 1db8cd6e2..665aeb000 100644 --- a/libfreerdp-utils/hexdump.c +++ b/libfreerdp/utils/hexdump.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-utils/list.c b/libfreerdp/utils/list.c similarity index 99% rename from libfreerdp-utils/list.c rename to libfreerdp/utils/list.c index 936b21762..265753ba6 100644 --- a/libfreerdp-utils/list.c +++ b/libfreerdp/utils/list.c @@ -17,9 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include + #include #include diff --git a/libfreerdp-utils/load_plugin.c b/libfreerdp/utils/load_plugin.c similarity index 78% rename from libfreerdp-utils/load_plugin.c rename to libfreerdp/utils/load_plugin.c index 08d80541a..c36e7ba62 100644 --- a/libfreerdp-utils/load_plugin.c +++ b/libfreerdp/utils/load_plugin.c @@ -17,7 +17,9 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include #include @@ -46,6 +48,21 @@ #endif + +#define MAX_STATIC_PLUGINS 50 + +struct static_plugin +{ + const char* name; + const char* entry_name; + void* entry_addr; +}; +typedef struct static_plugin staticPlugin; + +static staticPlugin g_static_plugins[MAX_STATIC_PLUGINS]; +static int g_static_plugins_count; + + /** * UNUSED * This function opens a handle on the specified library in order to load symbols from it. @@ -185,6 +202,10 @@ void* freerdp_load_plugin(const char* name, const char* entry_name) void* entry; char* suffixed_name; + /* first attempt to load a static plugin */ + entry = freerdp_load_static_plugin(name, entry_name); + if (entry != NULL) return entry; + suffixed_name = freerdp_append_shared_library_suffix((char*) name); if (!freerdp_path_contains_separator(suffixed_name)) @@ -276,3 +297,58 @@ void* freerdp_load_channel_plugin(rdpSettings* settings, const char* name, const return entry; } + +/** + * This function is used to register a static plugin so that it can be loaded later on using freerdp_load_plugin. + * + * @param name [IN] - name of the library to load + * @param entry_name [IN] - name of the symbol to register for later loading + * @param entry [IN] - function pointer to the entry function + * + * @return true on success, otherwise false. + */ +boolean freerdp_register_static_plugin(const char* name, const char* entry_name, void* entry_addr) +{ + staticPlugin* plugin; + + if (g_static_plugins_count >= MAX_STATIC_PLUGINS) + { + printf("freerdp_register_static_plugin: cannot register %s/%s", name, entry_name); + return false; + } + + /* add the static plugin to the vector */ + plugin = &g_static_plugins[g_static_plugins_count++]; + plugin->name = name; + plugin->entry_name = entry_name; + plugin->entry_addr = entry_addr; + + return true; +} + +/** + * This is a helper function, used by freerdp_load_plugin to return a function pointer from the static plugin table + * + * @param name [IN] - name of the library to load + * @param entry_name [IN] - name of the symbol to register for later loading + * + * @return Pointer to the entry function, NULL if no matching plugin could be found + */ +void* freerdp_load_static_plugin(const char* name, const char* entry_name) +{ + staticPlugin* plugin; + int i; + + for (i = 0; i < g_static_plugins_count; i++) + { + plugin = &g_static_plugins[i]; + if (!strcmp(plugin->name, name) && !strcmp(plugin->entry_name, entry_name)) + { + return plugin->entry_addr; + } + } + + return NULL; +} + + diff --git a/libfreerdp-utils/memory.c b/libfreerdp/utils/memory.c similarity index 99% rename from libfreerdp-utils/memory.c rename to libfreerdp/utils/memory.c index fae1cc2bc..011d5eacf 100644 --- a/libfreerdp-utils/memory.c +++ b/libfreerdp/utils/memory.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-utils/mutex.c b/libfreerdp/utils/mutex.c similarity index 98% rename from libfreerdp-utils/mutex.c rename to libfreerdp/utils/mutex.c index 49c539076..08c996f60 100644 --- a/libfreerdp-utils/mutex.c +++ b/libfreerdp/utils/mutex.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-utils/passphrase.c b/libfreerdp/utils/passphrase.c similarity index 98% rename from libfreerdp-utils/passphrase.c rename to libfreerdp/utils/passphrase.c index 9f73bbd8d..35c1b8a78 100644 --- a/libfreerdp-utils/passphrase.c +++ b/libfreerdp/utils/passphrase.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #ifdef _WIN32 diff --git a/libfreerdp-utils/pcap.c b/libfreerdp/utils/pcap.c similarity index 98% rename from libfreerdp-utils/pcap.c rename to libfreerdp/utils/pcap.c index 6de19a6dd..905905b7a 100644 --- a/libfreerdp-utils/pcap.c +++ b/libfreerdp/utils/pcap.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-utils/profiler.c b/libfreerdp/utils/profiler.c similarity index 98% rename from libfreerdp-utils/profiler.c rename to libfreerdp/utils/profiler.c index e4406b86f..dfd547a46 100644 --- a/libfreerdp-utils/profiler.c +++ b/libfreerdp/utils/profiler.c @@ -17,7 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include PROFILER* profiler_create(char* name) diff --git a/libfreerdp-utils/rail.c b/libfreerdp/utils/rail.c similarity index 99% rename from libfreerdp-utils/rail.c rename to libfreerdp/utils/rail.c index dbd7d3f54..99f41f487 100644 --- a/libfreerdp-utils/rail.c +++ b/libfreerdp/utils/rail.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-utils/rect.c b/libfreerdp/utils/rect.c similarity index 97% rename from libfreerdp-utils/rect.c rename to libfreerdp/utils/rect.c index 08cdea7fd..e8ee55d91 100644 --- a/libfreerdp-utils/rect.c +++ b/libfreerdp/utils/rect.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-utils/semaphore.c b/libfreerdp/utils/semaphore.c similarity index 97% rename from libfreerdp-utils/semaphore.c rename to libfreerdp/utils/semaphore.c index 9cd87c422..75bb1a57a 100644 --- a/libfreerdp-utils/semaphore.c +++ b/libfreerdp/utils/semaphore.c @@ -17,7 +17,12 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include + #include #include diff --git a/libfreerdp-utils/signal.c b/libfreerdp/utils/signal.c similarity index 98% rename from libfreerdp-utils/signal.c rename to libfreerdp/utils/signal.c index 5889a3d1f..3ce1b277a 100644 --- a/libfreerdp-utils/signal.c +++ b/libfreerdp/utils/signal.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-utils/sleep.c b/libfreerdp/utils/sleep.c similarity index 96% rename from libfreerdp-utils/sleep.c rename to libfreerdp/utils/sleep.c index 830cad615..fe7deb21e 100644 --- a/libfreerdp-utils/sleep.c +++ b/libfreerdp/utils/sleep.c @@ -17,7 +17,12 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include + #include #include diff --git a/libfreerdp-utils/stopwatch.c b/libfreerdp/utils/stopwatch.c similarity index 97% rename from libfreerdp-utils/stopwatch.c rename to libfreerdp/utils/stopwatch.c index daf164112..f2cad8f6d 100644 --- a/libfreerdp-utils/stopwatch.c +++ b/libfreerdp/utils/stopwatch.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include STOPWATCH* stopwatch_create() diff --git a/libfreerdp-utils/stream.c b/libfreerdp/utils/stream.c similarity index 98% rename from libfreerdp-utils/stream.c rename to libfreerdp/utils/stream.c index 834214942..534aa2e8c 100644 --- a/libfreerdp-utils/stream.c +++ b/libfreerdp/utils/stream.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-utils/string.c b/libfreerdp/utils/string.c similarity index 96% rename from libfreerdp-utils/string.c rename to libfreerdp/utils/string.c index c3b2a3ab3..9b0c30106 100644 --- a/libfreerdp-utils/string.c +++ b/libfreerdp/utils/string.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-utils/svc_plugin.c b/libfreerdp/utils/svc_plugin.c similarity index 99% rename from libfreerdp-utils/svc_plugin.c rename to libfreerdp/utils/svc_plugin.c index ac19ed824..c7fdc7390 100644 --- a/libfreerdp-utils/svc_plugin.c +++ b/libfreerdp/utils/svc_plugin.c @@ -18,10 +18,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include + #include #include #include diff --git a/libfreerdp-utils/tcp.c b/libfreerdp/utils/tcp.c similarity index 98% rename from libfreerdp-utils/tcp.c rename to libfreerdp/utils/tcp.c index 82f8c8b4c..b81cb7019 100644 --- a/libfreerdp-utils/tcp.c +++ b/libfreerdp/utils/tcp.c @@ -17,12 +17,17 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include #include + #include #include #include diff --git a/libfreerdp-utils/thread.c b/libfreerdp/utils/thread.c similarity index 97% rename from libfreerdp-utils/thread.c rename to libfreerdp/utils/thread.c index d25125917..5b8783a0c 100644 --- a/libfreerdp-utils/thread.c +++ b/libfreerdp/utils/thread.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-utils/time.c b/libfreerdp/utils/time.c similarity index 97% rename from libfreerdp-utils/time.c rename to libfreerdp/utils/time.c index fbcf46971..6f500a7c6 100644 --- a/libfreerdp-utils/time.c +++ b/libfreerdp/utils/time.c @@ -17,7 +17,12 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include + #include uint64 freerdp_windows_gmtime() diff --git a/libfreerdp-utils/uds.c b/libfreerdp/utils/uds.c similarity index 96% rename from libfreerdp-utils/uds.c rename to libfreerdp/utils/uds.c index 46c527e67..ff44f243c 100644 --- a/libfreerdp-utils/uds.c +++ b/libfreerdp/utils/uds.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/libfreerdp-utils/unicode.c b/libfreerdp/utils/unicode.c similarity index 99% rename from libfreerdp-utils/unicode.c rename to libfreerdp/utils/unicode.c index 92f98b5b2..3b84af97c 100644 --- a/libfreerdp-utils/unicode.c +++ b/libfreerdp/utils/unicode.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/libfreerdp-utils/wait_obj.c b/libfreerdp/utils/wait_obj.c similarity index 92% rename from libfreerdp-utils/wait_obj.c rename to libfreerdp/utils/wait_obj.c index a9f2e8ef2..ac4f1c021 100644 --- a/libfreerdp-utils/wait_obj.c +++ b/libfreerdp/utils/wait_obj.c @@ -17,12 +17,16 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include #include #include + #include + #include #include @@ -171,13 +175,12 @@ wait_obj_clear(struct wait_obj* obj) int wait_obj_select(struct wait_obj** listobj, int numobj, int timeout) { + int index; + int status; #ifndef _WIN32 int max; int sock; - int index; -#endif fd_set fds; - int status; struct timeval time; struct timeval* ptime; @@ -189,7 +192,6 @@ wait_obj_select(struct wait_obj** listobj, int numobj, int timeout) ptime = &time; } -#ifndef _WIN32 max = 0; FD_ZERO(&fds); if (listobj) @@ -205,7 +207,19 @@ wait_obj_select(struct wait_obj** listobj, int numobj, int timeout) } status = select(max + 1, &fds, 0, 0, ptime); #else - status = select(0, &fds, 0, 0, ptime); + HANDLE *hnds; + + hnds = (HANDLE *) xzalloc(sizeof(HANDLE) * (numobj + 1)); + for (index = 0; index < numobj; index++) + { + hnds[index] = listobj[index]->event; + } + + if (WaitForMultipleObjects(numobj, hnds, FALSE, timeout) == WAIT_FAILED) + status = -1; + else + status = 0; + xfree(hnds); #endif return status; diff --git a/scripts/TimeZones.cs b/scripts/TimeZones.cs index 1557d2cf9..36cea6050 100644 --- a/scripts/TimeZones.cs +++ b/scripts/TimeZones.cs @@ -1,4 +1,4 @@ -/** +/** * FreeRDP: A Remote Desktop Protocol Client * Time Zone Redirection Table Generator * @@ -24,224 +24,232 @@ using System.Collections.ObjectModel; namespace TimeZones { - struct SYSTEM_TIME_ENTRY - { - public UInt16 wYear; - public UInt16 wMonth; - public UInt16 wDayOfWeek; - public UInt16 wDay; - public UInt16 wHour; - public UInt16 wMinute; - public UInt16 wSecond; - public UInt16 wMilliseconds; - }; + struct SYSTEM_TIME_ENTRY + { + public UInt16 wYear; + public UInt16 wMonth; + public UInt16 wDayOfWeek; + public UInt16 wDay; + public UInt16 wHour; + public UInt16 wMinute; + public UInt16 wSecond; + public UInt16 wMilliseconds; + }; - struct TIME_ZONE_RULE_ENTRY - { - public long TicksStart; - public long TicksEnd; - public Int32 DaylightDelta; - public SYSTEM_TIME_ENTRY StandardDate; - public SYSTEM_TIME_ENTRY DaylightDate; - }; + struct TIME_ZONE_RULE_ENTRY + { + public long TicksStart; + public long TicksEnd; + public Int32 DaylightDelta; + public SYSTEM_TIME_ENTRY StandardDate; + public SYSTEM_TIME_ENTRY DaylightDate; + }; - struct TIME_ZONE_ENTRY - { - public string Id; - public UInt32 Bias; - public bool SupportsDST; - public string DisplayName; - public string StandardName; - public string DaylightName; - public string RuleTable; - public UInt32 RuleTableCount; - }; + struct TIME_ZONE_ENTRY + { + public string Id; + public UInt32 Bias; + public bool SupportsDST; + public string DisplayName; + public string StandardName; + public string DaylightName; + public string RuleTable; + public UInt32 RuleTableCount; + }; - class TimeZones - { - static void Main(string[] args) - { - int i; - UInt32 index; - const string file = @"TimeZones.txt"; - TimeZoneInfo.AdjustmentRule[] rules; - StreamWriter stream = new StreamWriter(file, false); - ReadOnlyCollection timeZones = TimeZoneInfo.GetSystemTimeZones(); + class TimeZones + { + static void Main(string[] args) + { + int i; + UInt32 index; + const string file = @"TimeZones.txt"; + TimeZoneInfo.AdjustmentRule[] rules; + StreamWriter stream = new StreamWriter(file, false); + ReadOnlyCollection timeZones = TimeZoneInfo.GetSystemTimeZones(); - stream.WriteLine(); + stream.WriteLine(); - stream.WriteLine("struct _SYSTEM_TIME_ENTRY"); - stream.WriteLine("{"); - stream.WriteLine("\tuint16 wYear;"); - stream.WriteLine("\tuint16 wMonth;"); - stream.WriteLine("\tuint16 wDayOfWeek;"); - stream.WriteLine("\tuint16 wDay;"); - stream.WriteLine("\tuint16 wHour;"); - stream.WriteLine("\tuint16 wMinute;"); - stream.WriteLine("\tuint16 wSecond;"); - stream.WriteLine("\tuint16 wMilliseconds;"); - stream.WriteLine("};"); - stream.WriteLine("typedef struct _SYSTEM_TIME_ENTRY SYSTEM_TIME_ENTRY;"); - stream.WriteLine(); + stream.WriteLine("struct _SYSTEM_TIME_ENTRY"); + stream.WriteLine("{"); + stream.WriteLine("\tuint16 wYear;"); + stream.WriteLine("\tuint16 wMonth;"); + stream.WriteLine("\tuint16 wDayOfWeek;"); + stream.WriteLine("\tuint16 wDay;"); + stream.WriteLine("\tuint16 wHour;"); + stream.WriteLine("\tuint16 wMinute;"); + stream.WriteLine("\tuint16 wSecond;"); + stream.WriteLine("\tuint16 wMilliseconds;"); + stream.WriteLine("};"); + stream.WriteLine("typedef struct _SYSTEM_TIME_ENTRY SYSTEM_TIME_ENTRY;"); + stream.WriteLine(); - stream.WriteLine("struct _TIME_ZONE_RULE_ENTRY"); - stream.WriteLine("{"); - stream.WriteLine("\tuint64 TicksStart;"); - stream.WriteLine("\tuint64 TicksEnd;"); - stream.WriteLine("\tsint32 DaylightDelta;"); - stream.WriteLine("\tSYSTEM_TIME_ENTRY StandardDate;"); - stream.WriteLine("\tSYSTEM_TIME_ENTRY DaylightDate;"); - stream.WriteLine("};"); - stream.WriteLine("typedef struct _TIME_ZONE_RULE_ENTRY TIME_ZONE_RULE_ENTRY;"); - stream.WriteLine(); + stream.WriteLine("struct _TIME_ZONE_RULE_ENTRY"); + stream.WriteLine("{"); + stream.WriteLine("\tuint64 TicksStart;"); + stream.WriteLine("\tuint64 TicksEnd;"); + stream.WriteLine("\tsint32 DaylightDelta;"); + stream.WriteLine("\tSYSTEM_TIME_ENTRY StandardDate;"); + stream.WriteLine("\tSYSTEM_TIME_ENTRY DaylightDate;"); + stream.WriteLine("};"); + stream.WriteLine("typedef struct _TIME_ZONE_RULE_ENTRY TIME_ZONE_RULE_ENTRY;"); + stream.WriteLine(); - stream.WriteLine("struct _TIME_ZONE_ENTRY"); - stream.WriteLine("{"); - stream.WriteLine("\tconst char* Id;"); - stream.WriteLine("\tuint32 Bias;"); - stream.WriteLine("\tboolean SupportsDST;"); - stream.WriteLine("\tconst char* DisplayName;"); - stream.WriteLine("\tconst char* StandardName;"); - stream.WriteLine("\tconst char* DaylightName;"); - stream.WriteLine("\tTIME_ZONE_RULE_ENTRY* RuleTable;"); - stream.WriteLine("\tuint32 RuleTableCount;"); - stream.WriteLine("};"); - stream.WriteLine("typedef struct _TIME_ZONE_ENTRY TIME_ZONE_ENTRY;"); - stream.WriteLine(); + stream.WriteLine("struct _TIME_ZONE_ENTRY"); + stream.WriteLine("{"); + stream.WriteLine("\tconst char* Id;"); + stream.WriteLine("\tuint32 Bias;"); + stream.WriteLine("\tboolean SupportsDST;"); + stream.WriteLine("\tconst char* DisplayName;"); + stream.WriteLine("\tconst char* StandardName;"); + stream.WriteLine("\tconst char* DaylightName;"); + stream.WriteLine("\tTIME_ZONE_RULE_ENTRY* RuleTable;"); + stream.WriteLine("\tuint32 RuleTableCount;"); + stream.WriteLine("};"); + stream.WriteLine("typedef struct _TIME_ZONE_ENTRY TIME_ZONE_ENTRY;"); + stream.WriteLine(); - index = 0; + index = 0; - foreach (TimeZoneInfo timeZone in timeZones) - { - rules = timeZone.GetAdjustmentRules(); + foreach (TimeZoneInfo timeZone in timeZones) + { + rules = timeZone.GetAdjustmentRules(); - if ((!timeZone.SupportsDaylightSavingTime) || (rules.Length < 1)) - { - index++; - continue; - } + if ((!timeZone.SupportsDaylightSavingTime) || (rules.Length < 1)) + { + index++; + continue; + } - stream.WriteLine("static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_{0}[] =", index); - stream.WriteLine("{"); + stream.WriteLine("static const TIME_ZONE_RULE_ENTRY TimeZoneRuleTable_{0}[] =", index); + stream.WriteLine("{"); - i = 0; - foreach (TimeZoneInfo.AdjustmentRule rule in rules) - { - DateTime time; - TIME_ZONE_RULE_ENTRY tzr; - TimeZoneInfo.TransitionTime transition; + i = 0; + foreach (TimeZoneInfo.AdjustmentRule rule in rules) + { + DateTime time; + TIME_ZONE_RULE_ENTRY tzr; + TimeZoneInfo.TransitionTime transition; - tzr.TicksStart = rule.DateEnd.ToUniversalTime().Ticks; - tzr.TicksEnd = rule.DateStart.ToUniversalTime().Ticks; - tzr.DaylightDelta = (Int32)rule.DaylightDelta.TotalMinutes; + tzr.TicksStart = rule.DateEnd.ToUniversalTime().Ticks; + tzr.TicksEnd = rule.DateStart.ToUniversalTime().Ticks; + tzr.DaylightDelta = (Int32)rule.DaylightDelta.TotalMinutes; - transition = rule.DaylightTransitionEnd; - time = transition.TimeOfDay; + transition = rule.DaylightTransitionEnd; + time = transition.TimeOfDay; - tzr.StandardDate.wYear = (UInt16)0; - tzr.StandardDate.wMonth = (UInt16)transition.Month; - tzr.StandardDate.wDayOfWeek = (UInt16)transition.DayOfWeek; - tzr.StandardDate.wDay = (UInt16)transition.Day; - tzr.StandardDate.wHour = (UInt16)time.Hour; - tzr.StandardDate.wMinute = (UInt16)time.Minute; - tzr.StandardDate.wSecond = (UInt16)time.Second; - tzr.StandardDate.wMilliseconds = (UInt16)time.Millisecond; + tzr.StandardDate.wYear = (UInt16)0; + tzr.StandardDate.wMonth = (UInt16)transition.Month; + tzr.StandardDate.wDayOfWeek = (UInt16)transition.DayOfWeek; + tzr.StandardDate.wDay = (UInt16)transition.Day; + tzr.StandardDate.wHour = (UInt16)time.Hour; + tzr.StandardDate.wMinute = (UInt16)time.Minute; + tzr.StandardDate.wSecond = (UInt16)time.Second; + tzr.StandardDate.wMilliseconds = (UInt16)time.Millisecond; - transition = rule.DaylightTransitionStart; - time = transition.TimeOfDay; + transition = rule.DaylightTransitionStart; + time = transition.TimeOfDay; - tzr.DaylightDate.wYear = (UInt16)0; - tzr.DaylightDate.wMonth = (UInt16)transition.Month; - tzr.DaylightDate.wDayOfWeek = (UInt16)transition.DayOfWeek; - tzr.DaylightDate.wDay = (UInt16)transition.Day; - tzr.DaylightDate.wHour = (UInt16)time.Hour; - tzr.DaylightDate.wMinute = (UInt16)time.Minute; - tzr.DaylightDate.wSecond = (UInt16)time.Second; - tzr.DaylightDate.wMilliseconds = (UInt16)time.Millisecond; + tzr.DaylightDate.wYear = (UInt16)0; + tzr.DaylightDate.wMonth = (UInt16)transition.Month; + tzr.DaylightDate.wDayOfWeek = (UInt16)transition.DayOfWeek; + tzr.DaylightDate.wDay = (UInt16)transition.Day; + tzr.DaylightDate.wHour = (UInt16)time.Hour; + tzr.DaylightDate.wMinute = (UInt16)time.Minute; + tzr.DaylightDate.wSecond = (UInt16)time.Second; + tzr.DaylightDate.wMilliseconds = (UInt16)time.Millisecond; - stream.Write("\t{"); - stream.Write(" {0}ULL, {1}ULL, {2},", tzr.TicksStart, tzr.TicksEnd, tzr.DaylightDelta); + stream.Write("\t{"); + stream.Write(" {0}ULL, {1}ULL, {2},", tzr.TicksStart, tzr.TicksEnd, tzr.DaylightDelta); - stream.Write(" { "); - stream.Write("{0}, {1}, {2}, {3}, {4}, {5}", - tzr.StandardDate.wYear, tzr.StandardDate.wMonth, tzr.StandardDate.wDayOfWeek, - tzr.StandardDate.wDay, tzr.StandardDate.wHour, tzr.StandardDate.wMinute, - tzr.StandardDate.wSecond, tzr.StandardDate.wMilliseconds); - stream.Write(" }, "); + stream.Write(" { "); + stream.Write("{0}, {1}, {2}, {3}, {4}, {5}", + tzr.StandardDate.wYear, tzr.StandardDate.wMonth, tzr.StandardDate.wDayOfWeek, + tzr.StandardDate.wDay, tzr.StandardDate.wHour, tzr.StandardDate.wMinute, + tzr.StandardDate.wSecond, tzr.StandardDate.wMilliseconds); + stream.Write(" }, "); - stream.Write("{ "); - stream.Write("{0}, {1}, {2}, {3}, {4}, {5}", - tzr.DaylightDate.wYear, tzr.DaylightDate.wMonth, tzr.DaylightDate.wDayOfWeek, - tzr.DaylightDate.wDay, tzr.DaylightDate.wHour, tzr.DaylightDate.wMinute, - tzr.DaylightDate.wSecond, tzr.DaylightDate.wMilliseconds); - stream.Write(" },"); + stream.Write("{ "); + stream.Write("{0}, {1}, {2}, {3}, {4}, {5}", + tzr.DaylightDate.wYear, tzr.DaylightDate.wMonth, tzr.DaylightDate.wDayOfWeek, + tzr.DaylightDate.wDay, tzr.DaylightDate.wHour, tzr.DaylightDate.wMinute, + tzr.DaylightDate.wSecond, tzr.DaylightDate.wMilliseconds); + stream.Write(" },"); - if (++i < rules.Length) - stream.WriteLine(" },"); - else - stream.WriteLine(" }"); - } + if (++i < rules.Length) + stream.WriteLine(" },"); + else + stream.WriteLine(" }"); + } - stream.WriteLine("};"); - stream.WriteLine(); - index++; - } + stream.WriteLine("};"); + stream.WriteLine(); + index++; + } - index = 0; - stream.WriteLine("static const TIME_ZONE_ENTRY TimeZoneTable[] ="); - stream.WriteLine("{"); + index = 0; + stream.WriteLine("static const TIME_ZONE_ENTRY TimeZoneTable[] ="); + stream.WriteLine("{"); - foreach (TimeZoneInfo timeZone in timeZones) - { - TIME_ZONE_ENTRY tz; - TimeSpan offset = timeZone.BaseUtcOffset; + foreach (TimeZoneInfo timeZone in timeZones) + { + Int32 sbias; + TIME_ZONE_ENTRY tz; + TimeSpan offset = timeZone.BaseUtcOffset; - rules = timeZone.GetAdjustmentRules(); + rules = timeZone.GetAdjustmentRules(); - tz.Id = timeZone.Id; + tz.Id = timeZone.Id; - if (offset.Hours >= 0) - tz.Bias = (UInt32)((offset.Hours * 60) + offset.Minutes); - else - tz.Bias = (UInt32)(((-1 * offset.Hours) * 60) + offset.Minutes + 720); + if (offset.Hours >= 0) + { + sbias = (offset.Hours * 60) + offset.Minutes; + tz.Bias = (UInt32) sbias; + } + else + { + sbias = (offset.Hours * 60) + offset.Minutes; + tz.Bias = (UInt32) (1440 + sbias); + } - tz.SupportsDST = timeZone.SupportsDaylightSavingTime; + tz.SupportsDST = timeZone.SupportsDaylightSavingTime; - tz.DisplayName = timeZone.DisplayName; - tz.StandardName = timeZone.StandardName; - tz.DaylightName = timeZone.DaylightName; + tz.DisplayName = timeZone.DisplayName; + tz.StandardName = timeZone.StandardName; + tz.DaylightName = timeZone.DaylightName; - if ((!tz.SupportsDST) || (rules.Length < 1)) - { - tz.RuleTableCount = 0; - tz.RuleTable = "NULL"; - } - else - { - tz.RuleTableCount = (UInt32)rules.Length; - tz.RuleTable = "&TimeZoneRuleTable_" + index; - tz.RuleTable = "(TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_" + index; - } + if ((!tz.SupportsDST) || (rules.Length < 1)) + { + tz.RuleTableCount = 0; + tz.RuleTable = "NULL"; + } + else + { + tz.RuleTableCount = (UInt32)rules.Length; + tz.RuleTable = "&TimeZoneRuleTable_" + index; + tz.RuleTable = "(TIME_ZONE_RULE_ENTRY*) &TimeZoneRuleTable_" + index; + } - stream.WriteLine("\t{"); + stream.WriteLine("\t{"); - stream.WriteLine("\t\t\"{0}\", {1}, {2}, \"{0}\",", - tz.Id, tz.Bias, tz.SupportsDST ? "true" : "false", tz.DisplayName); + stream.WriteLine("\t\t\"{0}\", {1}, {2}, \"{3}\",", + tz.Id, tz.Bias, tz.SupportsDST ? "true" : "false", tz.DisplayName); - stream.WriteLine("\t\t\"{0}\", \"{0}\",", tz.StandardName, tz.DaylightName); - stream.WriteLine("\t\t{0}, {1}", tz.RuleTable, tz.RuleTableCount); + stream.WriteLine("\t\t\"{0}\", \"{1}\",", tz.StandardName, tz.DaylightName); + stream.WriteLine("\t\t{0}, {1}", tz.RuleTable, tz.RuleTableCount); - index++; + index++; - if ((int) index < timeZones.Count) - stream.WriteLine("\t},"); - else - stream.WriteLine("\t}"); - } - stream.WriteLine("};"); - stream.WriteLine(); + if ((int)index < timeZones.Count) + stream.WriteLine("\t},"); + else + stream.WriteLine("\t}"); + } + stream.WriteLine("};"); + stream.WriteLine(); - stream.Close(); - } - } + stream.Close(); + } + } } + diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index cf7f3e743..a42687eb0 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -29,9 +29,9 @@ if(NOT WIN32) if(WITH_X11) add_subdirectory(X11) endif() - - # Build Server Channels library - add_subdirectory(channels) else() add_subdirectory(Windows) endif() + +# Build Server Channels library +add_subdirectory(channels) diff --git a/server/Windows/CMakeLists.txt b/server/Windows/CMakeLists.txt index 1de211f5d..334b65a0b 100644 --- a/server/Windows/CMakeLists.txt +++ b/server/Windows/CMakeLists.txt @@ -18,9 +18,20 @@ # limitations under the License. add_executable(wfreerdp-server - wfreerdp.c) + wf_input.c + wf_input.h + wf_peer.c + wf_peer.h + wfreerdp.c + wfreerdp.h) + +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(wfreerdp-server freerdp) +else() + target_link_libraries(wfreerdp-server + freerdp-core + freerdp-utils + freerdp-codec + freerdp-channels) +endif() -target_link_libraries(wfreerdp-server freerdp-core) -target_link_libraries(wfreerdp-server freerdp-utils) -target_link_libraries(wfreerdp-server freerdp-codec) -target_link_libraries(wfreerdp-server freerdp-channels) diff --git a/server/Windows/wf_input.c b/server/Windows/wf_input.c new file mode 100644 index 000000000..6c28a93cd --- /dev/null +++ b/server/Windows/wf_input.c @@ -0,0 +1,161 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Windows Server + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "wf_input.h" + +void wf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code) +{ + INPUT keyboard_event; + + keyboard_event.type = INPUT_KEYBOARD; + keyboard_event.ki.wVk = 0; + keyboard_event.ki.wScan = code; + keyboard_event.ki.dwFlags = KEYEVENTF_SCANCODE; + keyboard_event.ki.dwExtraInfo = 0; + keyboard_event.ki.time = 0; + + if (flags & KBD_FLAGS_RELEASE) + keyboard_event.ki.dwFlags |= KEYEVENTF_KEYUP; + + if (flags & KBD_FLAGS_EXTENDED) + keyboard_event.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; + + SendInput(1, &keyboard_event, sizeof(INPUT)); +} + +void wf_peer_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code) +{ + INPUT keyboard_event; + + keyboard_event.type = INPUT_KEYBOARD; + keyboard_event.ki.wVk = 0; + keyboard_event.ki.wScan = code; + keyboard_event.ki.dwFlags = KEYEVENTF_UNICODE; + keyboard_event.ki.dwExtraInfo = 0; + keyboard_event.ki.time = 0; + + if (flags & KBD_FLAGS_RELEASE) + keyboard_event.ki.dwFlags |= KEYEVENTF_KEYUP; + + SendInput(1, &keyboard_event, sizeof(INPUT)); +} + +void wf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ + INPUT mouse_event; + + ZeroMemory(&mouse_event, sizeof(INPUT)); + mouse_event.type = INPUT_MOUSE; + + if (flags & PTR_FLAGS_WHEEL) + { + mouse_event.mi.dwFlags = MOUSEEVENTF_WHEEL; + mouse_event.mi.mouseData = flags & WheelRotationMask; + + if (flags & PTR_FLAGS_WHEEL_NEGATIVE) + mouse_event.mi.mouseData *= -1; + + SendInput(1, &mouse_event, sizeof(INPUT)); + } + else + { + if (flags & PTR_FLAGS_MOVE) + { + mouse_event.mi.dx = x * (0xFFFF / GetSystemMetrics(SM_CXSCREEN)); + mouse_event.mi.dy = y * (0xFFFF / GetSystemMetrics(SM_CYSCREEN)); + mouse_event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; + + SendInput(1, &mouse_event, sizeof(INPUT)); + } + + mouse_event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE; + + if (flags & PTR_FLAGS_BUTTON1) + { + if (flags & PTR_FLAGS_DOWN) + mouse_event.mi.dwFlags |= MOUSEEVENTF_LEFTDOWN; + else + mouse_event.mi.dwFlags |= MOUSEEVENTF_LEFTUP; + + SendInput(1, &mouse_event, sizeof(INPUT)); + } + else if (flags & PTR_FLAGS_BUTTON2) + { + if (flags & PTR_FLAGS_DOWN) + mouse_event.mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN; + else + mouse_event.mi.dwFlags |= MOUSEEVENTF_RIGHTUP; + + SendInput(1, &mouse_event, sizeof(INPUT)); + } + else if (flags & PTR_FLAGS_BUTTON3) + { + if (flags & PTR_FLAGS_DOWN) + mouse_event.mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN; + else + mouse_event.mi.dwFlags |= MOUSEEVENTF_MIDDLEUP; + + SendInput(1, &mouse_event, sizeof(INPUT)); + } + } +} + +void wf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ + if ((flags & PTR_XFLAGS_BUTTON1) || (flags & PTR_XFLAGS_BUTTON2)) + { + INPUT mouse_event; + ZeroMemory(&mouse_event, sizeof(INPUT)); + + mouse_event.type = INPUT_MOUSE; + + if (flags & PTR_FLAGS_MOVE) + { + mouse_event.mi.dx = x * (0xFFFF / GetSystemMetrics(SM_CXSCREEN)); + mouse_event.mi.dy = y * (0xFFFF / GetSystemMetrics(SM_CYSCREEN)); + mouse_event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; + + SendInput(1, &mouse_event, sizeof(INPUT)); + } + + mouse_event.mi.dx = mouse_event.mi.dy = mouse_event.mi.dwFlags = 0; + + if (flags & PTR_XFLAGS_DOWN) + mouse_event.mi.dwFlags |= MOUSEEVENTF_XDOWN; + else + mouse_event.mi.dwFlags |= MOUSEEVENTF_XUP; + + if (flags & PTR_XFLAGS_BUTTON1) + mouse_event.mi.mouseData = XBUTTON1; + else if (flags & PTR_XFLAGS_BUTTON2) + mouse_event.mi.mouseData = XBUTTON2; + + SendInput(1, &mouse_event, sizeof(INPUT)); + } + else + { + wf_peer_mouse_event(input, flags, x, y); + } +} diff --git a/server/Windows/wf_input.h b/server/Windows/wf_input.h new file mode 100644 index 000000000..52f054977 --- /dev/null +++ b/server/Windows/wf_input.h @@ -0,0 +1,30 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Windows Server + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WF_INPUT_H +#define WF_INPUT_H + +#include "wfreerdp.h" + +void wf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code); +void wf_peer_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code); +void wf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); +void wf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); + +#endif /* WF_INPUT_H */ diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c new file mode 100644 index 000000000..56273b3d9 --- /dev/null +++ b/server/Windows/wf_peer.c @@ -0,0 +1,91 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Windows Server + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "wf_peer.h" + +void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context) +{ + +} + +void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context) +{ + if (context) + { + + } +} + +void wf_peer_init(freerdp_peer* client) +{ + client->context_size = sizeof(wfPeerContext); + client->ContextNew = (psPeerContextNew) wf_peer_context_new; + client->ContextFree = (psPeerContextFree) wf_peer_context_free; + freerdp_peer_context_new(client); +} + +boolean wf_peer_post_connect(freerdp_peer* client) +{ + wfPeerContext* context = (wfPeerContext*) client->context; + + /** + * This callback is called when the entire connection sequence is done, i.e. we've received the + * Font List PDU from the client and sent out the Font Map PDU. + * The server may start sending graphics output and receiving keyboard/mouse input after this + * callback returns. + */ + + printf("Client %s is activated (osMajorType %d osMinorType %d)", client->local ? "(local)" : client->hostname, + client->settings->os_major_type, client->settings->os_minor_type); + + if (client->settings->autologon) + { + printf(" and wants to login automatically as %s\\%s", + client->settings->domain ? client->settings->domain : "", + client->settings->username); + + /* A real server may perform OS login here if NLA is not executed previously. */ + } + printf("\n"); + + printf("Client requested desktop: %dx%dx%d\n", + client->settings->width, client->settings->height, client->settings->color_depth); + + return true; +} + +boolean wf_peer_activate(freerdp_peer* client) +{ + wfPeerContext* context = (wfPeerContext*) client->context; + + context->activated = true; + + return true; +} + +void wf_peer_synchronize_event(rdpInput* input, uint32 flags) +{ + +} diff --git a/server/Windows/wf_peer.h b/server/Windows/wf_peer.h new file mode 100644 index 000000000..2f8d120a7 --- /dev/null +++ b/server/Windows/wf_peer.h @@ -0,0 +1,35 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Windows Server + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WF_PEER_H +#define WF_PEER_H + +#include "wfreerdp.h" + +void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context); +void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context); + +void wf_peer_init(freerdp_peer* client); + +boolean wf_peer_post_connect(freerdp_peer* client); +boolean wf_peer_activate(freerdp_peer* client); + +void wf_peer_synchronize_event(rdpInput* input, uint32 flags); + +#endif /* WF_PEER_H */ diff --git a/server/Windows/wfreerdp.c b/server/Windows/wfreerdp.c index 9d62f4957..f793bc8f8 100644 --- a/server/Windows/wfreerdp.c +++ b/server/Windows/wfreerdp.c @@ -17,141 +17,33 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include #include + +#include #include -#include + +#include #include #include #include -#include -#include -#include +#include + +#include "wf_input.h" +#include "wf_peer.h" + +#include "wfreerdp.h" HANDLE g_done_event; int g_thread_count = 0; -struct wf_peer_context -{ - rdpContext _p; - boolean activated; -}; -typedef struct wf_peer_context wfPeerContext; - -void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context) -{ - -} - -void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context) -{ - if (context) - { - } -} - -static void wf_peer_init(freerdp_peer* client) -{ - client->context_size = sizeof(wfPeerContext); - client->ContextNew = (psPeerContextNew) wf_peer_context_new; - client->ContextFree = (psPeerContextFree) wf_peer_context_free; - freerdp_peer_context_new(client); -} - -boolean wf_peer_post_connect(freerdp_peer* client) -{ - wfPeerContext* context = (wfPeerContext*) client->context; - - /** - * This callback is called when the entire connection sequence is done, i.e. we've received the - * Font List PDU from the client and sent out the Font Map PDU. - * The server may start sending graphics output and receiving keyboard/mouse input after this - * callback returns. - */ - - printf("Client %s is activated (osMajorType %d osMinorType %d)", client->local ? "(local)" : client->hostname, - client->settings->os_major_type, client->settings->os_minor_type); - - if (client->settings->autologon) - { - printf(" and wants to login automatically as %s\\%s", - client->settings->domain ? client->settings->domain : "", - client->settings->username); - - /* A real server may perform OS login here if NLA is not executed previously. */ - } - printf("\n"); - - printf("Client requested desktop: %dx%dx%d\n", - client->settings->width, client->settings->height, client->settings->color_depth); - - /* A real server should tag the peer as activated here and start sending updates in main loop. */ - - /* Return false here would stop the execution of the peer mainloop. */ - return true; -} - -boolean wf_peer_activate(freerdp_peer* client) -{ - wfPeerContext* context = (wfPeerContext*) client->context; - - context->activated = true; - - return true; -} - -void wf_peer_synchronize_event(rdpInput* input, uint32 flags) -{ - printf("Client sent a synchronize event (flags:0x%X)\n", flags); -} - -void wf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code) -{ - freerdp_peer* client = input->context->peer; - rdpUpdate* update = client->update; - wfPeerContext* context = (wfPeerContext*) input->context; - - printf("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code); - - if ((flags & 0x4000) && code == 0x1F) /* 's' key */ - { - if (client->settings->width != 800) - { - client->settings->width = 800; - client->settings->height = 600; - } - else - { - client->settings->width = 640; - client->settings->height = 480; - } - update->DesktopResize(update->context); - context->activated = false; - } - else if ((flags & 0x4000) && code == 0x2D) /* 'x' key */ - { - client->Close(client); - } -} - -void wf_peer_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code) -{ - printf("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); -} - -void wf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) -{ - printf("Client sent a mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y); -} - -void wf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) -{ - printf("Client sent an extended mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y); -} - static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) { int rcount; @@ -167,10 +59,6 @@ static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) client->settings->cert_file = xstrdup("server.crt"); client->settings->privatekey_file = xstrdup("server.key"); - client->settings->nla_security = true; - client->settings->tls_security = false; - client->settings->rdp_security = false; - client->PostConnect = wf_peer_post_connect; client->Activate = wf_peer_activate; @@ -248,6 +136,11 @@ static void wf_server_main_loop(freerdp_listener* instance) int main(int argc, char* argv[]) { + HKEY hKey; + LONG status; + DWORD dwType; + DWORD dwSize; + DWORD dwValue; int port = 3389; WSADATA wsa_data; freerdp_listener* instance; @@ -261,6 +154,16 @@ int main(int argc, char* argv[]) g_done_event = CreateEvent(0, 1, 0, 0); + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + + if (status == ERROR_SUCCESS) + { + if (RegQueryValueEx(hKey, _T("DefaultPort"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + port = dwValue; + } + + RegCloseKey(hKey); + if (argc == 2) port = atoi(argv[1]); diff --git a/server/Windows/wfreerdp.h b/server/Windows/wfreerdp.h new file mode 100644 index 000000000..d22b27b1a --- /dev/null +++ b/server/Windows/wfreerdp.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Windows Server + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WFREERDP_H +#define WFREERDP_H + +#include + +struct wf_peer_context +{ + rdpContext _p; + boolean activated; +}; +typedef struct wf_peer_context wfPeerContext; + +#endif /* WFREERDP_H */ diff --git a/server/X11/CMakeLists.txt b/server/X11/CMakeLists.txt index 11a4202f3..be56d64bc 100644 --- a/server/X11/CMakeLists.txt +++ b/server/X11/CMakeLists.txt @@ -60,11 +60,18 @@ if(WITH_XTEST) target_link_libraries(xfreerdp-server ${XTEST_LIBRARIES}) endif() -target_link_libraries(xfreerdp-server freerdp-core) -target_link_libraries(xfreerdp-server freerdp-codec) -target_link_libraries(xfreerdp-server freerdp-utils) -target_link_libraries(xfreerdp-server freerdp-gdi) -target_link_libraries(xfreerdp-server freerdp-crypto) -target_link_libraries(xfreerdp-server freerdp-locale) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(xfreerdp-server freerdp) + target_link_libraries(xfreerdp-server winpr) +else() + target_link_libraries(xfreerdp-server + freerdp-core + freerdp-codec + freerdp-utils + freerdp-gdi + freerdp-crypto + freerdp-locale) + target_link_libraries(xfreerdp-server winpr-sspi) +endif() + target_link_libraries(xfreerdp-server ${X11_LIBRARIES}) -target_link_libraries(xfreerdp-server winpr-sspi) diff --git a/server/X11/xf_encode.c b/server/X11/xf_encode.c index 80f6bd3b7..5a941ceb6 100644 --- a/server/X11/xf_encode.c +++ b/server/X11/xf_encode.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/server/X11/xf_event.c b/server/X11/xf_event.c index d361a5c10..1a3780792 100644 --- a/server/X11/xf_event.c +++ b/server/X11/xf_event.c @@ -17,12 +17,17 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include #include #include #include + #include #include "xf_event.h" diff --git a/server/X11/xf_input.c b/server/X11/xf_input.c index 169c20e49..9d56ab224 100644 --- a/server/X11/xf_input.c +++ b/server/X11/xf_input.c @@ -17,7 +17,12 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include + #include #include "xf_input.h" diff --git a/server/X11/xf_peer.c b/server/X11/xf_peer.c index 7cf58b19b..e20c11938 100644 --- a/server/X11/xf_peer.c +++ b/server/X11/xf_peer.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -27,6 +31,7 @@ #include #include #include + #include #include #include diff --git a/server/X11/xfreerdp.c b/server/X11/xfreerdp.c index b8dd6a0d2..379209760 100644 --- a/server/X11/xfreerdp.c +++ b/server/X11/xfreerdp.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/server/channels/CMakeLists.txt b/server/channels/CMakeLists.txt index b4cd4cb4f..2ee9473e5 100644 --- a/server/channels/CMakeLists.txt +++ b/server/channels/CMakeLists.txt @@ -19,13 +19,16 @@ set(FREERDP_SERVER_CHANNELS_SRCS audin.c - rdpsnd.c -) + rdpsnd.c) add_library(freerdp-server-channels ${FREERDP_SERVER_CHANNELS_SRCS}) set_target_properties(freerdp-server-channels PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -target_link_libraries(freerdp-server-channels freerdp-channels freerdp-utils) + +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(freerdp-server-channels freerdp) +else() + target_link_libraries(freerdp-server-channels freerdp-channels freerdp-utils) +endif() install(TARGETS freerdp-server-channels DESTINATION ${CMAKE_INSTALL_LIBDIR}) - diff --git a/server/channels/audin.c b/server/channels/audin.c index 587b99f0a..3f51f0a2b 100644 --- a/server/channels/audin.c +++ b/server/channels/audin.c @@ -17,6 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + #include #include #include @@ -25,10 +33,6 @@ #include #include -#include -#include -#include - #define MSG_SNDIN_VERSION 0x01 #define MSG_SNDIN_FORMATS 0x02 #define MSG_SNDIN_OPEN 0x03 @@ -299,16 +303,20 @@ static void* audin_server_thread_func(void* arg) while (ready) { freerdp_thread_wait(thread); + if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); + if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == false) { if (bytes_returned == 0) break; - stream_check_size(s, bytes_returned); + + stream_check_size(s, (int) bytes_returned); + if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == false) break; diff --git a/server/channels/rdpsnd.c b/server/channels/rdpsnd.c index a18e76916..61a080a20 100644 --- a/server/channels/rdpsnd.c +++ b/server/channels/rdpsnd.c @@ -17,6 +17,14 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + #include #include #include @@ -25,10 +33,6 @@ #include #include -#include -#include -#include - typedef struct _rdpsnd_server { rdpsnd_server_context context; @@ -121,6 +125,7 @@ static boolean rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, STREAM* s) if (rdpsnd->context.num_client_formats > 0) { rdpsnd->context.client_formats = xzalloc(rdpsnd->context.num_client_formats * sizeof(rdpsndFormat)); + for (i = 0; i < rdpsnd->context.num_client_formats; i++) { if (stream_get_left(s) < 18) @@ -137,6 +142,7 @@ static boolean rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, STREAM* s) stream_read_uint16(s, rdpsnd->context.client_formats[i].nBlockAlign); stream_read_uint16(s, rdpsnd->context.client_formats[i].wBitsPerSample); stream_read_uint16(s, rdpsnd->context.client_formats[i].cbSize); + if (rdpsnd->context.client_formats[i].cbSize > 0) { stream_seek(s, rdpsnd->context.client_formats[i].cbSize); @@ -147,8 +153,6 @@ static boolean rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, STREAM* s) return true; } - - static void* rdpsnd_server_thread_func(void* arg) { void* fd; @@ -174,16 +178,20 @@ static void* rdpsnd_server_thread_func(void* arg) while (1) { freerdp_thread_wait(thread); + if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); + if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == false) { if (bytes_returned == 0) break; - stream_check_size(s, bytes_returned); + + stream_check_size(s, (int) bytes_returned); + if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == false) break; @@ -192,10 +200,12 @@ static void* rdpsnd_server_thread_func(void* arg) stream_read_uint8(s, msgType); stream_seek_uint8(s); /* bPad */ stream_read_uint16(s, BodySize); - if (BodySize + 4 > bytes_returned) + + if (BodySize + 4 > (int) bytes_returned) continue; - switch (msgType) { + switch (msgType) + { case SNDC_FORMATS: if (rdpsnd_server_recv_formats(rdpsnd, s)) { @@ -218,6 +228,7 @@ static boolean rdpsnd_server_initialize(rdpsnd_server_context* context) rdpsnd_server* rdpsnd = (rdpsnd_server*) context; rdpsnd->rdpsnd_channel = WTSVirtualChannelOpenEx(context->vcm, "rdpsnd", 0); + if (rdpsnd->rdpsnd_channel != NULL) { rdpsnd->rdpsnd_pdu = stream_new(4096); @@ -250,6 +261,7 @@ static void rdpsnd_server_select_format(rdpsnd_server_context* context, int clie context->selected_client_format = client_format_index; format = &context->client_formats[client_format_index]; + if (format->wFormatTag == 0x11) { bs = (format->nBlockAlign - 4 * format->nChannels) * 4; @@ -264,6 +276,7 @@ static void rdpsnd_server_select_format(rdpsnd_server_context* context, int clie { rdpsnd->out_frames = 0x4000 / rdpsnd->src_bytes_per_frame; } + if (format->nSamplesPerSec != context->src_format.nSamplesPerSec) { rdpsnd->out_frames = (rdpsnd->out_frames * context->src_format.nSamplesPerSec + format->nSamplesPerSec - 100) / format->nSamplesPerSec; @@ -271,6 +284,7 @@ static void rdpsnd_server_select_format(rdpsnd_server_context* context, int clie rdpsnd->out_pending_frames = 0; out_buffer_size = rdpsnd->out_frames * rdpsnd->src_bytes_per_frame; + if (rdpsnd->out_buffer_size < out_buffer_size) { rdpsnd->out_buffer = xrealloc(rdpsnd->out_buffer, out_buffer_size); diff --git a/server/test/CMakeLists.txt b/server/test/CMakeLists.txt index 368d4d976..fbf0d72ce 100644 --- a/server/test/CMakeLists.txt +++ b/server/test/CMakeLists.txt @@ -20,8 +20,15 @@ add_executable(tfreerdp-server tfreerdp.c) -target_link_libraries(tfreerdp-server freerdp-core) -target_link_libraries(tfreerdp-server freerdp-utils) -target_link_libraries(tfreerdp-server freerdp-codec) -target_link_libraries(tfreerdp-server freerdp-channels) -target_link_libraries(tfreerdp-server freerdp-server-channels) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(tfreerdp-server + freerdp + freerdp-server-channels) +else() + target_link_libraries(tfreerdp-server + freerdp-core + freerdp-utils + freerdp-codec + freerdp-channels + freerdp-server-channels) +endif() diff --git a/server/test/tfreerdp.c b/server/test/tfreerdp.c index 3f6771496..d3052ccc7 100644 --- a/server/test/tfreerdp.c +++ b/server/test/tfreerdp.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -25,6 +29,7 @@ #include #include #include + #include #include #include diff --git a/third-party/.gitignore b/third-party/.gitignore new file mode 100644 index 000000000..453af308c --- /dev/null +++ b/third-party/.gitignore @@ -0,0 +1,2 @@ +**/** + diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt new file mode 100644 index 000000000..5a27d8337 --- /dev/null +++ b/third-party/CMakeLists.txt @@ -0,0 +1,31 @@ +# Third-Party Extensions +# +# Copyright 2012 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# The third-party directory is meant for third-party components to be built +# as part of the main FreeRDP build system, making separate maintenance easier. +# Subdirectories of the third-party directory are ignored by git, but are +# automatically included by CMake when the -DWITH_THIRD_PARTY=on option is used. + +file(GLOB all_valid_subdirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/CMakeLists.txt") + +foreach(dir ${all_valid_subdirs}) + message(STATUS "path = ${dir}") + if(${dir} MATCHES "^([^/]*)//CMakeLists.txt") + string(REGEX REPLACE "^([^/]*)//CMakeLists.txt" "\\1" dir_trimmed ${dir}) + add_subdirectory(${dir_trimmed}) + endif() +endforeach(dir) + diff --git a/winpr/CMakeLists.txt b/winpr/CMakeLists.txt index 177734588..4ad76b33d 100644 --- a/winpr/CMakeLists.txt +++ b/winpr/CMakeLists.txt @@ -1,9 +1,7 @@ # WinPR: Windows Portable Runtime # winpr cmake build script # -# Copyright 2011 O.S. Systems Software Ltda. -# Copyright 2011 Otavio Salvador -# Copyright 2011 Marc-Andre Moreau +# Copyright 2012 Marc-Andre Moreau # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,18 +15,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -add_subdirectory(crt) -add_subdirectory(utils) -add_subdirectory(heap) -add_subdirectory(handle) -add_subdirectory(synch) -add_subdirectory(sysinfo) -add_subdirectory(bcrypt) -add_subdirectory(dsparse) -add_subdirectory(rpc) -add_subdirectory(sspicli) -add_subdirectory(sspi) -add_subdirectory(registry) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h) + +add_subdirectory(include) + +add_subdirectory(libwinpr) add_subdirectory(tools) diff --git a/winpr/include/CMakeLists.txt b/winpr/include/CMakeLists.txt new file mode 100644 index 000000000..fec1ede14 --- /dev/null +++ b/winpr/include/CMakeLists.txt @@ -0,0 +1,19 @@ +# WinPR: Windows Portable Runtime +# winpr cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +file(GLOB WINPR_HEADERS "winpr/*.h") +install(FILES ${WINPR_HEADERS} DESTINATION include/winpr) diff --git a/winpr/include/winpr/asn1.h b/winpr/include/winpr/asn1.h new file mode 100644 index 000000000..69f95e550 --- /dev/null +++ b/winpr/include/winpr/asn1.h @@ -0,0 +1,505 @@ +/** + * WinPR: Windows Portable Runtime + * ASN.1 Encoding & Decoding Engine + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_ASN1_H +#define WINPR_ASN1_H + +#include +#include + +typedef unsigned char ASN1uint8_t; +typedef signed char ASN1int8_t; + +typedef unsigned short ASN1uint16_t; +typedef signed short ASN1int16_t; + +typedef unsigned long ASN1uint32_t; +typedef signed long ASN1int32_t; + +typedef ASN1uint8_t ASN1octet_t; + +typedef ASN1uint8_t ASN1bool_t; + +struct tagASN1intx_t +{ + ASN1uint32_t length; + ASN1octet_t* value; +}; +typedef struct tagASN1intx_t ASN1intx_t; + +struct tagASN1octetstring_t +{ + ASN1uint32_t length; + ASN1octet_t* value; +}; +typedef struct tagASN1octetstring_t ASN1octetstring_t; + +struct tagASN1octetstring2_t +{ + ASN1uint32_t length; + ASN1octet_t value[1]; +}; +typedef struct tagASN1octetstring2_t ASN1octetstring2_t; + +struct ASN1iterator_s +{ + struct ASN1iterator_s* next; + void* value; +}; +typedef struct ASN1iterator_s ASN1iterator_t; + +struct tagASN1bitstring_t +{ + ASN1uint32_t length; + ASN1octet_t* value; +}; +typedef struct tagASN1bitstring_t ASN1bitstring_t; + +typedef char ASN1char_t; + +struct tagASN1charstring_t +{ + ASN1uint32_t length; + ASN1char_t* value; +}; +typedef struct tagASN1charstring_t ASN1charstring_t; + +typedef ASN1uint16_t ASN1char16_t; + +struct tagASN1char16string_t +{ + ASN1uint32_t length; + ASN1char16_t* value; +}; +typedef struct tagASN1char16string_t ASN1char16string_t; + +typedef ASN1uint32_t ASN1char32_t; + +struct tagASN1char32string_t +{ + ASN1uint32_t length; + ASN1char32_t* value; +}; +typedef struct tagASN1char32string_t ASN1char32string_t; + +typedef ASN1char_t* ASN1ztcharstring_t; +typedef ASN1char16_t* ASN1ztchar16string_t; +typedef ASN1char32_t* ASN1ztchar32string_t; + +struct tagASN1wstring_t +{ + ASN1uint32_t length; + WCHAR* value; +}; +typedef struct tagASN1wstring_t ASN1wstring_t; + +struct ASN1objectidentifier_s +{ + struct ASN1objectidentifier_s* next; + ASN1uint32_t value; +}; +typedef struct ASN1objectidentifier_s* ASN1objectidentifier_t; + +struct tagASN1objectidentifier2_t +{ + ASN1uint16_t count; + ASN1uint32_t value[16]; +}; +typedef struct tagASN1objectidentifier2_t ASN1objectidentifier2_t; + +struct tagASN1encodedOID_t +{ + ASN1uint16_t length; + ASN1octet_t* value; +}; +typedef struct tagASN1encodedOID_t ASN1encodedOID_t; + +typedef ASN1ztcharstring_t ASN1objectdescriptor_t; + +struct tagASN1generalizedtime_t +{ + ASN1uint16_t year; + ASN1uint8_t month; + ASN1uint8_t day; + ASN1uint8_t hour; + ASN1uint8_t minute; + ASN1uint8_t second; + ASN1uint16_t millisecond; + ASN1bool_t universal; + ASN1int16_t diff; +}; +typedef struct tagASN1generalizedtime_t ASN1generalizedtime_t; + +struct tagASN1utctime_t +{ + ASN1uint8_t year; + ASN1uint8_t month; + ASN1uint8_t day; + ASN1uint8_t hour; + ASN1uint8_t minute; + ASN1uint8_t second; + ASN1bool_t universal; + ASN1int16_t diff; +}; +typedef struct tagASN1utctime_t ASN1utctime_t; + +struct tagASN1open_t +{ + ASN1uint32_t length; + + union + { + void* encoded; + void* value; + }; +}; +typedef struct tagASN1open_t ASN1open_t; + +enum tagASN1blocktype_e +{ + ASN1_DER_SET_OF_BLOCK, +}; +typedef enum tagASN1blocktype_e ASN1blocktype_e; + +typedef ASN1int32_t ASN1enum_t; +typedef ASN1uint16_t ASN1choice_t; +typedef ASN1uint32_t ASN1magic_t; + +enum +{ + ASN1_CHOICE_BASE = 1, + ASN1_CHOICE_INVALID = -1, + ASN1_CHOICE_EXTENSION = 0, +}; + +enum tagASN1error_e +{ + ASN1_SUCCESS = 0, + ASN1_ERR_INTERNAL = -1001, + ASN1_ERR_EOD = -1002, + ASN1_ERR_CORRUPT = -1003, + ASN1_ERR_LARGE = -1004, + ASN1_ERR_CONSTRAINT = -1005, + ASN1_ERR_MEMORY = -1006, + ASN1_ERR_OVERFLOW = -1007, + ASN1_ERR_BADPDU = -1008, + ASN1_ERR_BADARGS = -1009, + ASN1_ERR_BADREAL = -1010, + ASN1_ERR_BADTAG = -1011, + ASN1_ERR_CHOICE = -1012, + ASN1_ERR_RULE = -1013, + ASN1_ERR_UTF8 = -1014, + ASN1_ERR_PDU_TYPE = -1051, + ASN1_ERR_NYI = -1052, + ASN1_WRN_EXTENDED = 1001, + ASN1_WRN_NOEOD = 1002, +}; +typedef enum tagASN1error_e ASN1error_e; + +enum tagASN1encodingrule_e +{ + ASN1_BER_RULE_BER = 0x0100, + ASN1_BER_RULE_CER = 0x0200, + ASN1_BER_RULE_DER = 0x0400, + ASN1_BER_RULE = ASN1_BER_RULE_BER | ASN1_BER_RULE_CER | ASN1_BER_RULE_DER, +}; +typedef enum tagASN1encodingrule_e ASN1encodingrule_e; + +typedef struct ASN1encoding_s* ASN1encoding_t; +typedef struct ASN1decoding_s* ASN1decoding_t; + +typedef ASN1int32_t (*ASN1BerEncFun_t)(ASN1encoding_t enc, ASN1uint32_t tag, void* data); +typedef ASN1int32_t (*ASN1BerDecFun_t)(ASN1decoding_t enc, ASN1uint32_t tag, void* data); + +struct tagASN1BerFunArr_t +{ + const ASN1BerEncFun_t* apfnEncoder; + const ASN1BerDecFun_t* apfnDecoder; +}; +typedef struct tagASN1BerFunArr_t ASN1BerFunArr_t; + +typedef void (*ASN1GenericFun_t)(void); +typedef void (*ASN1FreeFun_t)(void* data); + +struct tagASN1module_t +{ + ASN1magic_t nModuleName; + ASN1encodingrule_e eRule; + ASN1uint32_t dwFlags; + ASN1uint32_t cPDUs; + const ASN1FreeFun_t* apfnFreeMemory; + const ASN1uint32_t* acbStructSize; + ASN1BerFunArr_t BER; +}; +typedef struct tagASN1module_t* ASN1module_t; + +struct ASN1encoding_s +{ + ASN1magic_t magic; + ASN1uint32_t version; + ASN1module_t module; + ASN1octet_t* buf; + ASN1uint32_t size; + ASN1uint32_t len; + ASN1error_e err; + ASN1uint32_t bit; + ASN1octet_t* pos; + ASN1uint32_t cbExtraHeader; + ASN1encodingrule_e eRule; + ASN1uint32_t dwFlags; +}; + +struct ASN1decoding_s +{ + ASN1magic_t magic; + ASN1uint32_t version; + ASN1module_t module; + ASN1octet_t* buf; + ASN1uint32_t size; + ASN1uint32_t len; + ASN1error_e err; + ASN1uint32_t bit; + ASN1octet_t* pos; + ASN1encodingrule_e eRule; + ASN1uint32_t dwFlags; +}; + +enum +{ + ASN1FLAGS_NONE = 0x00000000L, + ASN1FLAGS_NOASSERT = 0x00001000L, +}; + +enum +{ + ASN1ENCODE_APPEND = 0x00000001L, + ASN1ENCODE_REUSEBUFFER = 0x00000004L, + ASN1ENCODE_SETBUFFER = 0x00000008L, + ASN1ENCODE_ALLOCATEBUFFER = 0x00000010L, + ASN1ENCODE_NOASSERT = ASN1FLAGS_NOASSERT, +}; + +enum +{ + ASN1DECODE_APPENDED = 0x00000001L, + ASN1DECODE_REWINDBUFFER = 0x00000004L, + ASN1DECODE_SETBUFFER = 0x00000008L, + ASN1DECODE_AUTOFREEBUFFER = 0x00000010L, + ASN1DECODE_NOASSERT = ASN1FLAGS_NOASSERT, +}; + +WINPR_API ASN1module_t ASN1_CreateModule(ASN1uint32_t nVersion, ASN1encodingrule_e eRule, + ASN1uint32_t dwFlags, ASN1uint32_t cPDU, const ASN1GenericFun_t apfnEncoder[], + const ASN1GenericFun_t apfnDecoder[], const ASN1FreeFun_t apfnFreeMemory[], + const ASN1uint32_t acbStructSize[], ASN1magic_t nModuleName); + +WINPR_API void ASN1_CloseModule(ASN1module_t pModule); + +WINPR_API ASN1error_e ASN1_CreateEncoder(ASN1module_t pModule, ASN1encoding_t* ppEncoderInfo, + ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize, ASN1encoding_t pParent); + +WINPR_API ASN1error_e ASN1_Encode(ASN1encoding_t pEncoderInfo, void* pDataStruct, ASN1uint32_t nPduNum, + ASN1uint32_t dwFlags, ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize); + +WINPR_API void ASN1_CloseEncoder(ASN1encoding_t pEncoderInfo); + +WINPR_API void ASN1_CloseEncoder2(ASN1encoding_t pEncoderInfo); + +WINPR_API ASN1error_e ASN1_CreateDecoder(ASN1module_t pModule, ASN1decoding_t* ppDecoderInfo, + ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize, ASN1decoding_t pParent); + +WINPR_API ASN1error_e ASN1_Decode(ASN1decoding_t pDecoderInfo, void** ppDataStruct, ASN1uint32_t nPduNum, + ASN1uint32_t dwFlags, ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize); + +WINPR_API void ASN1_CloseDecoder(ASN1decoding_t pDecoderInfo); + +WINPR_API void ASN1_FreeEncoded(ASN1encoding_t pEncoderInfo, void* pBuf); + +WINPR_API void ASN1_FreeDecoded(ASN1decoding_t pDecoderInfo, void* pDataStruct, ASN1uint32_t nPduNum); + +enum tagASN1option_e +{ + ASN1OPT_CHANGE_RULE = 0x101, + ASN1OPT_GET_RULE = 0x201, + ASN1OPT_NOT_REUSE_BUFFER = 0x301, + ASN1OPT_REWIND_BUFFER = 0x302, + ASN1OPT_SET_DECODED_BUFFER = 0x501, + ASN1OPT_DEL_DECODED_BUFFER = 0x502, + ASN1OPT_GET_DECODED_BUFFER_SIZE = 0x601, +}; +typedef enum tagASN1option_e ASN1option_e; + +struct tagASN1optionparam_t +{ + ASN1option_e eOption; + + union + { + ASN1encodingrule_e eRule; + ASN1uint32_t cbRequiredDecodedBufSize; + + struct + { + ASN1octet_t* pbBuf; + ASN1uint32_t cbBufSize; + } Buffer; + }; +}; +typedef struct tagASN1optionparam_t ASN1optionparam_t; +typedef struct tagASN1optionparam_t ASN1optionparam_s; + +WINPR_API ASN1error_e ASN1_SetEncoderOption(ASN1encoding_t pEncoderInfo, ASN1optionparam_t* pOptParam); +WINPR_API ASN1error_e ASN1_GetEncoderOption(ASN1encoding_t pEncoderInfo, ASN1optionparam_t* pOptParam); + +WINPR_API ASN1error_e ASN1_SetDecoderOption(ASN1decoding_t pDecoderInfo, ASN1optionparam_t* pOptParam); +WINPR_API ASN1error_e ASN1_GetDecoderOption(ASN1decoding_t pDecoderInfo, ASN1optionparam_t* pOptParam); + +WINPR_API void ASN1bitstring_free(ASN1bitstring_t* bitstring); +WINPR_API void ASN1octetstring_free(ASN1octetstring_t* octetstring); +WINPR_API void ASN1objectidentifier_free(ASN1objectidentifier_t* objectidentifier); +WINPR_API void ASN1charstring_free(ASN1charstring_t* charstring); +WINPR_API void ASN1char16string_free(ASN1char16string_t* char16string); +WINPR_API void ASN1char32string_free(ASN1char32string_t* char32string); +WINPR_API void ASN1ztcharstring_free(ASN1ztcharstring_t ztcharstring); +WINPR_API void ASN1ztchar16string_free(ASN1ztchar16string_t ztchar16string); +WINPR_API void ASN1ztchar32string_free(ASN1ztchar32string_t ztchar32string); +WINPR_API void ASN1open_free(ASN1open_t* open); +WINPR_API void ASN1utf8string_free(ASN1wstring_t* utf8string); + +WINPR_API LPVOID ASN1DecAlloc(ASN1decoding_t dec, ASN1uint32_t size); +WINPR_API LPVOID ASN1DecRealloc(ASN1decoding_t dec, LPVOID ptr, ASN1uint32_t size); + +WINPR_API void ASN1Free(LPVOID ptr); + +WINPR_API ASN1error_e ASN1EncSetError(ASN1encoding_t enc, ASN1error_e err); +WINPR_API ASN1error_e ASN1DecSetError(ASN1decoding_t dec, ASN1error_e err); + +WINPR_API ASN1uint32_t ASN1intx_uoctets(ASN1intx_t* intx); +WINPR_API void ASN1intx_free(ASN1intx_t* intx); +WINPR_API ASN1int32_t ASN1intx2int32(ASN1intx_t* intx); +WINPR_API ASN1uint32_t ASN1intx2uint32(ASN1intx_t* intx); +WINPR_API int ASN1intxisuint32(ASN1intx_t* intx); +WINPR_API void ASN1intx_setuint32(ASN1intx_t* dst, ASN1uint32_t val); + +WINPR_API ASN1uint32_t ASN1uint32_uoctets(ASN1uint32_t val); + +WINPR_API int ASN1intx_cmp(ASN1intx_t* intx1, ASN1intx_t* intx2); +WINPR_API int ASN1objectidentifier_cmp(ASN1objectidentifier_t* oid1, ASN1objectidentifier_t* oid2); +WINPR_API int ASN1objectidentifier2_cmp(ASN1objectidentifier2_t* oid1, ASN1objectidentifier2_t* oid2); +WINPR_API int ASN1bitstring_cmp(ASN1bitstring_t* str1, ASN1bitstring_t* str2, int length); +WINPR_API int ASN1octetstring_cmp(ASN1octetstring_t* str1, ASN1octetstring_t* str2); +WINPR_API int ASN1charstring_cmp(ASN1charstring_t* str1, ASN1charstring_t* str2); +WINPR_API int ASN1char16string_cmp(ASN1char16string_t* str1, ASN1char16string_t* str2); +WINPR_API int ASN1char32string_cmp(ASN1char32string_t* str1, ASN1char32string_t* str2); +WINPR_API int ASN1ztcharstring_cmp(ASN1ztcharstring_t str1, ASN1ztcharstring_t str2); +WINPR_API int ASN1ztchar16string_cmp(ASN1ztchar16string_t str1, ASN1ztchar16string_t str2); +WINPR_API int ASN1ztchar32string_cmp(ASN1ztchar32string_t str1, ASN1ztchar32string_t str2); +WINPR_API int ASN1open_cmp(ASN1open_t* open1, ASN1open_t* open2); +WINPR_API int ASN1generalizedtime_cmp(ASN1generalizedtime_t* t1, ASN1generalizedtime_t* t2); +WINPR_API int ASN1utctime_cmp(ASN1utctime_t* t1, ASN1utctime_t* t2); + +WINPR_API int ASN1BEREncCharString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1char_t* val); +WINPR_API int ASN1DEREncCharString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1char_t* val); +WINPR_API int ASN1BEREncChar16String(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1char16_t* val); +WINPR_API int ASN1DEREncChar16String(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1char16_t* val); +WINPR_API int ASN1BEREncChar32String(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1char32_t* val); +WINPR_API int ASN1DEREncChar32String(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1char32_t* val); +WINPR_API int ASN1BEREncOctetString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1octet_t* val); +WINPR_API int ASN1DEREncOctetString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1octet_t* val); +WINPR_API int ASN1BEREncBitString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t bitlen, ASN1octet_t* val); +WINPR_API int ASN1DEREncBitString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t bitlen, ASN1octet_t* val); +WINPR_API int ASN1BEREncGeneralizedTime(ASN1encoding_t enc, ASN1uint32_t tag, ASN1generalizedtime_t* val); +WINPR_API int ASN1DEREncGeneralizedTime(ASN1encoding_t enc, ASN1uint32_t tag, ASN1generalizedtime_t* val); +WINPR_API int ASN1BEREncS32(ASN1encoding_t enc, ASN1uint32_t tag, ASN1int32_t val); +WINPR_API int ASN1BEREncSX(ASN1encoding_t enc, ASN1uint32_t tag, ASN1intx_t* val); +WINPR_API int ASN1BEREncZeroMultibyteString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1ztcharstring_t val); +WINPR_API int ASN1DEREncZeroMultibyteString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1ztcharstring_t val); +WINPR_API int ASN1BEREncMultibyteString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1charstring_t* val); +WINPR_API int ASN1DEREncMultibyteString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1charstring_t* val); +WINPR_API int ASN1BEREncNull(ASN1encoding_t enc, ASN1uint32_t tag); +WINPR_API int ASN1BEREncObjectIdentifier(ASN1encoding_t enc, ASN1uint32_t tag, ASN1objectidentifier_t* val); +WINPR_API int ASN1BEREncObjectIdentifier2(ASN1encoding_t enc, ASN1uint32_t tag, ASN1objectidentifier2_t* val); +WINPR_API int ASN1BEREncRemoveZeroBits(ASN1uint32_t* nbits,ASN1octet_t* val); +WINPR_API int ASN1BEREncRemoveZeroBits2(ASN1uint32_t* nbits,ASN1octet_t* val,ASN1uint32_t minlen); +WINPR_API int ASN1BEREncUTCTime(ASN1encoding_t enc, ASN1uint32_t tag, ASN1utctime_t* val); +WINPR_API int ASN1DEREncUTCTime(ASN1encoding_t enc, ASN1uint32_t tag, ASN1utctime_t* val); +WINPR_API int ASN1BEREncFlush(ASN1encoding_t enc); +WINPR_API int ASN1BEREncOpenType(ASN1encoding_t enc, ASN1open_t* val); +WINPR_API int ASN1BERDecExplicitTag(ASN1decoding_t dec, ASN1uint32_t tag, ASN1decoding_t* dd, ASN1octet_t* *ppBufEnd); + +WINPR_API int ASN1BERDecEndOfContents(ASN1decoding_t dec, ASN1decoding_t dd, ASN1octet_t* pBufEnd); +WINPR_API int ASN1BERDecOctetString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1octetstring_t* val); +WINPR_API int ASN1BERDecOctetString2(ASN1decoding_t dec, ASN1uint32_t tag, ASN1octetstring_t* val); +WINPR_API int ASN1BERDecBitString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1bitstring_t* val); +WINPR_API int ASN1BERDecBitString2(ASN1decoding_t dec, ASN1uint32_t tag, ASN1bitstring_t* val); +WINPR_API int ASN1BERDecChar16String(ASN1decoding_t dec, ASN1uint32_t tag, ASN1char16string_t* val); +WINPR_API int ASN1BERDecChar32String(ASN1decoding_t dec, ASN1uint32_t tag, ASN1char32string_t* val); +WINPR_API int ASN1BERDecCharString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1charstring_t* val); +WINPR_API int ASN1BERDecGeneralizedTime(ASN1decoding_t dec, ASN1uint32_t tag, ASN1generalizedtime_t* val); +WINPR_API int ASN1BERDecZeroMultibyteString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1ztcharstring_t* val); +WINPR_API int ASN1BERDecMultibyteString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1charstring_t* val); +WINPR_API int ASN1BERDecNull(ASN1decoding_t dec, ASN1uint32_t tag); +WINPR_API int ASN1BERDecObjectIdentifier(ASN1decoding_t dec, ASN1uint32_t tag, ASN1objectidentifier_t* val); +WINPR_API int ASN1BERDecObjectIdentifier2(ASN1decoding_t dec, ASN1uint32_t tag, ASN1objectidentifier2_t* val); +WINPR_API int ASN1BERDecS8Val(ASN1decoding_t dec, ASN1uint32_t tag, ASN1int8_t* val); +WINPR_API int ASN1BERDecS16Val(ASN1decoding_t dec, ASN1uint32_t tag, ASN1int16_t* val); +WINPR_API int ASN1BERDecS32Val(ASN1decoding_t dec, ASN1uint32_t tag, ASN1int32_t* val); +WINPR_API int ASN1BERDecSXVal(ASN1decoding_t dec, ASN1uint32_t tag, ASN1intx_t* val); +WINPR_API int ASN1BERDecU8Val(ASN1decoding_t dec, ASN1uint32_t tag, ASN1uint8_t* val); +WINPR_API int ASN1BERDecU16Val(ASN1decoding_t dec, ASN1uint32_t tag, ASN1uint16_t* val); +WINPR_API int ASN1BERDecU32Val(ASN1decoding_t dec, ASN1uint32_t tag, ASN1uint32_t* val); +WINPR_API int ASN1BERDecUTCTime(ASN1decoding_t dec, ASN1uint32_t tag, ASN1utctime_t* val); +WINPR_API int ASN1BERDecZeroCharString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1ztcharstring_t* val); +WINPR_API int ASN1BERDecZeroChar16String(ASN1decoding_t dec, ASN1uint32_t tag, ASN1ztchar16string_t* val); +WINPR_API int ASN1BERDecZeroChar32String(ASN1decoding_t dec, ASN1uint32_t tag, ASN1ztchar32string_t* val); +WINPR_API int ASN1BERDecSkip(ASN1decoding_t dec); +WINPR_API int ASN1BERDecFlush(ASN1decoding_t dec); +WINPR_API int ASN1BERDecOpenType(ASN1decoding_t dec, ASN1open_t* val); +WINPR_API int ASN1BERDecOpenType2(ASN1decoding_t dec, ASN1open_t* val); + +WINPR_API int ASN1BEREncCheck(ASN1encoding_t enc, ASN1uint32_t noctets); +WINPR_API int ASN1BEREncTag(ASN1encoding_t enc, ASN1uint32_t tag); +WINPR_API int ASN1BEREncExplicitTag(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t* pnLenOff); +WINPR_API int ASN1BEREncEndOfContents(ASN1encoding_t enc, ASN1uint32_t nLenOff); +WINPR_API int ASN1BEREncLength(ASN1encoding_t enc, ASN1uint32_t len); + +WINPR_API int ASN1BERDecCheck(ASN1decoding_t dec, ASN1uint32_t len); +WINPR_API int ASN1BERDecTag(ASN1decoding_t dec, ASN1uint32_t tag, ASN1uint32_t* constructed); +WINPR_API int ASN1BERDecLength(ASN1decoding_t dec, ASN1uint32_t* len, ASN1uint32_t* infinite); +WINPR_API int ASN1BERDecNotEndOfContents(ASN1decoding_t dec, ASN1octet_t* pBufEnd); +WINPR_API int ASN1BERDecPeekTag(ASN1decoding_t dec, ASN1uint32_t* tag); + +WINPR_API int ASN1BEREncU32(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t val); +WINPR_API int ASN1BEREncBool(ASN1encoding_t enc, ASN1uint32_t tag, ASN1bool_t val); +WINPR_API int ASN1BERDecBool(ASN1decoding_t dec, ASN1uint32_t tag, ASN1bool_t* val); +WINPR_API int ASN1BEREncEoid(ASN1encoding_t enc, ASN1uint32_t tag, ASN1encodedOID_t* val); +WINPR_API int ASN1BERDecEoid(ASN1decoding_t dec, ASN1uint32_t tag, ASN1encodedOID_t* val); +WINPR_API int ASN1BERDotVal2Eoid(ASN1encoding_t enc, char* pszDotVal, ASN1encodedOID_t* pOut); +WINPR_API int ASN1BEREoid2DotVal(ASN1decoding_t dec, ASN1encodedOID_t* pIn, char** ppszDotVal); +WINPR_API void ASN1BEREoid_free(ASN1encodedOID_t* val); +WINPR_API int ASN1BEREncUTF8String(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t length, WCHAR* value); +WINPR_API int ASN1DEREncUTF8String(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t length, WCHAR* value); +WINPR_API int ASN1BERDecUTF8String(ASN1decoding_t dec, ASN1uint32_t tag, ASN1wstring_t* val); +WINPR_API int ASN1DEREncBeginBlk(ASN1encoding_t enc, ASN1blocktype_e eBlkType, void** ppBlk); +WINPR_API int ASN1DEREncNewBlkElement(void* pBlk, ASN1encoding_t* enc2); +WINPR_API int ASN1DEREncFlushBlkElement(void* pBlk); +WINPR_API int ASN1DEREncEndBlk(void* pBlk); + +#endif /* WINPR_ASN1_H */ + diff --git a/include/winpr/bcrypt.h b/winpr/include/winpr/bcrypt.h similarity index 100% rename from include/winpr/bcrypt.h rename to winpr/include/winpr/bcrypt.h diff --git a/winpr/include/winpr/config.h.in b/winpr/include/winpr/config.h.in new file mode 100644 index 000000000..5cd3bc731 --- /dev/null +++ b/winpr/include/winpr/config.h.in @@ -0,0 +1,32 @@ +/** + * WinPR: Windows Portable Runtime + * config.h definitions for installable headers + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_CONFIG_H +#define WINPR_CONFIG_H + +/* + * This generated config.h header is meant for installation, which is why + * all definitions MUST be prefixed to avoid conflicting with third-party + * libraries. Only add configurable definitions which really must be used + * from installable headers, such as the base type definition types. + */ + +#cmakedefine WITH_NATIVE_SSPI + +#endif /* WINPR_CONFIG_H */ diff --git a/include/winpr/crt.h b/winpr/include/winpr/crt.h similarity index 97% rename from include/winpr/crt.h rename to winpr/include/winpr/crt.h index 6bc32dd6c..21abb332a 100644 --- a/include/winpr/crt.h +++ b/winpr/include/winpr/crt.h @@ -22,6 +22,7 @@ #include #include +#include #include diff --git a/include/winpr/dsparse.h b/winpr/include/winpr/dsparse.h similarity index 100% rename from include/winpr/dsparse.h rename to winpr/include/winpr/dsparse.h diff --git a/include/winpr/handle.h b/winpr/include/winpr/handle.h similarity index 100% rename from include/winpr/handle.h rename to winpr/include/winpr/handle.h diff --git a/include/winpr/heap.h b/winpr/include/winpr/heap.h similarity index 100% rename from include/winpr/heap.h rename to winpr/include/winpr/heap.h diff --git a/winpr/include/winpr/library.h b/winpr/include/winpr/library.h new file mode 100644 index 000000000..124086b87 --- /dev/null +++ b/winpr/include/winpr/library.h @@ -0,0 +1,49 @@ +/** + * WinPR: Windows Portable Runtime + * Library Loader + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_LIBRARY_H +#define WINPR_LIBRARY_H + +#include +#include + +#ifndef _WIN32 + +WINPR_API HMODULE LoadLibraryA(LPCSTR lpLibFileName); +WINPR_API HMODULE LoadLibraryW(LPCWSTR lpLibFileName); + +WINPR_API HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); +WINPR_API HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); + +#ifdef UNICODE +#define LoadLibrary LoadLibraryW +#define LoadLibraryEx LoadLibraryExW +#else +#define LoadLibrary LoadLibraryA +#define LoadLibraryEx LoadLibraryExA +#endif + +WINPR_API FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName); + +WINPR_API BOOL FreeLibrary(HMODULE hLibModule); + +#endif + +#endif /* WINPR_LIBRARY_H */ + diff --git a/include/winpr/memory.h b/winpr/include/winpr/memory.h similarity index 100% rename from include/winpr/memory.h rename to winpr/include/winpr/memory.h diff --git a/include/winpr/midl.h b/winpr/include/winpr/midl.h similarity index 100% rename from include/winpr/midl.h rename to winpr/include/winpr/midl.h diff --git a/include/winpr/ndr.h b/winpr/include/winpr/ndr.h similarity index 100% rename from include/winpr/ndr.h rename to winpr/include/winpr/ndr.h diff --git a/include/winpr/ntlm.h b/winpr/include/winpr/ntlm.h similarity index 74% rename from include/winpr/ntlm.h rename to winpr/include/winpr/ntlm.h index 6e8759ceb..d6514f92a 100644 --- a/include/winpr/ntlm.h +++ b/winpr/include/winpr/ntlm.h @@ -34,12 +34,19 @@ WINPR_API BYTE* NTOWFv2W(LPWSTR Password, UINT32 PasswordLength, LPWSTR User, WINPR_API BYTE* NTOWFv2A(LPSTR Password, UINT32 PasswordLength, LPSTR User, UINT32 UserLength, LPSTR Domain, UINT32 DomainLength, BYTE* NtHash); +WINPR_API BYTE* NTOWFv2FromHashW(BYTE* NtHashV1, LPWSTR User, UINT32 UserLength, + LPWSTR Domain, UINT32 DomainLength, BYTE* NtHash); +WINPR_API BYTE* NTOWFv2FromHashA(BYTE* NtHashV1, LPSTR User, UINT32 UserLength, + LPSTR Domain, UINT32 DomainLength, BYTE* NtHash); + #ifdef UNICODE -#define NTOWFv1 NTOWFv1W -#define NTOWFv2 NTOWFv2W +#define NTOWFv1 NTOWFv1W +#define NTOWFv2 NTOWFv2W +#define NTOWFv2FromHash NTOWFv2FromHashW #else -#define NTOWFv1 NTOWFv1A -#define NTOWFv2 NTOWFv2W +#define NTOWFv1 NTOWFv1A +#define NTOWFv2 NTOWFv2A +#define NTOWFv2FromHash NTOWFv2FromHashA #endif #endif /* WINPR_UTILS_NTLM_H */ diff --git a/include/winpr/print.h b/winpr/include/winpr/print.h similarity index 100% rename from include/winpr/print.h rename to winpr/include/winpr/print.h diff --git a/include/winpr/registry.h b/winpr/include/winpr/registry.h similarity index 99% rename from include/winpr/registry.h rename to winpr/include/winpr/registry.h index 7facef76a..68aebd0fc 100644 --- a/include/winpr/registry.h +++ b/winpr/include/winpr/registry.h @@ -35,6 +35,10 @@ #define ERROR_SUCCESS 0 #endif +#ifndef ERROR_FILE_NOT_FOUND +#define ERROR_FILE_NOT_FOUND 2 +#endif + #define DELETE 0x00010000 #define READ_CONTROL 0x00020000 #define WRITE_DAC 0x00040000 diff --git a/include/winpr/rpc.h b/winpr/include/winpr/rpc.h similarity index 100% rename from include/winpr/rpc.h rename to winpr/include/winpr/rpc.h diff --git a/include/winpr/sam.h b/winpr/include/winpr/sam.h similarity index 100% rename from include/winpr/sam.h rename to winpr/include/winpr/sam.h diff --git a/include/winpr/security.h b/winpr/include/winpr/security.h similarity index 100% rename from include/winpr/security.h rename to winpr/include/winpr/security.h diff --git a/include/winpr/sspi.h b/winpr/include/winpr/sspi.h similarity index 99% rename from include/winpr/sspi.h rename to winpr/include/winpr/sspi.h index e0881e566..0c4bd9fb2 100644 --- a/include/winpr/sspi.h +++ b/winpr/include/winpr/sspi.h @@ -20,7 +20,7 @@ #ifndef WINPR_SSPI_H #define WINPR_SSPI_H -#include "config.h" +#include #include #include @@ -883,14 +883,19 @@ struct _SecurityFunctionTableW typedef struct _SecurityFunctionTableW SecurityFunctionTableW; typedef SecurityFunctionTableW* PSecurityFunctionTableW; +typedef PSecurityFunctionTableA (SEC_ENTRY * INIT_SECURITY_INTERFACE_A)(void); +typedef PSecurityFunctionTableW (SEC_ENTRY * INIT_SECURITY_INTERFACE_W)(void); + #ifdef UNICODE #define InitSecurityInterface InitSecurityInterfaceW #define SecurityFunctionTable SecurityFunctionTableW #define PSecurityFunctionTable PSecurityFunctionTableW +#define INIT_SECURITY_INTERFACE INIT_SECURITY_INTERFACE_W #else #define InitSecurityInterface InitSecurityInterfaceA #define SecurityFunctionTable SecurityFunctionTableA #define PSecurityFunctionTable PSecurityFunctionTableA +#define INIT_SECURITY_INTERFACE INIT_SECURITY_INTERFACE_A #endif /* Package Management */ diff --git a/include/winpr/sspicli.h b/winpr/include/winpr/sspicli.h similarity index 100% rename from include/winpr/sspicli.h rename to winpr/include/winpr/sspicli.h diff --git a/include/winpr/stream.h b/winpr/include/winpr/stream.h similarity index 100% rename from include/winpr/stream.h rename to winpr/include/winpr/stream.h diff --git a/include/winpr/string.h b/winpr/include/winpr/string.h similarity index 96% rename from include/winpr/string.h rename to winpr/include/winpr/string.h index 8dc0ae721..eb311908e 100644 --- a/include/winpr/string.h +++ b/winpr/include/winpr/string.h @@ -47,6 +47,10 @@ WINPR_API char* _strdup(const char* strSource); WINPR_API WCHAR* _wcsdup(const WCHAR* strSource); +WINPR_API int _stricmp(const char* string1, const char* string2); + +WINPR_API char* strtok_s(char* strToken, const char* strDelimit, char** context); + WINPR_API LPSTR CharUpperA(LPSTR lpsz); WINPR_API LPWSTR CharUpperW(LPWSTR lpsz); diff --git a/include/winpr/synch.h b/winpr/include/winpr/synch.h similarity index 100% rename from include/winpr/synch.h rename to winpr/include/winpr/synch.h diff --git a/include/winpr/sysinfo.h b/winpr/include/winpr/sysinfo.h similarity index 100% rename from include/winpr/sysinfo.h rename to winpr/include/winpr/sysinfo.h diff --git a/include/winpr/tchar.h b/winpr/include/winpr/tchar.h similarity index 100% rename from include/winpr/tchar.h rename to winpr/include/winpr/tchar.h diff --git a/include/winpr/windows.h b/winpr/include/winpr/windows.h similarity index 100% rename from include/winpr/windows.h rename to winpr/include/winpr/windows.h diff --git a/include/winpr/winpr.h b/winpr/include/winpr/winpr.h similarity index 98% rename from include/winpr/winpr.h rename to winpr/include/winpr/winpr.h index 479b19b6e..28dc8f465 100644 --- a/include/winpr/winpr.h +++ b/winpr/include/winpr/winpr.h @@ -19,8 +19,6 @@ #ifndef WINPR_H #define WINPR_H -#include "config.h" - #if defined _WIN32 || defined __CYGWIN__ #ifdef WINPR_EXPORTS #ifdef __GNUC__ diff --git a/include/winpr/wtypes.h b/winpr/include/winpr/wtypes.h similarity index 99% rename from include/winpr/wtypes.h rename to winpr/include/winpr/wtypes.h index f84710fb9..d7cdba3ac 100644 --- a/include/winpr/wtypes.h +++ b/winpr/include/winpr/wtypes.h @@ -208,6 +208,9 @@ typedef struct _SECURITY_ATTRIBUTES BOOL bInheritHandle; } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; +typedef void* HMODULE; +typedef void* FARPROC; + #endif typedef BYTE byte; diff --git a/winpr/libwinpr/CMakeLists.txt b/winpr/libwinpr/CMakeLists.txt new file mode 100644 index 000000000..c3b03afa2 --- /dev/null +++ b/winpr/libwinpr/CMakeLists.txt @@ -0,0 +1,65 @@ +# WinPR: Windows Portable Runtime +# winpr cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if (APPLE) + # flat_namespace should be avoided, but is required for -undefined warning. Since WinPR currently has + # a lot of undefined symbols in use, use this hack until they're filled out. + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-flat_namespace,-undefined,warning") +endif() + +if(WITH_MONOLITHIC_BUILD) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() + +add_subdirectory(crt) +add_subdirectory(utils) +add_subdirectory(heap) +add_subdirectory(handle) +add_subdirectory(synch) +add_subdirectory(sysinfo) +add_subdirectory(bcrypt) +add_subdirectory(dsparse) +add_subdirectory(asn1) +add_subdirectory(rpc) +add_subdirectory(sspicli) +add_subdirectory(sspi) +add_subdirectory(registry) +add_subdirectory(library) + +if(WITH_MONOLITHIC_BUILD) + add_library(winpr + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $) + + set_target_properties(winpr PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + + target_link_libraries(winpr ${WINPR_LIBS}) + install(TARGETS winpr DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + diff --git a/winpr/asn1/CMakeLists.txt b/winpr/libwinpr/asn1/CMakeLists.txt similarity index 79% rename from winpr/asn1/CMakeLists.txt rename to winpr/libwinpr/asn1/CMakeLists.txt index 09822861e..94eb5ea97 100644 --- a/winpr/asn1/CMakeLists.txt +++ b/winpr/libwinpr/asn1/CMakeLists.txt @@ -20,9 +20,16 @@ set(WINPR_ASN1_SRCS asn1.c) -add_library(winpr-asn1 ${WINPR_ASN1_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-asn1 OBJECT ${WINPR_ASN1_SRCS}) +else() + add_library(winpr-asn1 ${WINPR_ASN1_SRCS}) +endif() set_target_properties(winpr-asn1 PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -install(TARGETS winpr-asn1 DESTINATION ${CMAKE_INSTALL_LIBDIR}) - +if(WITH_MONOLITHIC_BUILD) + +else() + install(TARGETS winpr-asn1 DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/libwinpr/asn1/asn1.c b/winpr/libwinpr/asn1/asn1.c new file mode 100644 index 000000000..ee11192f3 --- /dev/null +++ b/winpr/libwinpr/asn1/asn1.c @@ -0,0 +1,316 @@ +/** + * WinPR: Windows Portable Runtime + * ASN.1 Encoding & Decoding Engine + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#ifndef _WIN32 + +ASN1module_t ASN1_CreateModule(ASN1uint32_t nVersion, ASN1encodingrule_e eRule, + ASN1uint32_t dwFlags, ASN1uint32_t cPDU, const ASN1GenericFun_t apfnEncoder[], + const ASN1GenericFun_t apfnDecoder[], const ASN1FreeFun_t apfnFreeMemory[], + const ASN1uint32_t acbStructSize[], ASN1magic_t nModuleName) +{ + ASN1module_t module = NULL; + + if (!((apfnEncoder) && (apfnDecoder) && (apfnFreeMemory) && (acbStructSize))) + return NULL; + + module = (ASN1module_t) malloc(sizeof(struct tagASN1module_t)); + ZeroMemory(module, sizeof(struct tagASN1module_t)); + + if (module) + { + module->nModuleName = nModuleName; + module->dwFlags = dwFlags; + module->eRule = eRule; + module->cPDUs = cPDU; + module->apfnFreeMemory = apfnFreeMemory; + module->acbStructSize = acbStructSize; + + if (eRule & ASN1_BER_RULE) + { + module->BER.apfnEncoder = (const ASN1BerEncFun_t*) apfnEncoder; + module->BER.apfnDecoder = (const ASN1BerDecFun_t*) apfnDecoder; + } + } + + return module; +} + +void ASN1_CloseModule(ASN1module_t pModule) +{ + if (!pModule) + free(pModule); +} + +ASN1error_e ASN1_CreateEncoder(ASN1module_t pModule, ASN1encoding_t* ppEncoderInfo, + ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize, ASN1encoding_t pParent) +{ + ASN1error_e status; + ASN1encoding_t encoder; + ASN1encodingrule_e rule; + + if (pModule && ppEncoderInfo) + { + *ppEncoderInfo = 0; + encoder = (ASN1encoding_t) malloc(sizeof(struct ASN1encoding_s)); + + if (encoder) + { + ZeroMemory(encoder, sizeof(struct ASN1encoding_s)); + encoder->magic = 0x44434E45; + encoder->err = 0; + encoder->dwFlags = pModule->dwFlags; + encoder->module = pModule; + + if (pbBuf && cbBufSize) + { + encoder->dwFlags |= ASN1ENCODE_SETBUFFER; + encoder->buf = pbBuf; + encoder->pos = pbBuf; + encoder->size = cbBufSize; + } + + if (pParent) + { + encoder[1].magic = (ASN1magic_t) pParent; + rule = pParent->eRule; + } + else + { + encoder[1].magic = (ASN1magic_t) encoder; + rule = pModule->eRule; + } + + encoder->eRule = rule; + + if (encoder->dwFlags & ASN1ENCODE_SETBUFFER) + goto LABEL_SET_BUFFER; + + if (!pParent) + { +LABEL_ENCODER_COMPLETE: + *ppEncoderInfo = encoder; + return 0; + } + + if (rule & ASN1_BER_RULE) + { + //if (ASN1BEREncCheck(encoder, 1)) + { + *encoder->buf = 0; +LABEL_SET_BUFFER: + if (pParent) + pParent[1].version = (ASN1uint32_t) encoder; + + goto LABEL_ENCODER_COMPLETE; + } + + status = ASN1_ERR_MEMORY; + } + else + { + status = ASN1_ERR_RULE; + } + + free(encoder); + } + else + { + status = ASN1_ERR_MEMORY; + } + } + else + { + status = ASN1_ERR_BADARGS; + } + + return status; +} + +ASN1error_e ASN1_Encode(ASN1encoding_t pEncoderInfo, void* pDataStruct, ASN1uint32_t nPduNum, + ASN1uint32_t dwFlags, ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize) +{ + int flags; + ASN1error_e status; + ASN1module_t module; + ASN1BerEncFun_t pfnEncoder; + + if (!pEncoderInfo) + return ASN1_ERR_BADARGS; + + ASN1EncSetError(pEncoderInfo, ASN1_SUCCESS); + + if (dwFlags & 8) + { + pEncoderInfo->dwFlags |= 8; + pEncoderInfo->buf = pbBuf; + pEncoderInfo->pos = pbBuf; + pEncoderInfo->size = cbBufSize; + } + else + { + flags = dwFlags | pEncoderInfo->dwFlags; + + if (flags & 0x10) + { + pEncoderInfo->dwFlags &= 0xFFFFFFF7; + pEncoderInfo->buf = 0; + pEncoderInfo->pos = 0; + pEncoderInfo->size = 0; + } + else + { + if (!(dwFlags & ASN1ENCODE_REUSEBUFFER) && (flags & ASN1ENCODE_APPEND)) + goto LABEL_MODULE; + + pEncoderInfo->pos = pEncoderInfo->buf; + } + } + + pEncoderInfo->len = 0; + pEncoderInfo->bit = 0; + +LABEL_MODULE: + module = pEncoderInfo->module; + + if (nPduNum >= module->cPDUs) + goto LABEL_BAD_PDU; + + if (!(pEncoderInfo->eRule & ASN1_BER_RULE)) + { + status = ASN1_ERR_RULE; + return ASN1EncSetError(pEncoderInfo, status); + } + + pfnEncoder = module->BER.apfnEncoder[nPduNum]; + + if (!pfnEncoder) + { +LABEL_BAD_PDU: + status = ASN1_ERR_BADPDU; + return ASN1EncSetError(pEncoderInfo, status); + } + + if (pfnEncoder(pEncoderInfo, 0, pDataStruct)) + { + //ASN1BEREncFlush(pEncoderInfo); + } + else + { + if (pEncoderInfo[1].err >= 0) + ASN1EncSetError(pEncoderInfo, ASN1_ERR_CORRUPT); + } + + if (pEncoderInfo[1].err < 0) + { + if (((dwFlags & 0xFF) | (pEncoderInfo->dwFlags & 0xFF)) & 0x10) + { + ASN1_FreeEncoded(pEncoderInfo, pEncoderInfo->buf); + pEncoderInfo->buf = 0; + pEncoderInfo->pos = 0; + pEncoderInfo->bit = 0; + pEncoderInfo->len = 0; + pEncoderInfo->size = 0; + } + } + + return pEncoderInfo[1].err; +} + +void ASN1_CloseEncoder(ASN1encoding_t pEncoderInfo) +{ + ASN1magic_t magic; + + if (pEncoderInfo) + { + magic = pEncoderInfo[1].magic; + + if (pEncoderInfo != (ASN1encoding_t) magic) + pEncoderInfo[1].version = 0; + + free(pEncoderInfo); + } +} + +ASN1error_e ASN1EncSetError(ASN1encoding_t enc, ASN1error_e err) +{ + ASN1error_e status; + ASN1encoding_t encoder; + ASN1encoding_t nextEncoder; + + status = err; + encoder = enc; + + while (encoder) + { + nextEncoder = (ASN1encoding_t) &encoder[1]; + + encoder->err = err; + + if (encoder == nextEncoder) + break; + + encoder = nextEncoder; + } + + return status; +} + +ASN1error_e ASN1DecSetError(ASN1decoding_t dec, ASN1error_e err) +{ + ASN1error_e status; + ASN1decoding_t decoder; + ASN1decoding_t nextDecoder; + + status = err; + decoder = dec; + + while (decoder) + { + nextDecoder = (ASN1decoding_t) &decoder[1]; + + decoder->err = err; + + if (decoder == nextDecoder) + break; + + decoder = nextDecoder; + } + + return status; +} + +void ASN1_FreeEncoded(ASN1encoding_t pEncoderInfo, void* pBuf) +{ + return; +} + +void ASN1_FreeDecoded(ASN1decoding_t pDecoderInfo, void* pDataStruct, ASN1uint32_t nPduNum) +{ + return; +} + +#endif diff --git a/winpr/bcrypt/CMakeLists.txt b/winpr/libwinpr/bcrypt/CMakeLists.txt similarity index 65% rename from winpr/bcrypt/CMakeLists.txt rename to winpr/libwinpr/bcrypt/CMakeLists.txt index 4f9db8e7d..1b2b8a086 100644 --- a/winpr/bcrypt/CMakeLists.txt +++ b/winpr/libwinpr/bcrypt/CMakeLists.txt @@ -20,19 +20,29 @@ set(WINPR_BCRYPT_SRCS bcrypt.c) -add_library(winpr-bcrypt ${WINPR_BCRYPT_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-bcrypt OBJECT ${WINPR_BCRYPT_SRCS}) +else() + add_library(winpr-bcrypt ${WINPR_BCRYPT_SRCS}) +endif() include_directories(${OPENSSL_INCLUDE_DIR}) include_directories(${ZLIB_INCLUDE_DIRS}) set_target_properties(winpr-bcrypt PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -if (NOT WIN32) - target_link_libraries(winpr-bcrypt winpr-crt) +set(WINPR_BCRYPT_LIBS + ${ZLIB_LIBRARIES}) + +if(WITH_MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${WINPR_BCRYPT_LIBS} PARENT_SCOPE) +else() + if(NOT WIN32) + set(WINPR_BCRYPT_LIBS ${WINPR_BCRYPT_LIBS} winpr-crt) + endif() + + set(WINPR_BCRYPT_LIBS ${WINPR_BCRYPT_LIBS} winpr-utils) + + target_link_libraries(winpr-bcrypt ${WINPR_BCRYPT_LIBS}) + install(TARGETS winpr-bcrypt DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() - -target_link_libraries(winpr-bcrypt winpr-utils) -target_link_libraries(winpr-bcrypt ${ZLIB_LIBRARIES}) - -install(TARGETS winpr-bcrypt DESTINATION ${CMAKE_INSTALL_LIBDIR}) - diff --git a/winpr/bcrypt/bcrypt.c b/winpr/libwinpr/bcrypt/bcrypt.c similarity index 98% rename from winpr/bcrypt/bcrypt.c rename to winpr/libwinpr/bcrypt/bcrypt.c index 08b9e205f..63840e850 100644 --- a/winpr/bcrypt/bcrypt.c +++ b/winpr/libwinpr/bcrypt/bcrypt.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include /** diff --git a/winpr/crt/CMakeLists.txt b/winpr/libwinpr/crt/CMakeLists.txt similarity index 79% rename from winpr/crt/CMakeLists.txt rename to winpr/libwinpr/crt/CMakeLists.txt index a4a35ac37..7dfb7f90c 100644 --- a/winpr/crt/CMakeLists.txt +++ b/winpr/libwinpr/crt/CMakeLists.txt @@ -21,9 +21,16 @@ set(WINPR_CRT_SRCS memory.c string.c) -add_library(winpr-crt ${WINPR_CRT_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-crt OBJECT ${WINPR_CRT_SRCS}) +else() + add_library(winpr-crt ${WINPR_CRT_SRCS}) +endif() set_target_properties(winpr-crt PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -install(TARGETS winpr-crt DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) +else() + install(TARGETS winpr-crt DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/crt/memory.c b/winpr/libwinpr/crt/memory.c similarity index 94% rename from winpr/crt/memory.c rename to winpr/libwinpr/crt/memory.c index 0f9b16f39..39ac0dbe3 100644 --- a/winpr/crt/memory.c +++ b/winpr/libwinpr/crt/memory.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include /* Memory Allocation: http://msdn.microsoft.com/en-us/library/hk1k7x6x.aspx */ diff --git a/winpr/crt/string.c b/winpr/libwinpr/crt/string.c similarity index 97% rename from winpr/crt/string.c rename to winpr/libwinpr/crt/string.c index 920b58639..307cede6a 100644 --- a/winpr/crt/string.c +++ b/winpr/libwinpr/crt/string.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -65,6 +69,16 @@ WCHAR* _wcsdup(const WCHAR* strSource) return strDestination; } +int _stricmp(const char* string1, const char* string2) +{ + return strcasecmp(string1, string2); +} + +char* strtok_s(char* strToken, const char* strDelimit, char** context) +{ + return strtok_r(strToken, strDelimit, context); +} + /* Windows API Sets - api-ms-win-core-string-l2-1-0.dll * http://msdn.microsoft.com/en-us/library/hh802935/ */ diff --git a/winpr/dsparse/CMakeLists.txt b/winpr/libwinpr/dsparse/CMakeLists.txt similarity index 78% rename from winpr/dsparse/CMakeLists.txt rename to winpr/libwinpr/dsparse/CMakeLists.txt index 9d4e188d1..b3420b341 100644 --- a/winpr/dsparse/CMakeLists.txt +++ b/winpr/libwinpr/dsparse/CMakeLists.txt @@ -20,9 +20,16 @@ set(WINPR_DSPARSE_SRCS dsparse.c) -add_library(winpr-dsparse ${WINPR_DSPARSE_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-dsparse OBJECT ${WINPR_DSPARSE_SRCS}) +else() + add_library(winpr-dsparse ${WINPR_DSPARSE_SRCS}) +endif() set_target_properties(winpr-dsparse PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -install(TARGETS winpr-dsparse DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) +else() + install(TARGETS winpr-dsparse DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/dsparse/dsparse.c b/winpr/libwinpr/dsparse/dsparse.c similarity index 97% rename from winpr/dsparse/dsparse.c rename to winpr/libwinpr/dsparse/dsparse.c index cf4e04926..45ff7ed90 100644 --- a/winpr/dsparse/dsparse.c +++ b/winpr/libwinpr/dsparse/dsparse.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include /** diff --git a/winpr/handle/CMakeLists.txt b/winpr/libwinpr/handle/CMakeLists.txt similarity index 78% rename from winpr/handle/CMakeLists.txt rename to winpr/libwinpr/handle/CMakeLists.txt index 16edeb710..228e846ac 100644 --- a/winpr/handle/CMakeLists.txt +++ b/winpr/libwinpr/handle/CMakeLists.txt @@ -20,9 +20,16 @@ set(WINPR_HANDLE_SRCS handle.c) -add_library(winpr-handle ${WINPR_HANDLE_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-handle OBJECT ${WINPR_HANDLE_SRCS}) +else() + add_library(winpr-handle ${WINPR_HANDLE_SRCS}) +endif() set_target_properties(winpr-handle PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -install(TARGETS winpr-handle DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) +else() + install(TARGETS winpr-handle DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/handle/handle.c b/winpr/libwinpr/handle/handle.c similarity index 96% rename from winpr/handle/handle.c rename to winpr/libwinpr/handle/handle.c index 23ac25566..6f9f9c742 100644 --- a/winpr/handle/handle.c +++ b/winpr/libwinpr/handle/handle.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #ifndef _WIN32 diff --git a/winpr/heap/CMakeLists.txt b/winpr/libwinpr/heap/CMakeLists.txt similarity index 79% rename from winpr/heap/CMakeLists.txt rename to winpr/libwinpr/heap/CMakeLists.txt index 4f708b521..3ee0bb22f 100644 --- a/winpr/heap/CMakeLists.txt +++ b/winpr/libwinpr/heap/CMakeLists.txt @@ -20,9 +20,16 @@ set(WINPR_HEAP_SRCS heap.c) -add_library(winpr-heap ${WINPR_HEAP_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-heap OBJECT ${WINPR_HEAP_SRCS}) +else() + add_library(winpr-heap ${WINPR_HEAP_SRCS}) +endif() set_target_properties(winpr-heap PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -install(TARGETS winpr-heap DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) +else() + install(TARGETS winpr-heap DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/heap/heap.c b/winpr/libwinpr/heap/heap.c similarity index 96% rename from winpr/heap/heap.c rename to winpr/libwinpr/heap/heap.c index cb859e056..5de8cba21 100644 --- a/winpr/heap/heap.c +++ b/winpr/libwinpr/heap/heap.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include /* Memory Allocation: http://msdn.microsoft.com/en-us/library/hk1k7x6x.aspx */ diff --git a/winpr/synch/CMakeLists.txt b/winpr/libwinpr/library/CMakeLists.txt similarity index 63% rename from winpr/synch/CMakeLists.txt rename to winpr/libwinpr/library/CMakeLists.txt index ddbca8c96..1f7808273 100644 --- a/winpr/synch/CMakeLists.txt +++ b/winpr/libwinpr/library/CMakeLists.txt @@ -1,5 +1,5 @@ # WinPR: Windows Portable Runtime -# libwinpr-synch cmake build script +# libwinpr-library cmake build script # # Copyright 2011 O.S. Systems Software Ltda. # Copyright 2011 Otavio Salvador @@ -17,20 +17,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(WINPR_SYNCH_SRCS - critical.c - event.c - mutex.c - semaphore.c - sleep.c) +set(WINPR_LIBRARY_SRCS + library.c) -add_library(winpr-synch ${WINPR_SYNCH_SRCS}) - -set_target_properties(winpr-synch PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") - -if(NOT WIN32) - target_link_libraries(winpr-synch winpr-handle) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-library OBJECT ${WINPR_LIBRARY_SRCS}) +else() + add_library(winpr-library ${WINPR_LIBRARY_SRCS}) endif() -install(TARGETS winpr-synch DESTINATION ${CMAKE_INSTALL_LIBDIR}) +set_target_properties(winpr-library PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") +if(WITH_MONOLITHIC_BUILD) + +else() + install(TARGETS winpr-library DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/libwinpr/library/library.c b/winpr/libwinpr/library/library.c new file mode 100644 index 000000000..9688076cc --- /dev/null +++ b/winpr/libwinpr/library/library.c @@ -0,0 +1,138 @@ +/** + * WinPR: Windows Portable Runtime + * Library Loader + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +/** + * api-ms-win-core-libraryloader-l1-1-1.dll: + * + * AddDllDirectory + * DisableThreadLibraryCalls + * EnumResourceLanguagesExA + * EnumResourceLanguagesExW + * EnumResourceNamesExA + * EnumResourceNamesExW + * EnumResourceTypesExA + * EnumResourceTypesExW + * FindResourceExW + * FindStringOrdinal + * FreeLibrary + * FreeLibraryAndExitThread + * FreeResource + * GetModuleFileNameA + * GetModuleFileNameW + * GetModuleHandleA + * GetModuleHandleExA + * GetModuleHandleExW + * GetModuleHandleW + * GetProcAddress + * LoadLibraryExA + * LoadLibraryExW + * LoadResource + * LoadStringA + * LoadStringW + * LockResource + * QueryOptionalDelayLoadedAPI + * RemoveDllDirectory + * SetDefaultDllDirectories + * SizeofResource + */ + +#ifndef _WIN32 + +#include +#include +#include + +HMODULE LoadLibraryA(LPCSTR lpLibFileName) +{ + HMODULE library; + + library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY); + + if (library == NULL) + { + printf("LoadLibraryA: failed to open %s: %s\n", lpLibFileName, dlerror()); + return NULL; + } + + return library; +} + +HMODULE LoadLibraryW(LPCWSTR lpLibFileName) +{ + return (HMODULE) NULL; +} + +HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +{ + HMODULE library; + + library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY); + + if (library == NULL) + { + printf("LoadLibraryA: failed to open %s: %s\n", lpLibFileName, dlerror()); + return NULL; + } + + return library; +} + +HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +{ + return (HMODULE) NULL; +} + +FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName) +{ + FARPROC proc; + + proc = dlsym(hModule, lpProcName); + + if (proc == NULL) + { + printf("GetProcAddress: could not find procedure %s: %s\n", lpProcName, dlerror()); + return (FARPROC) NULL; + } + + return proc; +} + +BOOL FreeLibrary(HMODULE hLibModule) +{ + int status; + + status = dlclose(hLibModule); + + if (status == 0) + { + printf("FreeLibrary() failure: %s\n", dlerror()); + return FALSE; + } + + return TRUE; +} + +#endif + diff --git a/winpr/registry/CMakeLists.txt b/winpr/libwinpr/registry/CMakeLists.txt similarity index 75% rename from winpr/registry/CMakeLists.txt rename to winpr/libwinpr/registry/CMakeLists.txt index cb4b0be76..bec525300 100644 --- a/winpr/registry/CMakeLists.txt +++ b/winpr/libwinpr/registry/CMakeLists.txt @@ -22,11 +22,17 @@ set(WINPR_REGISTRY_SRCS registry_reg.h registry.c) -add_library(winpr-registry ${WINPR_REGISTRY_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-registry OBJECT ${WINPR_REGISTRY_SRCS}) +else() + add_library(winpr-registry ${WINPR_REGISTRY_SRCS}) +endif() set_target_properties(winpr-registry PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -target_link_libraries(winpr-registry winpr-utils) - -install(TARGETS winpr-registry DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) +else() + target_link_libraries(winpr-registry winpr-utils) + install(TARGETS winpr-registry DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/registry/registry.c b/winpr/libwinpr/registry/registry.c similarity index 98% rename from winpr/registry/registry.c rename to winpr/libwinpr/registry/registry.c index 3b9c80ba1..dbc82e849 100644 --- a/winpr/registry/registry.c +++ b/winpr/libwinpr/registry/registry.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include /* @@ -30,6 +34,7 @@ #include #include #include +#include #include "registry_reg.h" @@ -217,7 +222,7 @@ LONG RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesire while (pKey != NULL) { - if (strcmp(pKey->subname, lpSubKey) == 0) + if (_stricmp(pKey->subname, lpSubKey) == 0) { *phkResult = pKey; return ERROR_SUCCESS; @@ -228,7 +233,7 @@ LONG RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesire *phkResult = NULL; - return 0; + return ERROR_FILE_NOT_FOUND; } LONG RegOpenUserClassesRoot(HANDLE hToken, DWORD dwOptions, REGSAM samDesired, PHKEY phkResult) diff --git a/winpr/registry/registry_reg.c b/winpr/libwinpr/registry/registry_reg.c similarity index 96% rename from winpr/registry/registry_reg.c rename to winpr/libwinpr/registry/registry_reg.c index c07bd4618..6082b2a25 100644 --- a/winpr/registry/registry_reg.c +++ b/winpr/libwinpr/registry/registry_reg.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -27,6 +31,9 @@ #define WINPR_HKLM_HIVE "/etc/winpr/HKLM.reg" +void reg_print_key(Reg* reg, RegKey* key); +void reg_print_value(Reg* reg, RegVal* value); + struct reg_data_type { char* tag; @@ -197,11 +204,12 @@ void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey) { char* name; char* path; + char* save; int length; path = _strdup(subkey->name); - name = strtok(path, "\\"); + name = strtok_s(path, "\\", &save); while (name != NULL) { @@ -212,7 +220,7 @@ void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey) subkey->subname = _strdup(name); } - name = strtok(NULL, "\\"); + name = strtok_s(NULL, "\\", &save); } free(path); diff --git a/winpr/registry/registry_reg.h b/winpr/libwinpr/registry/registry_reg.h similarity index 100% rename from winpr/registry/registry_reg.h rename to winpr/libwinpr/registry/registry_reg.h diff --git a/winpr/rpc/CMakeLists.txt b/winpr/libwinpr/rpc/CMakeLists.txt similarity index 72% rename from winpr/rpc/CMakeLists.txt rename to winpr/libwinpr/rpc/CMakeLists.txt index af607cbae..6e18f2d59 100644 --- a/winpr/rpc/CMakeLists.txt +++ b/winpr/libwinpr/rpc/CMakeLists.txt @@ -31,19 +31,29 @@ set(WINPR_RPC_SRCS ndr_union.c ndr_union.h midl.c) -add_library(winpr-rpc ${WINPR_RPC_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-rpc OBJECT ${WINPR_RPC_SRCS}) +else() + add_library(winpr-rpc ${WINPR_RPC_SRCS}) +endif() include_directories(${OPENSSL_INCLUDE_DIR}) include_directories(${ZLIB_INCLUDE_DIRS}) set_target_properties(winpr-rpc PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") +set(WINPR_RPC_LIBS + ${OPENSSL_LIBRARIES}) + if(WIN32) - target_link_libraries(winpr-rpc ws2_32) + set(WINPR_RPC_LIBS ${WINPR_RPC_LIBS} ws2_32) else() - target_link_libraries(winpr-rpc ${ZLIB_LIBRARIES}) + set(WINPR_RPC_LIBS ${WINPR_RPC_LIBS} ${ZLIB_LIBRARIES}) endif() -target_link_libraries(winpr-rpc ${OPENSSL_LIBRARIES}) - -install(TARGETS winpr-rpc DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${WINPR_RPC_LIBS} PARENT_SCOPE) +else() + target_link_libraries(winpr-rpc ${WINPR_RPC_LIBS}) + install(TARGETS winpr-rpc DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/rpc/midl.c b/winpr/libwinpr/rpc/midl.c similarity index 94% rename from winpr/rpc/midl.c rename to winpr/libwinpr/rpc/midl.c index bdd5bde5e..aab05d549 100644 --- a/winpr/rpc/midl.c +++ b/winpr/libwinpr/rpc/midl.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/rpc/ndr.c b/winpr/libwinpr/rpc/ndr.c similarity index 99% rename from winpr/rpc/ndr.c rename to winpr/libwinpr/rpc/ndr.c index bca80d84a..d90a2a03b 100644 --- a/winpr/rpc/ndr.c +++ b/winpr/libwinpr/rpc/ndr.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/winpr/rpc/ndr_array.c b/winpr/libwinpr/rpc/ndr_array.c similarity index 98% rename from winpr/rpc/ndr_array.c rename to winpr/libwinpr/rpc/ndr_array.c index 3c800144d..d9c53c5ea 100644 --- a/winpr/rpc/ndr_array.c +++ b/winpr/libwinpr/rpc/ndr_array.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/rpc/ndr_array.h b/winpr/libwinpr/rpc/ndr_array.h similarity index 100% rename from winpr/rpc/ndr_array.h rename to winpr/libwinpr/rpc/ndr_array.h diff --git a/winpr/rpc/ndr_context.c b/winpr/libwinpr/rpc/ndr_context.c similarity index 97% rename from winpr/rpc/ndr_context.c rename to winpr/libwinpr/rpc/ndr_context.c index 270074f95..531840074 100644 --- a/winpr/rpc/ndr_context.c +++ b/winpr/libwinpr/rpc/ndr_context.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/rpc/ndr_context.h b/winpr/libwinpr/rpc/ndr_context.h similarity index 100% rename from winpr/rpc/ndr_context.h rename to winpr/libwinpr/rpc/ndr_context.h diff --git a/winpr/rpc/ndr_correlation.c b/winpr/libwinpr/rpc/ndr_correlation.c similarity index 98% rename from winpr/rpc/ndr_correlation.c rename to winpr/libwinpr/rpc/ndr_correlation.c index 1a9383403..3deb4caca 100644 --- a/winpr/rpc/ndr_correlation.c +++ b/winpr/libwinpr/rpc/ndr_correlation.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/rpc/ndr_correlation.h b/winpr/libwinpr/rpc/ndr_correlation.h similarity index 100% rename from winpr/rpc/ndr_correlation.h rename to winpr/libwinpr/rpc/ndr_correlation.h diff --git a/winpr/rpc/ndr_pointer.c b/winpr/libwinpr/rpc/ndr_pointer.c similarity index 99% rename from winpr/rpc/ndr_pointer.c rename to winpr/libwinpr/rpc/ndr_pointer.c index bec4b4f2e..f140776d3 100644 --- a/winpr/rpc/ndr_pointer.c +++ b/winpr/libwinpr/rpc/ndr_pointer.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/rpc/ndr_pointer.h b/winpr/libwinpr/rpc/ndr_pointer.h similarity index 100% rename from winpr/rpc/ndr_pointer.h rename to winpr/libwinpr/rpc/ndr_pointer.h diff --git a/winpr/rpc/ndr_private.c b/winpr/libwinpr/rpc/ndr_private.c similarity index 99% rename from winpr/rpc/ndr_private.c rename to winpr/libwinpr/rpc/ndr_private.c index 22fc59868..db57de23b 100644 --- a/winpr/rpc/ndr_private.c +++ b/winpr/libwinpr/rpc/ndr_private.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/rpc/ndr_private.h b/winpr/libwinpr/rpc/ndr_private.h similarity index 100% rename from winpr/rpc/ndr_private.h rename to winpr/libwinpr/rpc/ndr_private.h diff --git a/winpr/rpc/ndr_simple.c b/winpr/libwinpr/rpc/ndr_simple.c similarity index 99% rename from winpr/rpc/ndr_simple.c rename to winpr/libwinpr/rpc/ndr_simple.c index 97927f19e..d9492c130 100644 --- a/winpr/rpc/ndr_simple.c +++ b/winpr/libwinpr/rpc/ndr_simple.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/rpc/ndr_simple.h b/winpr/libwinpr/rpc/ndr_simple.h similarity index 100% rename from winpr/rpc/ndr_simple.h rename to winpr/libwinpr/rpc/ndr_simple.h diff --git a/winpr/rpc/ndr_string.c b/winpr/libwinpr/rpc/ndr_string.c similarity index 95% rename from winpr/rpc/ndr_string.c rename to winpr/libwinpr/rpc/ndr_string.c index a52fb9923..e5f022df4 100644 --- a/winpr/rpc/ndr_string.c +++ b/winpr/libwinpr/rpc/ndr_string.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/rpc/ndr_string.h b/winpr/libwinpr/rpc/ndr_string.h similarity index 100% rename from winpr/rpc/ndr_string.h rename to winpr/libwinpr/rpc/ndr_string.h diff --git a/winpr/rpc/ndr_structure.c b/winpr/libwinpr/rpc/ndr_structure.c similarity index 99% rename from winpr/rpc/ndr_structure.c rename to winpr/libwinpr/rpc/ndr_structure.c index d7f3957c2..cf0895c30 100644 --- a/winpr/rpc/ndr_structure.c +++ b/winpr/libwinpr/rpc/ndr_structure.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/rpc/ndr_structure.h b/winpr/libwinpr/rpc/ndr_structure.h similarity index 100% rename from winpr/rpc/ndr_structure.h rename to winpr/libwinpr/rpc/ndr_structure.h diff --git a/winpr/rpc/ndr_union.c b/winpr/libwinpr/rpc/ndr_union.c similarity index 96% rename from winpr/rpc/ndr_union.c rename to winpr/libwinpr/rpc/ndr_union.c index 644ef5831..be4fab3e2 100644 --- a/winpr/rpc/ndr_union.c +++ b/winpr/libwinpr/rpc/ndr_union.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/rpc/ndr_union.h b/winpr/libwinpr/rpc/ndr_union.h similarity index 100% rename from winpr/rpc/ndr_union.h rename to winpr/libwinpr/rpc/ndr_union.h diff --git a/winpr/rpc/rpc.c b/winpr/libwinpr/rpc/rpc.c similarity index 94% rename from winpr/rpc/rpc.c rename to winpr/libwinpr/rpc/rpc.c index c76096627..2987cfb54 100644 --- a/winpr/rpc/rpc.c +++ b/winpr/libwinpr/rpc/rpc.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/sspi/CMakeLists.txt b/winpr/libwinpr/sspi/CMakeLists.txt similarity index 71% rename from winpr/sspi/CMakeLists.txt rename to winpr/libwinpr/sspi/CMakeLists.txt index 6ec31db3a..88c1b07b0 100644 --- a/winpr/sspi/CMakeLists.txt +++ b/winpr/libwinpr/sspi/CMakeLists.txt @@ -52,21 +52,37 @@ if(NOT WITH_NATIVE_SSPI) ${WINPR_SSPI_SRCS}) endif() -add_library(winpr-sspi ${WINPR_SSPI_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-sspi OBJECT ${WINPR_SSPI_SRCS}) +else() + add_library(winpr-sspi ${WINPR_SSPI_SRCS}) +endif() include_directories(${ZLIB_INCLUDE_DIRS}) include_directories(${OPENSSL_INCLUDE_DIR}) set_target_properties(winpr-sspi PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -if (NOT WIN32) - target_link_libraries(winpr-sspi winpr-crt) - target_link_libraries(winpr-sspi winpr-sysinfo) +set(WINPR_SSPI_LIBS + ${ZLIB_LIBRARIES} + ${OPENSSL_LIBRARIES}) + +if(WITH_MONOLITHIC_BUILD) + set(WINPR_SSPI_LIBS ${WINPR_SSPI_LIBS} winpr) +else() + if (NOT WIN32) + set(WINPR_SSPI_LIBS ${WINPR_SSPI_LIBS} + winpr-crt + winpr-sysinfo + winpr-registry) + endif() + + set(WINPR_SSPI_LIBS ${WINPR_SSPI_LIBS} winpr-utils) endif() -target_link_libraries(winpr-sspi winpr-utils) -target_link_libraries(winpr-sspi ${ZLIB_LIBRARIES}) -target_link_libraries(winpr-sspi ${OPENSSL_LIBRARIES}) - -install(TARGETS winpr-sspi DESTINATION ${CMAKE_INSTALL_LIBDIR}) - +if(WITH_MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${WINPR_SSPI_LIBS} PARENT_SCOPE) +else() + target_link_libraries(winpr-sspi ${WINPR_SSPI_LIBS}) + install(TARGETS winpr-sspi DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/sspi/CredSSP/credssp.c b/winpr/libwinpr/sspi/CredSSP/credssp.c similarity index 99% rename from winpr/sspi/CredSSP/credssp.c rename to winpr/libwinpr/sspi/CredSSP/credssp.c index e92d53841..3da23e942 100644 --- a/winpr/sspi/CredSSP/credssp.c +++ b/winpr/libwinpr/sspi/CredSSP/credssp.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/sspi/CredSSP/credssp.h b/winpr/libwinpr/sspi/CredSSP/credssp.h similarity index 100% rename from winpr/sspi/CredSSP/credssp.h rename to winpr/libwinpr/sspi/CredSSP/credssp.h diff --git a/winpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c similarity index 89% rename from winpr/sspi/NTLM/ntlm.c rename to winpr/libwinpr/sspi/NTLM/ntlm.c index 0577e5318..9c5bf4b0c 100644 --- a/winpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -28,6 +32,7 @@ #include #include #include +#include #include "ntlm.h" #include "../sspi.h" @@ -56,7 +61,14 @@ void ntlm_SetContextWorkstation(NTLM_CONTEXT* context, char* Workstation) free(Workstation); } -void ntlm_SetContextServicePrincipalName(NTLM_CONTEXT* context, char* ServicePrincipalName) +void ntlm_SetContextServicePrincipalNameW(NTLM_CONTEXT* context, LPWSTR ServicePrincipalName) +{ + context->ServicePrincipalName.Length = lstrlenW(ServicePrincipalName) * 2; + context->ServicePrincipalName.Buffer = (PWSTR) malloc(context->ServicePrincipalName.Length); + CopyMemory(context->ServicePrincipalName.Buffer, ServicePrincipalName, context->ServicePrincipalName.Length); +} + +void ntlm_SetContextServicePrincipalNameA(NTLM_CONTEXT* context, char* ServicePrincipalName) { context->ServicePrincipalName.Length = strlen(ServicePrincipalName) * 2; context->ServicePrincipalName.Buffer = (PWSTR) malloc(context->ServicePrincipalName.Length); @@ -94,13 +106,47 @@ NTLM_CONTEXT* ntlm_ContextNew() if (context != NULL) { + HKEY hKey; + LONG status; + DWORD dwType; + DWORD dwSize; + DWORD dwValue; + context->NTLMv2 = TRUE; context->UseMIC = FALSE; - context->NegotiateFlags = 0; context->SendVersionInfo = TRUE; + + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\WinPR\\NTLM"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + + if (status == ERROR_SUCCESS) + { + if (RegQueryValueEx(hKey, _T("NTLMv2"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + context->NTLMv2 = dwValue ? 1 : 0; + + if (RegQueryValueEx(hKey, _T("UseMIC"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + context->UseMIC = dwValue ? 1 : 0; + + if (RegQueryValueEx(hKey, _T("SendVersionInfo"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + context->SendVersionInfo = dwValue ? 1 : 0; + + RegCloseKey(hKey); + } + + context->SuppressExtendedProtection = FALSE; + + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\LSA"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + + if (status == ERROR_SUCCESS) + { + if (RegQueryValueEx(hKey, _T("SuppressExtendedProtection"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + context->SuppressExtendedProtection = dwValue ? 1 : 0; + + RegCloseKey(hKey); + } + + context->NegotiateFlags = 0; context->LmCompatibilityLevel = 3; context->state = NTLM_STATE_INITIAL; - context->SuppressExtendedProtection = FALSE; memset(context->MachineID, 0xAA, sizeof(context->MachineID)); if (context->NTLMv2) @@ -142,7 +188,9 @@ SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal credentials = sspi_CredentialsNew(); identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData; - CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); + + if (identity != NULL) + CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) NTLM_PACKAGE_NAME); @@ -154,7 +202,11 @@ SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal credentials = sspi_CredentialsNew(); identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData; - CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); + + if (identity) + CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); + else + ZeroMemory(&(credentials->identity), sizeof(SEC_WINNT_AUTH_IDENTITY)); sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) NTLM_PACKAGE_NAME); @@ -233,12 +285,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesW(PCredHandle phCredent SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer) { - if (ulAttribute == SECPKG_CRED_ATTR_NAMES) - { - return SEC_E_OK; - } - - return SEC_E_UNSUPPORTED_FUNCTION; + return ntlm_QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer); } /** @@ -351,17 +398,6 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle phCredenti SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) -{ - return SEC_E_OK; -} - -/** - * @see http://msdn.microsoft.com/en-us/library/windows/desktop/aa375512%28v=vs.85%29.aspx - */ -SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, - SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, - PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) { NTLM_CONTEXT* context; SECURITY_STATUS status; @@ -374,6 +410,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredenti if (!context) { context = ntlm_ContextNew(); + if (!context) return SEC_E_INSUFFICIENT_MEMORY; @@ -383,7 +420,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredenti credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); ntlm_SetContextWorkstation(context, NULL); - ntlm_SetContextServicePrincipalName(context, pszTargetName); + ntlm_SetContextServicePrincipalNameW(context, pszTargetName); sspi_CopyAuthIdentity(&context->identity, &credentials->identity); sspi_SecureHandleSetLowerPointer(phNewContext, context); @@ -455,6 +492,35 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredenti return SEC_E_OUT_OF_SEQUENCE; } +/** + * @see http://msdn.microsoft.com/en-us/library/windows/desktop/aa375512%28v=vs.85%29.aspx + */ +SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, + SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, + PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, + PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) +{ + int length; + SECURITY_STATUS status; + SEC_WCHAR* pszTargetNameW = NULL; + + if (pszTargetName != NULL) + { + length = strlen(pszTargetName); + pszTargetNameW = (PWSTR) malloc((length + 1) * 2); + MultiByteToWideChar(CP_ACP, 0, pszTargetName, length, pszTargetNameW, length); + pszTargetNameW[length] = 0; + } + + status = ntlm_InitializeSecurityContextW(phCredential, phContext, pszTargetNameW, fContextReq, + Reserved1, TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); + + if (pszTargetNameW != NULL) + free(pszTargetNameW); + + return status; +} + /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375354 */ SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext) @@ -474,11 +540,6 @@ SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext) /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa379337/ */ SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer) -{ - return SEC_E_OK; -} - -SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer) { if (!phContext) return SEC_E_INVALID_HANDLE; @@ -501,6 +562,11 @@ SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext, UL return SEC_E_UNSUPPORTED_FUNCTION; } +SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer) +{ + return ntlm_QueryContextAttributesW(phContext, ulAttribute, pBuffer); +} + SECURITY_STATUS SEC_ENTRY ntlm_RevertSecurityContext(PCtxtHandle phContext) { return SEC_E_OK; diff --git a/winpr/sspi/NTLM/ntlm.h b/winpr/libwinpr/sspi/NTLM/ntlm.h similarity index 100% rename from winpr/sspi/NTLM/ntlm.h rename to winpr/libwinpr/sspi/NTLM/ntlm.h diff --git a/winpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c similarity index 99% rename from winpr/sspi/NTLM/ntlm_av_pairs.c rename to winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c index 2261703ea..26967621f 100644 --- a/winpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ntlm.h" #include "../sspi.h" @@ -360,6 +364,6 @@ void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context) NTLM_AV_PAIR* AvEOL; AvEOL = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvEOL); - ZeroMemory((void*) AvEOL, 12); + ZeroMemory((void*) AvEOL, 4); } } diff --git a/winpr/sspi/NTLM/ntlm_av_pairs.h b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.h similarity index 100% rename from winpr/sspi/NTLM/ntlm_av_pairs.h rename to winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.h diff --git a/winpr/sspi/NTLM/ntlm_compute.c b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c similarity index 94% rename from winpr/sspi/NTLM/ntlm_compute.c rename to winpr/libwinpr/sspi/NTLM/ntlm_compute.c index 18787aea7..3fe05ee58 100644 --- a/winpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ntlm.h" #include "../sspi.h" @@ -49,9 +53,9 @@ void ntlm_get_version_info(NTLM_VERSION_INFO* versionInfo) GetVersionExA(&osVersionInfo); - versionInfo->ProductMajorVersion = osVersionInfo.dwMajorVersion; - versionInfo->ProductMinorVersion = osVersionInfo.dwMinorVersion; - versionInfo->ProductBuild = osVersionInfo.dwBuildNumber; + versionInfo->ProductMajorVersion = (UINT8) osVersionInfo.dwMajorVersion; + versionInfo->ProductMinorVersion = (UINT8) osVersionInfo.dwMinorVersion; + versionInfo->ProductBuild = (UINT16) osVersionInfo.dwBuildNumber; ZeroMemory(versionInfo->Reserved, sizeof(versionInfo->Reserved)); versionInfo->NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3; } @@ -226,6 +230,8 @@ void ntlm_fetch_ntlm_v2_hash(NTLM_CONTEXT* context, char* hash) WINPR_SAM_ENTRY* entry; sam = SamOpen(1); + if (sam == NULL) + return; entry = SamLookupUserW(sam, (LPWSTR) context->identity.User, context->identity.UserLength * 2, @@ -233,16 +239,46 @@ void ntlm_fetch_ntlm_v2_hash(NTLM_CONTEXT* context, char* hash) if (entry != NULL) { - CopyMemory(hash, entry->NtHash, 16); +#ifdef WITH_DEBUG_NTLM + printf("NTLM Hash:\n"); + winpr_HexDump(entry->NtHash, 16); +#endif + + NTOWFv2FromHashW(entry->NtHash, + (LPWSTR) context->identity.User, context->identity.UserLength * 2, + (LPWSTR) context->identity.Domain, context->identity.DomainLength * 2, + (BYTE*) hash); + + SamFreeEntry(sam, entry); + SamClose(sam); + + return; + } + + entry = SamLookupUserW(sam, + (LPWSTR) context->identity.User, context->identity.UserLength * 2, NULL, 0); + + if (entry != NULL) + { +#ifdef WITH_DEBUG_NTLM + printf("NTLM Hash:\n"); + winpr_HexDump(entry->NtHash, 16); +#endif + + NTOWFv2FromHashW(entry->NtHash, + (LPWSTR) context->identity.User, context->identity.UserLength * 2, + (LPWSTR) context->identity.Domain, context->identity.DomainLength * 2, + (BYTE*) hash); + + SamFreeEntry(sam, entry); + SamClose(sam); + + return; } else { printf("Error: Could not find user in SAM database\n"); } - - SamFreeEntry(sam, entry); - - SamClose(sam); } void ntlm_compute_ntlm_v2_hash(NTLM_CONTEXT* context, char* hash) diff --git a/winpr/sspi/NTLM/ntlm_compute.h b/winpr/libwinpr/sspi/NTLM/ntlm_compute.h similarity index 100% rename from winpr/sspi/NTLM/ntlm_compute.h rename to winpr/libwinpr/sspi/NTLM/ntlm_compute.h diff --git a/winpr/sspi/NTLM/ntlm_message.c b/winpr/libwinpr/sspi/NTLM/ntlm_message.c similarity index 97% rename from winpr/sspi/NTLM/ntlm_message.c rename to winpr/libwinpr/sspi/NTLM/ntlm_message.c index dbdaaed26..28d17f02c 100644 --- a/winpr/sspi/NTLM/ntlm_message.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_message.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ntlm.h" #include "../sspi.h" @@ -264,15 +268,15 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu message.NegotiateFlags |= NTLMSSP_REQUEST_TARGET; message.NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE; - if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION) - ntlm_get_version_info(&(message.Version)); - if (context->confidentiality) message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; if (context->SendVersionInfo) message.NegotiateFlags |= NTLMSSP_NEGOTIATE_VERSION; + if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION) + ntlm_get_version_info(&(message.Version)); + context->NegotiateFlags = message.NegotiateFlags; /* Message Header (12 bytes) */ @@ -398,6 +402,12 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf ntlm_print_message_fields(&(message.TargetName), "TargetName"); ntlm_print_message_fields(&(message.TargetInfo), "TargetInfo"); + + if (context->ChallengeTargetInfo.cbBuffer > 0) + { + printf("ChallengeTargetInfo (%d):\n", (int) context->ChallengeTargetInfo.cbBuffer); + ntlm_print_av_pair_list(context->ChallengeTargetInfo.pvBuffer); + } #endif /* AV_PAIRs */ @@ -862,11 +872,15 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer { message.NegotiateFlags |= NTLMSSP_NEGOTIATE_56; message.NegotiateFlags |= NTLMSSP_NEGOTIATE_VERSION; + message.NegotiateFlags |= NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED; } if (context->UseMIC) message.NegotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO; + if (context->confidentiality) + message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; + message.NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH; message.NegotiateFlags |= NTLMSSP_NEGOTIATE_128; message.NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY; @@ -879,14 +893,11 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION) ntlm_get_version_info(&(message.Version)); - message.Workstation.Len = context->Workstation.Length; - message.Workstation.Buffer = (BYTE*) context->Workstation.Buffer; - - if (!context->NTLMv2) - message.Workstation.Len = 0; - - if (message.Workstation.Len > 0) - message.NegotiateFlags |= NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED; + if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) + { + message.Workstation.Len = context->Workstation.Length; + message.Workstation.Buffer = (BYTE*) context->Workstation.Buffer; + } message.DomainName.Len = (UINT16) context->identity.DomainLength * 2; message.DomainName.Buffer = (BYTE*) context->identity.Domain; @@ -906,9 +917,6 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer message.EncryptedRandomSessionKey.Len = 16; message.EncryptedRandomSessionKey.Buffer = context->EncryptedRandomSessionKey; - if (context->confidentiality) - message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; - PayloadBufferOffset = 64; if (context->UseMIC) @@ -1006,6 +1014,12 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION) ntlm_print_version_info(&(message.Version)); + if (context->AuthenticateTargetInfo.cbBuffer > 0) + { + printf("AuthenticateTargetInfo (%d):\n", (int) context->AuthenticateTargetInfo.cbBuffer); + ntlm_print_av_pair_list(context->AuthenticateTargetInfo.pvBuffer); + } + ntlm_print_message_fields(&(message.DomainName), "DomainName"); ntlm_print_message_fields(&(message.UserName), "UserName"); ntlm_print_message_fields(&(message.Workstation), "Workstation"); diff --git a/winpr/sspi/NTLM/ntlm_message.h b/winpr/libwinpr/sspi/NTLM/ntlm_message.h similarity index 100% rename from winpr/sspi/NTLM/ntlm_message.h rename to winpr/libwinpr/sspi/NTLM/ntlm_message.h diff --git a/winpr/sspi/Negotiate/negotiate.c b/winpr/libwinpr/sspi/Negotiate/negotiate.c similarity index 99% rename from winpr/sspi/Negotiate/negotiate.c rename to winpr/libwinpr/sspi/Negotiate/negotiate.c index c8bc191dd..616c647a7 100644 --- a/winpr/sspi/Negotiate/negotiate.c +++ b/winpr/libwinpr/sspi/Negotiate/negotiate.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/sspi/Negotiate/negotiate.h b/winpr/libwinpr/sspi/Negotiate/negotiate.h similarity index 100% rename from winpr/sspi/Negotiate/negotiate.h rename to winpr/libwinpr/sspi/Negotiate/negotiate.h diff --git a/winpr/sspi/Schannel/schannel.c b/winpr/libwinpr/sspi/Schannel/schannel.c similarity index 99% rename from winpr/sspi/Schannel/schannel.c rename to winpr/libwinpr/sspi/Schannel/schannel.c index 2f94c41c2..b6d755379 100644 --- a/winpr/sspi/Schannel/schannel.c +++ b/winpr/libwinpr/sspi/Schannel/schannel.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/sspi/Schannel/schannel.h b/winpr/libwinpr/sspi/Schannel/schannel.h similarity index 100% rename from winpr/sspi/Schannel/schannel.h rename to winpr/libwinpr/sspi/Schannel/schannel.h diff --git a/winpr/sspi/sspi.c b/winpr/libwinpr/sspi/sspi.c similarity index 94% rename from winpr/sspi/sspi.c rename to winpr/libwinpr/sspi/sspi.c index 6d30464d5..87697460c 100644 --- a/winpr/sspi/sspi.c +++ b/winpr/libwinpr/sspi/sspi.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -353,7 +357,7 @@ void sspi_GlobalFinish() #ifndef WITH_NATIVE_SSPI -SecurityFunctionTableA* sspi_GetSecurityFunctionTableByNameA(const SEC_CHAR* Name) +SecurityFunctionTableA* sspi_GetSecurityFunctionTableAByNameA(const SEC_CHAR* Name) { int index; UINT32 cPackages; @@ -371,7 +375,12 @@ SecurityFunctionTableA* sspi_GetSecurityFunctionTableByNameA(const SEC_CHAR* Nam return NULL; } -SecurityFunctionTableW* sspi_GetSecurityFunctionTableByNameW(const SEC_WCHAR* Name) +SecurityFunctionTableA* sspi_GetSecurityFunctionTableAByNameW(const SEC_WCHAR* Name) +{ + return NULL; +} + +SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameW(const SEC_WCHAR* Name) { int index; UINT32 cPackages; @@ -389,6 +398,23 @@ SecurityFunctionTableW* sspi_GetSecurityFunctionTableByNameW(const SEC_WCHAR* Na return NULL; } +SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameA(const SEC_CHAR* Name) +{ + int length; + SEC_WCHAR* NameW; + SecurityFunctionTableW* table; + + length = strlen(Name); + NameW = (SEC_WCHAR*) malloc((length + 1) * 2); + MultiByteToWideChar(CP_ACP, 0, Name, length, (LPWSTR) NameW, length); + NameW[length] = 0; + + table = sspi_GetSecurityFunctionTableWByNameW(NameW); + free(NameW); + + return table; +} + void FreeContextBuffer_EnumerateSecurityPackages(void* contextBuffer); void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer); @@ -599,7 +625,7 @@ SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SECURITY_STATUS status; - SecurityFunctionTableW* table = sspi_GetSecurityFunctionTableByNameW(pszPackage); + SecurityFunctionTableW* table = sspi_GetSecurityFunctionTableWByNameW(pszPackage); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -618,7 +644,7 @@ SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_ void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SECURITY_STATUS status; - SecurityFunctionTableA* table = sspi_GetSecurityFunctionTableByNameA(pszPackage); + SecurityFunctionTableA* table = sspi_GetSecurityFunctionTableAByNameA(pszPackage); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -648,7 +674,7 @@ SECURITY_STATUS SEC_ENTRY FreeCredentialsHandle(PCredHandle phCredential) if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableAByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -682,7 +708,7 @@ SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesW(PCredHandle phCredential, if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameW(Name); + table = sspi_GetSecurityFunctionTableWByNameW(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -706,7 +732,7 @@ SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesA(PCredHandle phCredential, if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableAByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -734,7 +760,7 @@ SECURITY_STATUS SEC_ENTRY AcceptSecurityContext(PCredHandle phCredential, PCtxtH if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableAByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -769,7 +795,7 @@ SECURITY_STATUS SEC_ENTRY DeleteSecurityContext(PCtxtHandle phContext) if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableAByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -811,7 +837,7 @@ SECURITY_STATUS SEC_ENTRY InitializeSecurityContextW(PCredHandle phCredential, P if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = (SecurityFunctionTableW*) sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableWByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -840,7 +866,7 @@ SECURITY_STATUS SEC_ENTRY InitializeSecurityContextA(PCredHandle phCredential, P if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableAByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -866,7 +892,7 @@ SECURITY_STATUS SEC_ENTRY QueryContextAttributesW(PCtxtHandle phContext, ULONG u if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = (SecurityFunctionTableW*) sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableWByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -890,7 +916,7 @@ SECURITY_STATUS SEC_ENTRY QueryContextAttributesA(PCtxtHandle phContext, ULONG u if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableAByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -931,7 +957,7 @@ SECURITY_STATUS SEC_ENTRY DecryptMessage(PCtxtHandle phContext, PSecBufferDesc p if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableAByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -955,7 +981,7 @@ SECURITY_STATUS SEC_ENTRY EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSec if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableAByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -979,7 +1005,7 @@ SECURITY_STATUS SEC_ENTRY MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecB if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableAByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -1003,7 +1029,7 @@ SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext, PSecBufferDesc if (!Name) return SEC_E_SECPKG_NOT_FOUND; - table = sspi_GetSecurityFunctionTableByNameA(Name); + table = sspi_GetSecurityFunctionTableAByNameA(Name); if (!table) return SEC_E_SECPKG_NOT_FOUND; @@ -1029,7 +1055,7 @@ SecurityFunctionTableA SSPI_SecurityFunctionTableA = CompleteAuthToken, /* CompleteAuthToken */ DeleteSecurityContext, /* DeleteSecurityContext */ ApplyControlToken, /* ApplyControlToken */ - QueryContextAttributes, /* QueryContextAttributes */ + QueryContextAttributesA, /* QueryContextAttributes */ ImpersonateSecurityContext, /* ImpersonateSecurityContext */ RevertSecurityContext, /* RevertSecurityContext */ MakeSignature, /* MakeSignature */ @@ -1061,7 +1087,7 @@ SecurityFunctionTableW SSPI_SecurityFunctionTableW = CompleteAuthToken, /* CompleteAuthToken */ DeleteSecurityContext, /* DeleteSecurityContext */ ApplyControlToken, /* ApplyControlToken */ - QueryContextAttributes, /* QueryContextAttributes */ + QueryContextAttributesW, /* QueryContextAttributes */ ImpersonateSecurityContext, /* ImpersonateSecurityContext */ RevertSecurityContext, /* RevertSecurityContext */ MakeSignature, /* MakeSignature */ diff --git a/winpr/sspi/sspi.h b/winpr/libwinpr/sspi/sspi.h similarity index 99% rename from winpr/sspi/sspi.h rename to winpr/libwinpr/sspi/sspi.h index 92a7894d2..b51f72398 100644 --- a/winpr/sspi/sspi.h +++ b/winpr/libwinpr/sspi/sspi.h @@ -20,8 +20,6 @@ #ifndef WINPR_SSPI_PRIVATE_H #define WINPR_SSPI_PRIVATE_H -#include "config.h" - #include struct _CREDENTIALS diff --git a/winpr/sspicli/CMakeLists.txt b/winpr/libwinpr/sspicli/CMakeLists.txt similarity index 78% rename from winpr/sspicli/CMakeLists.txt rename to winpr/libwinpr/sspicli/CMakeLists.txt index b747a9d2f..24487a795 100644 --- a/winpr/sspicli/CMakeLists.txt +++ b/winpr/libwinpr/sspicli/CMakeLists.txt @@ -20,9 +20,16 @@ set(WINPR_SSPICLI_SRCS sspicli.c) -add_library(winpr-sspicli ${WINPR_SSPICLI_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-sspicli OBJECT ${WINPR_SSPICLI_SRCS}) +else() + add_library(winpr-sspicli ${WINPR_SSPICLI_SRCS}) +endif() set_target_properties(winpr-sspicli PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -install(TARGETS winpr-sspicli DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) +else() + install(TARGETS winpr-sspicli DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/sspicli/sspicli.c b/winpr/libwinpr/sspicli/sspicli.c similarity index 97% rename from winpr/sspicli/sspicli.c rename to winpr/libwinpr/sspicli/sspicli.c index ef18f7e0c..6a820b2a2 100644 --- a/winpr/sspicli/sspicli.c +++ b/winpr/libwinpr/sspicli/sspicli.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include /** diff --git a/winpr/libwinpr/synch/CMakeLists.txt b/winpr/libwinpr/synch/CMakeLists.txt new file mode 100644 index 000000000..e53671556 --- /dev/null +++ b/winpr/libwinpr/synch/CMakeLists.txt @@ -0,0 +1,55 @@ +# WinPR: Windows Portable Runtime +# libwinpr-synch cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(CMAKE_THREAD_PREFER_PTHREAD) +find_required_package(Threads) + +set(WINPR_SYNCH_SRCS + critical.c + event.c + mutex.c + semaphore.c + sleep.c) + +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-synch OBJECT ${WINPR_SYNCH_SRCS}) +else() + add_library(winpr-synch ${WINPR_SYNCH_SRCS}) +endif() + +set_target_properties(winpr-synch PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +set(WINPR_SYNCH_LIBS + ${CMAKE_THREAD_LIBS_INIT} + ${CMAKE_DL_LIBS}) + +if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) + set(WINPR_SYNCH_LIBS ${WINPR_SYNCH_LIBS} rt) +endif() + +if(WITH_MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${WINPR_SYNCH_LIBS} PARENT_SCOPE) +else() + if(NOT WIN32) + set(WINPR_SYNCH_LIBS ${WINPR_SYNCH_LIBS} winpr-handle) + endif() + + target_link_libraries(winpr-synch ${WINPR_SYNCH_LIBS}) + install(TARGETS winpr-synch DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/synch/critical.c b/winpr/libwinpr/synch/critical.c similarity index 93% rename from winpr/synch/critical.c rename to winpr/libwinpr/synch/critical.c index b929ef678..1ebbf99c4 100644 --- a/winpr/synch/critical.c +++ b/winpr/libwinpr/synch/critical.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include diff --git a/winpr/synch/event.c b/winpr/libwinpr/synch/event.c similarity index 93% rename from winpr/synch/event.c rename to winpr/libwinpr/synch/event.c index b929ef678..1ebbf99c4 100644 --- a/winpr/synch/event.c +++ b/winpr/libwinpr/synch/event.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include diff --git a/winpr/synch/mutex.c b/winpr/libwinpr/synch/mutex.c similarity index 93% rename from winpr/synch/mutex.c rename to winpr/libwinpr/synch/mutex.c index b929ef678..1ebbf99c4 100644 --- a/winpr/synch/mutex.c +++ b/winpr/libwinpr/synch/mutex.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include diff --git a/winpr/synch/semaphore.c b/winpr/libwinpr/synch/semaphore.c similarity index 98% rename from winpr/synch/semaphore.c rename to winpr/libwinpr/synch/semaphore.c index 867364a1e..8d4be4ea7 100644 --- a/winpr/synch/semaphore.c +++ b/winpr/libwinpr/synch/semaphore.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #ifndef _WIN32 diff --git a/winpr/synch/sleep.c b/winpr/libwinpr/synch/sleep.c similarity index 93% rename from winpr/synch/sleep.c rename to winpr/libwinpr/synch/sleep.c index b929ef678..1ebbf99c4 100644 --- a/winpr/synch/sleep.c +++ b/winpr/libwinpr/synch/sleep.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include diff --git a/winpr/sysinfo/CMakeLists.txt b/winpr/libwinpr/sysinfo/CMakeLists.txt similarity index 78% rename from winpr/sysinfo/CMakeLists.txt rename to winpr/libwinpr/sysinfo/CMakeLists.txt index cf82e0be7..159163800 100644 --- a/winpr/sysinfo/CMakeLists.txt +++ b/winpr/libwinpr/sysinfo/CMakeLists.txt @@ -20,9 +20,16 @@ set(WINPR_SYSINFO_SRCS sysinfo.c) -add_library(winpr-sysinfo ${WINPR_SYSINFO_SRCS}) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-sysinfo OBJECT ${WINPR_SYSINFO_SRCS}) +else() + add_library(winpr-sysinfo ${WINPR_SYSINFO_SRCS}) +endif() set_target_properties(winpr-sysinfo PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -install(TARGETS winpr-sysinfo DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WITH_MONOLITHIC_BUILD) +else() + install(TARGETS winpr-sysinfo DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/sysinfo/sysinfo.c b/winpr/libwinpr/sysinfo/sysinfo.c similarity index 98% rename from winpr/sysinfo/sysinfo.c rename to winpr/libwinpr/sysinfo/sysinfo.c index feadc8986..000e7a757 100644 --- a/winpr/sysinfo/sysinfo.c +++ b/winpr/libwinpr/sysinfo/sysinfo.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include /** diff --git a/winpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt similarity index 67% rename from winpr/utils/CMakeLists.txt rename to winpr/libwinpr/utils/CMakeLists.txt index 12d24a0b7..ff4868d76 100644 --- a/winpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -23,19 +23,28 @@ set(WINPR_UTILS_SRCS sam.c stream.c) -add_library(winpr-utils ${WINPR_UTILS_SRCS}) - include_directories(${ZLIB_INCLUDE_DIRS}) include_directories(${OPENSSL_INCLUDE_DIR}) -set_target_properties(winpr-utils PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") - -if (NOT WIN32) - target_link_libraries(winpr-utils winpr-crt) +if(WITH_MONOLITHIC_BUILD) + add_library(winpr-utils OBJECT ${WINPR_UTILS_SRCS}) +else() + add_library(winpr-utils ${WINPR_UTILS_SRCS}) endif() -target_link_libraries(winpr-utils ${ZLIB_LIBRARIES}) -target_link_libraries(winpr-utils ${OPENSSL_LIBRARIES}) +set_target_properties(winpr-utils PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -install(TARGETS winpr-utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) +set(WINPR_UTILS_LIBS + ${ZLIB_LIBRARIES} + ${OPENSSL_LIBRARIES}) +if(WITH_MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${WINPR_UTILS_LIBS} PARENT_SCOPE) +else() + if (NOT WIN32) + set(WINPR_UTILS_LIBS ${WINPR_UTILS_LIBS} winpr-crt) + endif() + + target_link_libraries(winpr-utils ${WINPR_UTILS_LIBS}) + install(TARGETS winpr-utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/winpr/utils/ntlm.c b/winpr/libwinpr/utils/ntlm.c similarity index 70% rename from winpr/utils/ntlm.c rename to winpr/libwinpr/utils/ntlm.c index be2851705..200583ac6 100644 --- a/winpr/utils/ntlm.c +++ b/winpr/libwinpr/utils/ntlm.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -61,7 +65,7 @@ BYTE* NTOWFv1A(LPSTR Password, UINT32 PasswordLength, BYTE* NtHash) PasswordW = (LPWSTR) malloc(PasswordLength * 2); MultiByteToWideChar(CP_ACP, 0, Password, PasswordLength, PasswordW, PasswordLength); - NtHash = NTOWFv1W(PasswordW, PasswordLength, NtHash); + NtHash = NTOWFv1W(PasswordW, PasswordLength * 2, NtHash); free(PasswordW); @@ -129,3 +133,49 @@ BYTE* NTOWFv2A(LPSTR Password, UINT32 PasswordLength, LPSTR User, return NtHash; } +BYTE* NTOWFv2FromHashW(BYTE* NtHashV1, LPWSTR User, UINT32 UserLength, LPWSTR Domain, UINT32 DomainLength, BYTE* NtHash) +{ + BYTE* buffer; + + if (!User) + return NULL; + + if (!NtHash) + NtHash = (BYTE*) malloc(16); + + buffer = (BYTE*) malloc(UserLength + DomainLength); + + /* Concatenate(UpperCase(User), Domain) */ + + CopyMemory(buffer, User, UserLength); + CharUpperBuffW((LPWSTR) buffer, UserLength / 2); + CopyMemory(&buffer[UserLength], Domain, DomainLength); + + /* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is the NTLMv2 hash */ + HMAC(EVP_md5(), (void*) NtHashV1, 16, buffer, UserLength + DomainLength, (void*) NtHash, NULL); + + free(buffer); + + return NtHash; +} + +BYTE* NTOWFv2FromHashA(BYTE* NtHashV1, LPSTR User, UINT32 UserLength, LPSTR Domain, UINT32 DomainLength, BYTE* NtHash) +{ + LPWSTR UserW = NULL; + LPWSTR DomainW = NULL; + LPWSTR PasswordW = NULL; + + UserW = (LPWSTR) malloc(UserLength * 2); + DomainW = (LPWSTR) malloc(DomainLength * 2); + + MultiByteToWideChar(CP_ACP, 0, User, UserLength, UserW, UserLength); + MultiByteToWideChar(CP_ACP, 0, Domain, DomainLength, DomainW, DomainLength); + + NtHash = NTOWFv2FromHashW(NtHashV1, UserW, UserLength * 2, DomainW, DomainLength * 2, NtHash); + + free(UserW); + free(DomainW); + free(PasswordW); + + return NtHash; +} diff --git a/winpr/utils/print.c b/winpr/libwinpr/utils/print.c similarity index 96% rename from winpr/utils/print.c rename to winpr/libwinpr/utils/print.c index 9aa50fee2..173df27c7 100644 --- a/winpr/utils/print.c +++ b/winpr/libwinpr/utils/print.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/utils/sam.c b/winpr/libwinpr/utils/sam.c similarity index 86% rename from winpr/utils/sam.c rename to winpr/libwinpr/utils/sam.c index 14ca4ab01..b4cebc685 100644 --- a/winpr/utils/sam.c +++ b/winpr/libwinpr/utils/sam.c @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -25,36 +29,44 @@ #include #include +#ifdef _WIN32 +#define WINPR_SAM_FILE "C:\\SAM" +#else #define WINPR_SAM_FILE "/etc/winpr/SAM" +#endif WINPR_SAM* SamOpen(BOOL read_only) { - WINPR_SAM* sam; + FILE* fp = NULL; + WINPR_SAM* sam = NULL; - sam = (WINPR_SAM*) malloc(sizeof(WINPR_SAM)); - - if (sam != NULL) + if (read_only) { - sam->read_only = read_only; - - if (sam->read_only) - { - sam->fp = fopen(WINPR_SAM_FILE, "r"); - } - else - { - sam->fp = fopen(WINPR_SAM_FILE, "r+"); - - if (!sam->fp) - sam->fp = fopen(WINPR_SAM_FILE, "w+"); - } + fp = fopen(WINPR_SAM_FILE, "r"); } + else + { + fp = fopen(WINPR_SAM_FILE, "r+"); + + if (!fp) + fp = fopen(WINPR_SAM_FILE, "w+"); + } + + if (fp) + { + sam = (WINPR_SAM*) malloc(sizeof(WINPR_SAM)); + sam->read_only = read_only; + sam->fp = fp; + } + else + printf("Could not open SAM file!\n"); return sam; } -void SamLookupStart(WINPR_SAM* sam) +BOOL SamLookupStart(WINPR_SAM* sam) { + size_t read_size; long int file_size; fseek(sam->fp, 0, SEEK_END); @@ -62,20 +74,31 @@ void SamLookupStart(WINPR_SAM* sam) fseek(sam->fp, 0, SEEK_SET); if (file_size < 1) - return; + return FALSE; sam->buffer = (char*) malloc(file_size + 2); - if (fread(sam->buffer, file_size, 1, sam->fp) != 1) + read_size = fread(sam->buffer, file_size, 1, sam->fp); + + if (!read_size) + { + if (!ferror(sam->fp)) + read_size = file_size; + } + + if (read_size < 1) { free(sam->buffer); - return; + sam->buffer = NULL; + return FALSE; } sam->buffer[file_size] = '\n'; sam->buffer[file_size + 1] = '\0'; sam->line = strtok(sam->buffer, "\n"); + + return TRUE; } void SamLookupFinish(WINPR_SAM* sam) @@ -112,7 +135,7 @@ void HexStrToBin(char* str, BYTE* bin, int length) WINPR_SAM_ENTRY* SamReadEntry(WINPR_SAM* sam, WINPR_SAM_ENTRY* entry) { - char* p[5]; + char* p[7]; int LmHashLength; int NtHashLength; @@ -120,13 +143,15 @@ WINPR_SAM_ENTRY* SamReadEntry(WINPR_SAM* sam, WINPR_SAM_ENTRY* entry) p[1] = strchr(p[0], ':') + 1; p[2] = strchr(p[1], ':') + 1; p[3] = strchr(p[2], ':') + 1; - p[4] = p[0] + strlen(p[0]); + p[4] = strchr(p[3], ':') + 1; + p[5] = strchr(p[4], ':') + 1; + p[6] = p[0] + strlen(p[0]); entry->UserLength = p[1] - p[0] - 1; entry->DomainLength = p[2] - p[1] - 1; LmHashLength = p[3] - p[2] - 1; - NtHashLength = p[4] - p[3]; + NtHashLength = p[4] - p[3] - 1; entry->User = (LPSTR) malloc(entry->UserLength + 1); memcpy(entry->User, p[0], entry->UserLength); diff --git a/winpr/utils/stream.c b/winpr/libwinpr/utils/stream.c similarity index 98% rename from winpr/utils/stream.c rename to winpr/libwinpr/utils/stream.c index 3def650cf..a1be346a5 100644 --- a/winpr/utils/stream.c +++ b/winpr/libwinpr/utils/stream.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include diff --git a/winpr/tools/hash/CMakeLists.txt b/winpr/tools/hash/CMakeLists.txt index b8a1fc46c..cef98e55d 100644 --- a/winpr/tools/hash/CMakeLists.txt +++ b/winpr/tools/hash/CMakeLists.txt @@ -20,5 +20,9 @@ add_executable(winpr-hash hash.c) -target_link_libraries(winpr-hash winpr-utils) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(winpr-hash winpr) +else() + target_link_libraries(winpr-hash winpr-utils) +endif() diff --git a/winpr/tools/hash/hash.c b/winpr/tools/hash/hash.c index e42cbd1a9..f984047a8 100644 --- a/winpr/tools/hash/hash.c +++ b/winpr/tools/hash/hash.c @@ -48,7 +48,6 @@ int main(int argc, char* argv[]) { int index = 1; BYTE NtHash[16]; - BOOL sam_entry = 0; char* User = NULL; UINT32 UserLength; char* Domain = NULL; @@ -100,10 +99,6 @@ int main(int argc, char* argv[]) printf("Usage: winpr-hash -u -p [-d ]\n"); exit(1); } - else if (strcmp("-s", argv[index]) == 0) - { - sam_entry = 1; - } index++; } @@ -118,29 +113,22 @@ int main(int argc, char* argv[]) PasswordLength = strlen(Password); DomainLength = (Domain) ? strlen(Domain) : 0; - NTOWFv2A(Password, PasswordLength, User, UserLength, Domain, DomainLength, NtHash); + NTOWFv1A(Password, PasswordLength, NtHash); - if (sam_entry) - { - printf("%s:", User); - - if (DomainLength > 0) - printf("%s:", Domain); - else - printf(":"); + printf("%s:", User); + if (DomainLength > 0) + printf("%s:", Domain); + else printf(":"); - for (index = 0; index < 16; index++) - printf("%02x", NtHash[index]); - printf("\n"); - } - else - { - for (index = 0; index < 16; index++) - printf("%02x", NtHash[index]); - printf("\n"); - } + printf(":"); + + for (index = 0; index < 16; index++) + printf("%02x", NtHash[index]); + + printf(":::"); + printf("\n"); return 0; } diff --git a/winpr/tools/reg/CMakeLists.txt b/winpr/tools/reg/CMakeLists.txt index fd121a00e..446de5d2f 100644 --- a/winpr/tools/reg/CMakeLists.txt +++ b/winpr/tools/reg/CMakeLists.txt @@ -20,8 +20,12 @@ add_executable(winpr-reg reg.c) -target_link_libraries(winpr-reg winpr-utils) - -if(NOT WIN32) - target_link_libraries(winpr-reg winpr-registry) +if(WITH_MONOLITHIC_BUILD) + target_link_libraries(winpr-reg winpr) +else() + target_link_libraries(winpr-reg winpr-utils) + + if(NOT WIN32) + target_link_libraries(winpr-reg winpr-registry) + endif() endif() diff --git a/xcode.sh b/xcode.sh new file mode 100755 index 000000000..eebfed050 --- /dev/null +++ b/xcode.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# Xcode generated files directory +XCODE_PROJ_DIR=xcode +# MacFreeRDP client directory +CLIENT_MAC_DIR=./client/Mac/ +pushd . + +GEN='Xcode' + +# Build settings +ARCH=-DCMAKE_OSX_ARCHITECTURES="${CMAKE_OSX_ARCHITECTURES:-i386;x86_64}" +BUILDTYPE=-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:Debug}" +MANPAGES=-DWITH_MANPAGES="${WITHMANPAGES:NO}" + +# Run cmake for FreeRDP and MacFreeRDP +mkdir ${XCODE_PROJ_DIR} >/dev/null 2>&1 +pushd ${XCODE_PROJ_DIR} +cmake ${BUILDTYPE} -G "$GEN" ${ARCH} ../ +popd +mkdir ${CLIENT_MAC_DIR}/${XCODE_PROJ_DIR} >/dev/null 2>&1 +pushd ${CLIENT_MAC_DIR}/${XCODE_PROJ_DIR} +cmake ${BUILDTYPE} -G "$GEN" ${ARCH} ../ +popd + +# Check for errors; otherwise, ask for compile. +if [ "$?" -ne 0 ]; then + echo "CMake failed. Please check error messages" + popd > /dev/null + exit +else + popd + while true + do + echo -n "Compile FreeRDP? (y or n) - (y recommended for MacFreeRDP compilation):" + read CONFIRM + case $CONFIRM in + y|Y|YES|yes|Yes) + pushd ./${XCODE_PROJ_DIR} + xcodebuild + popd + break ;; + n|N|no|NO|No) + echo OK - you entered $CONFIRM + break + ;; + *) echo Please enter only y or n + esac + done + + echo "SUCCESS!" + while true + do + echo -n "Open Xcode projects now? (y or n):" + read CONFIRM + case $CONFIRM in + y|Y|YES|yes|Yes) + open ${CLIENT_MAC_DIR}/${XCODE_PROJ_DIR}/MacFreeRDP.xcodeproj + open ./${XCODE_PROJ_DIR}/FreeRDP.xcodeproj + break ;; + n|N|no|NO|No) + echo OK - $CONFIRM + break + ;; + *) echo Please enter only y or n + esac + done + + echo -n "NOTE: Dragging FreeRDP project from finder onto the MacFreeRDP project in Xcode + will enable code stepping from MacFreeRDP into FreeRDP. +" +fi \ No newline at end of file