diff options
Diffstat (limited to '')
-rw-r--r-- | scripts/LECHash.c | 101 | ||||
-rw-r--r-- | scripts/LOMHash.c | 77 | ||||
-rw-r--r-- | scripts/TimeZones.csx | 205 | ||||
-rw-r--r-- | scripts/blacklist-address-sanitizer.txt | 0 | ||||
-rw-r--r-- | scripts/blacklist-memory-sanitizer.txt | 1 | ||||
-rw-r--r-- | scripts/blacklist-thread-sanitizer.txt | 0 | ||||
-rwxr-xr-x | scripts/bundle-mac-os.sh | 298 | ||||
-rwxr-xr-x | scripts/create_release_tarball.sh | 65 | ||||
-rwxr-xr-x | scripts/fetch_language_identifiers.py | 129 | ||||
-rwxr-xr-x | scripts/gprof_generate.sh.cmake | 56 | ||||
-rw-r--r-- | scripts/specBytesToCode.py | 69 | ||||
-rw-r--r-- | scripts/test-scard.cpp | 921 | ||||
-rwxr-xr-x | scripts/toolchains_path.py | 49 | ||||
-rwxr-xr-x | scripts/update-windows-zones.py | 41 | ||||
-rwxr-xr-x | scripts/xcode.sh | 74 | ||||
-rwxr-xr-x | scripts/xkb.pl | 303 |
16 files changed, 2389 insertions, 0 deletions
diff --git a/scripts/LECHash.c b/scripts/LECHash.c new file mode 100644 index 0000000..3464fe3 --- /dev/null +++ b/scripts/LECHash.c @@ -0,0 +1,101 @@ +#include <stdio.h> +typedef unsigned short UINT16; + +static UINT16 HuffCodeLEC[] = { + 0x0004, 0x0024, 0x0014, 0x0011, 0x0051, 0x0031, 0x0071, 0x0009, 0x0049, 0x0029, 0x0069, 0x0015, + 0x0095, 0x0055, 0x00d5, 0x0035, 0x00b5, 0x0075, 0x001d, 0x00f5, 0x011d, 0x009d, 0x019d, 0x005d, + 0x000d, 0x008d, 0x015d, 0x00dd, 0x01dd, 0x003d, 0x013d, 0x00bd, 0x004d, 0x01bd, 0x007d, 0x006b, + 0x017d, 0x00fd, 0x01fd, 0x0003, 0x0103, 0x0083, 0x0183, 0x026b, 0x0043, 0x016b, 0x036b, 0x00eb, + 0x0143, 0x00c3, 0x02eb, 0x01c3, 0x01eb, 0x0023, 0x03eb, 0x0123, 0x00a3, 0x01a3, 0x001b, 0x021b, + 0x0063, 0x011b, 0x0163, 0x00e3, 0x00cd, 0x01e3, 0x0013, 0x0113, 0x0093, 0x031b, 0x009b, 0x029b, + 0x0193, 0x0053, 0x019b, 0x039b, 0x005b, 0x025b, 0x015b, 0x035b, 0x0153, 0x00d3, 0x00db, 0x02db, + 0x01db, 0x03db, 0x003b, 0x023b, 0x013b, 0x01d3, 0x033b, 0x00bb, 0x02bb, 0x01bb, 0x03bb, 0x007b, + 0x002d, 0x027b, 0x017b, 0x037b, 0x00fb, 0x02fb, 0x01fb, 0x03fb, 0x0007, 0x0207, 0x0107, 0x0307, + 0x0087, 0x0287, 0x0187, 0x0387, 0x0033, 0x0047, 0x0247, 0x0147, 0x0347, 0x00c7, 0x02c7, 0x01c7, + 0x0133, 0x03c7, 0x0027, 0x0227, 0x0127, 0x0327, 0x00a7, 0x00b3, 0x0019, 0x01b3, 0x0073, 0x02a7, + 0x0173, 0x01a7, 0x03a7, 0x0067, 0x00f3, 0x0267, 0x0167, 0x0367, 0x00e7, 0x02e7, 0x01e7, 0x03e7, + 0x01f3, 0x0017, 0x0217, 0x0117, 0x0317, 0x0097, 0x0297, 0x0197, 0x0397, 0x0057, 0x0257, 0x0157, + 0x0357, 0x00d7, 0x02d7, 0x01d7, 0x03d7, 0x0037, 0x0237, 0x0137, 0x0337, 0x00b7, 0x02b7, 0x01b7, + 0x03b7, 0x0077, 0x0277, 0x07ff, 0x0177, 0x0377, 0x00f7, 0x02f7, 0x01f7, 0x03f7, 0x03ff, 0x000f, + 0x020f, 0x010f, 0x030f, 0x008f, 0x028f, 0x018f, 0x038f, 0x004f, 0x024f, 0x014f, 0x034f, 0x00cf, + 0x000b, 0x02cf, 0x01cf, 0x03cf, 0x002f, 0x022f, 0x010b, 0x012f, 0x032f, 0x00af, 0x02af, 0x01af, + 0x008b, 0x03af, 0x006f, 0x026f, 0x018b, 0x016f, 0x036f, 0x00ef, 0x02ef, 0x01ef, 0x03ef, 0x001f, + 0x021f, 0x011f, 0x031f, 0x009f, 0x029f, 0x019f, 0x039f, 0x005f, 0x004b, 0x025f, 0x015f, 0x035f, + 0x00df, 0x02df, 0x01df, 0x03df, 0x003f, 0x023f, 0x013f, 0x033f, 0x00bf, 0x02bf, 0x014b, 0x01bf, + 0x00ad, 0x00cb, 0x01cb, 0x03bf, 0x002b, 0x007f, 0x027f, 0x017f, 0x012b, 0x037f, 0x00ff, 0x02ff, + 0x00ab, 0x01ab, 0x006d, 0x0059, 0x17ff, 0x0fff, 0x0039, 0x0079, 0x01ff, 0x0005, 0x0045, 0x0034, + 0x000c, 0x002c, 0x001c, 0x0000, 0x003c, 0x0002, 0x0022, 0x0010, 0x0012, 0x0008, 0x0032, 0x000a, + 0x002a, 0x001a, 0x003a, 0x0006, 0x0026, 0x0016, 0x0036, 0x000e, 0x002e, 0x001e, 0x003e, 0x0001, + 0x00ed, 0x0018, 0x0021, 0x0025, 0x0065 +}; + +UINT16 HashTable[512] = { [0 ... 511] = 0xffff }; + +static UINT16 tab[8] = { 511, 0, 508, 448, 494, 347, 486, 482 }; + +UINT16 hash(UINT16 key) +{ + UINT16 h; + h = (key & 0x1ff) ^ (key >> 9) ^ (key >> 4) ^ (key >> 7); + return h; +} + +UINT16 minihash(UINT16 key) +{ + UINT16 h; + h = ((((key >> 8) ^ (key & 0xff)) >> 2) & 0xf); + + if (key >> 9) + h = ~h; + + return (h % 12); +} + +void buildhashtable(void) +{ + for (int i = 0; i < 293; i++) + { + UINT16 h = hash(HuffCodeLEC[i]); + + if (HashTable[h] != 0xffff) + { + HashTable[h] ^= (HuffCodeLEC[i] & 0xfe00) ^ 0xfe00; + HashTable[tab[minihash(HuffCodeLEC[i])]] = i; + } + else + { + HashTable[h] = i; + HashTable[h] ^= 0xfe00; + } + } +} + +UINT16 getvalue(UINT16 huff) +{ + UINT16 h = HashTable[hash(huff)]; + + if ((h ^ huff) >> 9) + return h & 0x1ff; + else + return HashTable[tab[minihash(huff)]]; +} + +main() +{ + buildhashtable(); + printf("static UINT16 HuffIndexLEC[512] = {\n"); + + for (int i = 0; i < 512; i++) + { + if (i == 511) + printf("0x%04" PRIx16 " };\n", HashTable[i]); + else + printf("0x%04" PRIx16 ", ", HashTable[i]); + } + + for (int i = 0; i < 293; i++) + if (i != getvalue(HuffCodeLEC[i])) + printf("Fail :( at %d : 0x%04" PRIx16 "\n", i, HuffCodeLEC[i]); + + return 0; +} diff --git a/scripts/LOMHash.c b/scripts/LOMHash.c new file mode 100644 index 0000000..b3b97c3 --- /dev/null +++ b/scripts/LOMHash.c @@ -0,0 +1,77 @@ +#include <stdio.h> +typedef unsigned short UINT16; +typedef unsigned char BYTE; +static UINT16 HuffCodeLOM[] = { 0x0001, 0x0000, 0x0002, 0x0009, 0x0006, 0x0005, 0x000d, 0x000b, + 0x0003, 0x001b, 0x0007, 0x0017, 0x0037, 0x000f, 0x004f, 0x006f, + 0x002f, 0x00ef, 0x001f, 0x005f, 0x015f, 0x009f, 0x00df, 0x01df, + 0x003f, 0x013f, 0x00bf, 0x01bf, 0x007f, 0x017f, 0x00ff, 0x01ff }; + +UINT16 HashTable[32] = { [0 ... 31] = 0xffff }; + +BYTE tab[4] = { 0, 4, 10, 19 }; + +UINT16 hash(UINT16 key) +{ + return ((key & 0x1f) ^ (key >> 5) ^ (key >> 9)); +} + +BYTE minihash(UINT16 key) +{ + BYTE h; + h = (key >> 4) & 0xf; + return ((h ^ (h >> 2) ^ (h >> 3)) & 0x3); +} + +void buildhashtable(void) +{ + for (int i = 0; i < 32; i++) + { + UINT16 h = hash(HuffCodeLOM[i]); + + if (HashTable[h] != 0xffff) + { + HashTable[h] ^= (HuffCodeLOM[i] & 0xfe0) ^ 0xfe0; + HashTable[tab[minihash(HuffCodeLOM[i])]] = i; + } + else + { + HashTable[h] = i; + HashTable[h] ^= 0xfe0; + } + + printf("at %d %" PRIu16 "=0x%" PRIx16 "\n", i, h, HashTable[h]); + } +} + +BYTE getvalue(UINT16 huff) +{ + UINT16 h = HashTable[hash(huff)]; + + if ((h ^ huff) >> 5) + { + return h & 0x1f; + } + else + return HashTable[tab[minihash(huff)]]; +} + +main() +{ + buildhashtable(); + printf("static UINT16 HuffIndexLOM[32] = {\n"); + + for (int i = 0; i < 32; i++) + { + if (i == 31) + printf("0x%" PRIx16 " };\n", HashTable[i]); + else + printf("0x%" PRIx16 ", ", HashTable[i]); + } + + for (int i = 0; i < 32; i++) + if (i != getvalue(HuffCodeLOM[i])) + printf("Fail :( at %d : 0x%04" PRIx16 " got %" PRIu8 "\n", i, HuffCodeLOM[i], + getvalue(HuffCodeLOM[i])); + + return 0; +} diff --git a/scripts/TimeZones.csx b/scripts/TimeZones.csx new file mode 100644 index 0000000..d0a39ba --- /dev/null +++ b/scripts/TimeZones.csx @@ -0,0 +1,205 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Time Zone Redirection Table Generator + * + * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* Run with ' csi scripts/TimeZones.csx' from freerdp checkout root */ + +using System; +using System.IO; +using System.Globalization; +using System.Collections.ObjectModel; + +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_ENTRY +{ + public string Id; + public Int32 Bias; + public bool SupportsDST; + public string DisplayName; + public string StandardName; + public string DaylightName; + public string RuleTable; + public UInt32 RuleTableCount; +}; + +int i; +UInt32 index; +const string file = @"winpr/libwinpr/timezone/TimeZones.c"; +TimeZoneInfo.AdjustmentRule[] rules; +StreamWriter stream = new StreamWriter(file, false); +ReadOnlyCollection<TimeZoneInfo> timeZones = TimeZoneInfo.GetSystemTimeZones(); + +Console.WriteLine("Updating " + file); +stream.WriteLine("/* "); +stream.WriteLine(" * Automatically generated with scripts/TimeZones.csx"); +stream.WriteLine(" */ "); +stream.WriteLine(); + +stream.WriteLine("#include \"TimeZones.h\""); +stream.WriteLine(); + +index = 0; + +foreach (TimeZoneInfo timeZone in timeZones) +{ + rules = timeZone.GetAdjustmentRules(); + + if ((!timeZone.SupportsDaylightSavingTime) || (rules.Length < 1)) + { + index++; + continue; + } + + 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; + + tzr.TicksStart = rule.DateEnd.ToUniversalTime().Ticks; + tzr.TicksEnd = rule.DateStart.ToUniversalTime().Ticks; + tzr.DaylightDelta = (Int32)rule.DaylightDelta.TotalMinutes; + + 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.Week; + 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; + + tzr.DaylightDate.wYear = (UInt16)0; + tzr.DaylightDate.wMonth = (UInt16)transition.Month; + tzr.DaylightDate.wDayOfWeek = (UInt16)transition.DayOfWeek; + tzr.DaylightDate.wDay = (UInt16)transition.Week; + 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(" { "); + stream.Write("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}", + 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}, {6}, {7}", + 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(" }"); + } + + stream.WriteLine("};"); + stream.WriteLine(); + index++; +} + +index = 0; +stream.WriteLine("const TIME_ZONE_ENTRY TimeZoneTable[] ="); +stream.WriteLine("{"); + +foreach (TimeZoneInfo timeZone in timeZones) +{ + TIME_ZONE_ENTRY tz; + TimeSpan offset = timeZone.BaseUtcOffset; + + rules = timeZone.GetAdjustmentRules(); + + tz.Id = timeZone.Id; + tz.Bias = -(Int32)offset.TotalMinutes; + + tz.SupportsDST = timeZone.SupportsDaylightSavingTime; + + 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; + } + + stream.WriteLine("\t{"); + + stream.WriteLine("\t\t\"{0}\", {1}, {2}, \"{3}\",", + tz.Id, tz.Bias, tz.SupportsDST ? "TRUE" : "FALSE", tz.DisplayName); + + stream.WriteLine("\t\t\"{0}\", \"{1}\",", tz.StandardName, tz.DaylightName); + stream.WriteLine("\t\t{0}, {1}", tz.RuleTable, tz.RuleTableCount); + + index++; + + if ((int)index < timeZones.Count) + stream.WriteLine("\t},"); + else + stream.WriteLine("\t}"); +} +stream.WriteLine("};"); +stream.WriteLine(); +stream.WriteLine("const size_t TimeZoneTableNrElements = ARRAYSIZE(TimeZoneTable);"); +stream.WriteLine(); + +stream.Close(); + diff --git a/scripts/blacklist-address-sanitizer.txt b/scripts/blacklist-address-sanitizer.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/scripts/blacklist-address-sanitizer.txt diff --git a/scripts/blacklist-memory-sanitizer.txt b/scripts/blacklist-memory-sanitizer.txt new file mode 100644 index 0000000..9a05abb --- /dev/null +++ b/scripts/blacklist-memory-sanitizer.txt @@ -0,0 +1 @@ +fun:RAND* diff --git a/scripts/blacklist-thread-sanitizer.txt b/scripts/blacklist-thread-sanitizer.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/scripts/blacklist-thread-sanitizer.txt diff --git a/scripts/bundle-mac-os.sh b/scripts/bundle-mac-os.sh new file mode 100755 index 0000000..8bb1986 --- /dev/null +++ b/scripts/bundle-mac-os.sh @@ -0,0 +1,298 @@ +#!/bin/bash -xe +SCRIPT_PATH="$(dirname -- "${BASH_SOURCE[0]}")" # relative +SCRIPT_PATH="$(cd -- "$SCRIPT_PATH" && pwd)" # absolutized and normalized + +BASE=$(pwd) +SRC="$BASE/src" +BUILD="$BASE/build" +INSTALL="$BASE/install/MacFreeRDP.app/Contents" + +BINDIR=MacOS +LIBDIR=Frameworks +DATADIR=Resources + +DEPLOYMENT_ARCH='arm64 x86_64' +DEPLOYMENT_TARGET=12 + +usage () { + echo "${BASH_SOURCE[0]} [-a|--arch 'arch1 arch2 ...'] [-t|--target target][-h|--help]" + echo "" + echo "default options:" + echo "arch [$DEPLOYMENT_ARCH]" + echo "target [$DEPLOYMENT_TARGET]" +} + +while [[ $# -gt 0 ]]; do + case $1 in + -a|--arch) + DEPLOYMENT_ARCH="$2" + shift # past argument + shift # past value + ;; + -t|--target) + DEPLOYMENT_TARGET="$2" + shift # past argument + shift # past value + ;; + -t|--target) + usage + exit 0 + ;; + -*|--*) + usage + exit 1 + ;; + *) + usage + exit 1 + ;; + esac +done + +fix_rpath() { + SEARCH_PATH=$1 + FIX_PATH=$1 + EXT=".dylib" + if [ "$#" -gt 1 ]; + then + FIX_PATH=$2 + fi + if [ "$#" -gt 2 ]; + then + EXT=$3 + fi + + # some build systems do not handle @rpath on mac os correctly. + # do check that and fix it. + DYLIB_ABS_NAMES=$(find $SEARCH_PATH -type f -name "*$EXT") + for DYLIB_ABS in $DYLIB_ABS_NAMES; + do + DYLIB_NAME=$(basename $DYLIB_ABS) + install_name_tool -id @rpath/$DYLIB_NAME $DYLIB_ABS + + for DYLIB_DEP in $(otool -L $DYLIB_ABS | grep "$FIX_PATH" | cut -d' ' -f1); + do + if [[ $DYLIB_DEP == $DYLIB_ABS ]]; + then + continue + elif [[ $DYLIB_DEP == $FIX_PATH/* ]]; + then + DEP_BASE=$(basename $DYLIB_DEP) + install_name_tool -change $DYLIB_DEP @rpath/$DEP_BASE $DYLIB_ABS + fi + done + done +} + +replace_rpath() { + FILE=$1 + for PTH in $(otool -l $FILE | grep -A2 LC_RPATH | grep path | xargs -J ' ' | cut -d ' ' -f2); + do + install_name_tool -delete_rpath $PTH $FILE + done + install_name_tool -add_rpath @loader_path/../$LIBDIR $FILE +} + +CMAKE_ARCHS= +OSSL_FLAGS="-mmacosx-version-min=$DEPLOYMENT_TARGET" +for ARCH in $DEPLOYMENT_ARCH; +do + OSSL_FLAGS="$OSSL_FLAGS -arch $ARCH" + CMAKE_ARCHS="$ARCH;$CMAKE_ARCHS" +done + +echo "build arch [$DEPLOYMENT_ARCH]" +echo "build target [$DEPLOYMENT_TARGET]" + +CMAKE_ARGS="-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON \ + -DCMAKE_VERBOSE_MAKEFILE=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DWITH_MANPAGES=OFF \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_OSX_ARCHITECTURES=$CMAKE_ARCHS \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=$DEPLOYMENT_TARGET \ + -DCMAKE_INSTALL_PREFIX='$INSTALL' \ + -DCMAKE_INSTALL_LIBDIR='lib' \ + -DCMAKE_INSTALL_BINDIR='bin' \ + -DCMAKE_INSTALL_DATADIR='$DATADIR' \ + -DINSTALL_LIB_DIR='$INSTALL/lib' \ + -DINSTALL_BIN_DIR='$INSTALL/bin' \ + -DCMAKE_PREFIX_PATH='$INSTALL;$INSTALL/lib;$INSTALL/lib/cmake' \ + -DCMAKE_IGNORE_PATH='/opt/local;/usr/local;/opt/homebrew;/Library;~/Library' + " + +if [ ! -d $SRC ]; +then + mkdir -p $SRC + cd $SRC + git clone -b openssl-3.2.0 https://github.com/openssl/openssl.git + git clone --depth 1 -b v1.3 https://github.com/madler/zlib.git + git clone --depth 1 -b uriparser-0.9.7 https://github.com/uriparser/uriparser.git + git clone --depth 1 -b v1.7.16 https://github.com/DaveGamble/cJSON.git + git clone --depth 1 -b release-2.28.1 https://github.com/libsdl-org/SDL.git + git clone --depth 1 --shallow-submodules --recurse-submodules -b release-2.20.2 https://github.com/libsdl-org/SDL_ttf.git + git clone --depth 1 --shallow-submodules --recurse-submodules -b release-2.8.1 https://github.com/libsdl-org/SDL_image.git + git clone --depth 1 --shallow-submodules --recurse-submodules -b v1.0.26 https://github.com/libusb/libusb-cmake.git + git clone --depth 1 -b n6.0 https://github.com/FFmpeg/FFmpeg.git + git clone --depth 1 -b v2.4.0 https://github.com/cisco/openh264.git + git clone --depth 1 -b v1.4 https://gitlab.xiph.org/xiph/opus.git + git clone --depth 1 -b 2.11.1 https://github.com/knik0/faad2.git + git clone --depth 1 -b 1.18.0 https://gitlab.freedesktop.org/cairo/cairo.git + git clone --depth 1 -b 1_30 https://github.com/knik0/faac.git + cd faac + ./bootstrap +fi + +if [ -d $INSTALL ]; +then + rm -rf $INSTALL +fi + +if [ -d $BUILD ]; +then + rm -rf $BUILD +fi + +mkdir -p $BUILD +cd $BUILD + +cmake -GNinja -Bzlib -S$SRC/zlib $CMAKE_ARGS +cmake --build zlib +cmake --install zlib + +cmake -GNinja -Buriparser -S$SRC/uriparser $CMAKE_ARGS -DURIPARSER_BUILD_DOCS=OFF -DURIPARSER_BUILD_TESTS=OFF \ + -DURIPARSER_BUILD_TOOLS=OFF +cmake --build uriparser +cmake --install uriparser + +cmake -GNinja -BcJSON -S$SRC/cJSON $CMAKE_ARGS -DENABLE_CJSON_TEST=OFF -DBUILD_SHARED_AND_STATIC_LIBS=OFF +cmake --build cJSON +cmake --install cJSON + +cmake -GNinja -Bopus -S$SRC/opus $CMAKE_ARGS -DOPUS_BUILD_SHARED_LIBRARY=ON +cmake --build opus +cmake --install opus + +cmake -GNinja -Bfaad2 -S$SRC/faad2 $CMAKE_ARGS +cmake --build faad2 +cmake --install faad2 + +cmake -GNinja -BSDL -S$SRC/SDL $CMAKE_ARGS -DSDL_TEST=OFF -DSDL_TESTS=OFF -DSDL_STATIC_PIC=ON +cmake --build SDL +cmake --install SDL + +cmake -GNinja -BSDL_ttf -S$SRC/SDL_ttf $CMAKE_ARGS -DSDL2TTF_HARFBUZZ=ON -DSDL2TTF_FREETYPE=ON -DSDL2TTF_VENDORED=ON \ + -DFT_DISABLE_ZLIB=OFF -DSDL2TTF_SAMPLES=OFF +cmake --build SDL_ttf +cmake --install SDL_ttf + +cmake -GNinja -BSDL_image -S$SRC/SDL_image $CMAKE_ARGS -DSDL2IMAGE_SAMPLES=OFF -DSDL2IMAGE_DEPS_SHARED=OFF +cmake --build SDL_image +cmake --install SDL_image + +cmake -GNinja -Blibusb-cmake -S$SRC/libusb-cmake $CMAKE_ARGS -DLIBUSB_BUILD_EXAMPLES=OFF -DLIBUSB_BUILD_TESTING=OFF \ + -DLIBUSB_ENABLE_DEBUG_LOGGING=OFF -DLIBUSB_BUILD_SHARED_LIBS=ON +cmake --build libusb-cmake +cmake --install libusb-cmake + +mkdir -p openssl +cd openssl + +CFLAGS=$OSSL_FLAGS LDFLAGS=$OSSL_FLAGS $SRC/openssl/config --prefix=$INSTALL --libdir=lib no-asm no-tests no-docs no-apps zlib +CFLAGS=$OSSL_FLAGS LDFLAGS=$OSSL_FLAGS make -j build_sw +CFLAGS=$OSSL_FLAGS LDFLAGS=$OSSL_FLAGS make -j install_sw + +cd $BUILD +mkdir -p faac +cd faac +# undefine __SSE2__, symbol clashes with universal build +CFLAGS="$OSSL_FLAGS -U__SSE2__" LDFLAGS=$OSSL_FLAGS $SRC/faac/configure --prefix=$INSTALL --libdir="$INSTALL/lib" \ + --enable-shared --disable-static +CFLAGS="$OSSL_FLAGS -U__SSE2__" LDFLAGS=$OSSL_FLAGS make -j +CFLAGS="$OSSL_FLAGS -U__SSE2__" LDFLAGS=$OSSL_FLAGS make -j install + +cd $BUILD + +meson setup --prefix="$INSTALL" -Doptimization=3 -Db_lto=true -Db_pie=true -Dc_args="$OSSL_FLAGS" -Dc_link_args="$OSSL_FLAGS" \ + -Dcpp_args="$OSSL_FLAGS" -Dcpp_link_args="$OSSL_FLAGS" -Dpkgconfig.relocatable=true -Dtests=disabled \ + -Dlibdir=lib openh264 $SRC/openh264 +ninja -C openh264 install + +for ARCH in $DEPLOYMENT_ARCH; +do + mkdir -p $BUILD/FFmpeg/$ARCH + cd $BUILD/FFmpeg/$ARCH + FFCFLAGS="-arch $ARCH -mmacosx-version-min=$DEPLOYMENT_TARGET" + FINSTPATH=$BUILD/FFmpeg/install/$ARCH + CFLAGS=$FFCFLAGS LDFLAGS=$FFCFLAGS $SRC/FFmpeg/configure --prefix=$FINSTPATH --disable-all \ + --enable-shared --disable-static --enable-swscale --disable-asm --disable-libxcb \ + --disable-securetransport --disable-xlib --enable-cross-compile + CFLAGS=$FFCFLAGS LDFLAGS=$FFCFLAGS make -j + CFLAGS=$FFCFLAGS LDFLAGS=$FFCFLAGS make -j install + fix_rpath "$FINSTPATH/lib" +done + +BASE_ARCH="${DEPLOYMENT_ARCH%% *}" + +cd $BUILD/FFmpeg/install/$ARCH +cp -r include/* $INSTALL/include/ +find lib -type l -exec cp -P {} $INSTALL/lib/ \; +BASE_LIBS=$(find lib -type f -name "*.dylib" -exec basename {} \;) + +cd $BUILD/FFmpeg/install +for LIB in $BASE_LIBS; +do + LIBS=$(find . -name $LIB) + lipo $LIBS -output $INSTALL/lib/$LIB -create +done + +cd $BUILD +cmake -GNinja -Bfreerdp -S"$SCRIPT_PATH/.." \ + $CMAKE_ARGS \ + -DWITH_PLATFORM_SERVER=OFF \ + -DWITH_NEON=OFF \ + -DWITH_SSE=OFF \ + -DWITH_FFMPEG=OFF \ + -DWITH_SWSCALE=ON \ + -DWITH_OPUS=ON \ + -DWITH_WEBVIEW=OFF \ + -DWITH_FAAD2=ON \ + -DWITH_FAAC=ON \ + -DWITH_INTERNAL_RC4=ON \ + -DWITH_INTERNAL_MD4=ON \ + -DWITH_INTERNAL_MD5=ON +cmake --build freerdp +cmake --install freerdp + +# remove unused stuff from bin +find "$INSTALL" -name "*.a" -exec rm -f {} \; +find "$INSTALL" -name "*.la" -exec rm -f {} \; +find "$INSTALL" -name sdl2-config -exec rm -f {} \; + +fix_rpath "$INSTALL/lib" +fix_rpath "$INSTALL/bin" "$INSTALL/lib" "" + +# move files in place +cd $INSTALL +mv lib $LIBDIR +mv bin $BINDIR + +# update RPATH +for LIB in $(find $LIBDIR -type f -name "*.dylib"); +do + replace_rpath $LIB +done + +for BIN in $(find $BINDIR -type f); +do + replace_rpath $BIN +done + +# clean up unused data +rm -rf "$INSTALL/include" +rm -rf "$INSTALL/share" +rm -rf "$INSTALL/bin" +rm -rf "$INSTALL/$LIBDIR/cmake" +rm -rf "$INSTALL/$LIBDIR/pkgconfig" + +# TODO: Create remaining files required diff --git a/scripts/create_release_tarball.sh b/scripts/create_release_tarball.sh new file mode 100755 index 0000000..2ad9ca7 --- /dev/null +++ b/scripts/create_release_tarball.sh @@ -0,0 +1,65 @@ +#!/bin/bash -e + +function run { + "$@" + RES=$? + if [[ $RES -ne 0 ]]; + then + echo "[ERROR] $@ returned $RES" >&2 + exit 1 + fi +} + +if [ -z ${TAG:-} ];then + echo "No TAG set - trying to detect" + TAG=$(git describe --tags) + echo "Is the TAG ${TAG} ok (YES|NO)?" + read answ + case "$answ" in + YES): + ;; + *) + echo 'stopping here' + exit 1 + esac +fi + +function create_hash { + NAME=$1 + run md5sum ${NAME} > ${NAME}.md5 + run sha1sum ${NAME} > ${NAME}.sha1 + run sha256sum ${NAME} > ${NAME}.sha256 + run sha512sum ${NAME} > ${NAME}.sha512 +} + +function create_tar { + ARGS=$1 + EXT=$2 + TAG=$3 + + NAME=freerdp-${TAG}${EXT} + run tar $ARGS ${NAME} freerdp-${TAG} + create_hash ${NAME} +} + +TMPDIR=$(mktemp -d -t release-${TAG}-XXXXXXXXXX) + +run git archive --prefix=freerdp-${TAG}/ --format=tar.gz -o ${TMPDIR}/freerdp-${TAG}.tar.gz ${TAG} +run tar xzvf ${TMPDIR}/freerdp-${TAG}.tar.gz -C ${TMPDIR} +run echo ${TAG} > ${TMPDIR}/freerdp-${TAG}/.source_version + +pushd . +cd $TMPDIR +create_tar czf .tar.gz ${TAG} +create_tar cvjSf .tar.bz2 ${TAG} +create_tar cfJ .tar.xz ${TAG} + +ZIPNAME=freerdp-${TAG}.zip +run zip -r ${ZIPNAME} freerdp-${TAG} +create_hash ${ZIPNAME} +popd + +run mv ${TMPDIR}/freerdp-${TAG}.tar* . +run mv ${TMPDIR}/freerdp-${TAG}.zip* . +run rm -rf ${TMPDIR} +exit 0 diff --git a/scripts/fetch_language_identifiers.py b/scripts/fetch_language_identifiers.py new file mode 100755 index 0000000..a6c6adf --- /dev/null +++ b/scripts/fetch_language_identifiers.py @@ -0,0 +1,129 @@ +#!/bin/env python3 +# +# This is a helper script that fetches the current language and keyboard tables +# and writes the result to a C compatible struct. +# +import os +import sys +import requests +import numpy as np +import traceback +from bs4 import BeautifulSoup +from bs4 import element + +intro = '''/* This file is auto generated from + * + * https://docs.microsoft.com/en-us/windows/win32/intl/language-identifier-constants-and-strings + * + * please do not edit but use ./scripts/fetch_language_identifiers.py to regenerate! + */ + +''' + +def parse_html(text): + soup = BeautifulSoup(text, 'html.parser') + table = soup.find("table") + head = table.find('thead').find('tr') + headers = [] + for th in head: + if type(th) == element.Tag: + headers += th + + body = table.find('tbody') + languages = [] + + for tr in body: + if type(tr) == element.Tag: + entry = [] + for th in tr: + if type(th) == element.Tag: + if th.string: + entry += [th.string] + else: + entry += [''] + languages += [entry] + return [headers, languages] + +def is_base(num, base): + try: + v = int(num, base) + return True + except ValueError: + return False + +def padhexa(v): + s = hex(v) + return '0x' + s[2:].zfill(8) + +def write_struct(fp, struct, name, url, base, inv = False, typemap = None): + li = requests.get(url) + if li.status_code != requests.codes.ok: + print('Could not fetch ' + str(url) + ', reponse code ' + str(li.status_code)) + sys.exit(1) + headers, languages = parse_html(li.text) + + fp.write('const ' + str(struct) + ' ' + str(name) + '[] =\n') + fp.write('{\n') + fp.write('/* ') + for h in headers: + fp.write('\t[') + fp.write(h) + fp.write(']\t') + fp.write('*/\n') + last = [None] * 32 + for language in languages: + fp.write('\t{ ') + line = '' + pos = 0 + for e in language: + try: + v = int(e, base=base) + switcher = { + 0: padhexa(v), + 2: bin(v), + 8: oct(v), + 10: str(v), + 16: padhexa(v) + } + h = str(switcher.get(base)) + if h != "None": + last[pos] = h + if inv: + line = h + ', ' + line + else: + line += h + ', ' + except ValueError: + if typemap and typemap[pos] != str: + line += str(last[pos]) + ',\t' + else: + if e == "": + line += '"' + str(last[pos]) + '",\t' + else: + line += '"' + e + '",\t' + if e != "None": + last[pos] = str(e) + pos = pos + 1 + fp.write(line[:-2] + '},\n') + fp.write('};\n') + fp.write('\n') + +def update_lang_identifiers(fp): +# [Language identifier] [Primary language] [Prim. lang. identifier] [Prim. lang. symbol] [Sublanguage] [Sublang. identifier] [Sublang. symbol] + write_struct(fp, 'LanguageIdentifier', 'language_identifiers', 'https://docs.microsoft.com/en-us/windows/win32/intl/language-identifier-constants-and-strings', 16, False, [int, str, int, str, str, int, str]) + +def update_code_pages(fp): + write_struct(fp, 'CodePage', 'code_pages', 'https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers', 10) + +def update_input_locales(fp): + write_struct(fp, 'KeyboardIdentifier', 'keyboard_identifiers', 'https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-vista/cc766503(v=ws.10)', 0) + write_struct(fp, 'RDP_KEYBOARD_LAYOUT', 'RDP_KEYBOARD_LAYOUT_TABLE', 'https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-language-pack-default-values', 16, True) + +try: + with open('language_identifiers.c', 'w') as fp: + fp.write(intro) + update_lang_identifiers(fp) + update_code_pages(fp) + update_input_locales(fp) +except: + print('exception cought') + traceback.print_exc() diff --git a/scripts/gprof_generate.sh.cmake b/scripts/gprof_generate.sh.cmake new file mode 100755 index 0000000..848989f --- /dev/null +++ b/scripts/gprof_generate.sh.cmake @@ -0,0 +1,56 @@ +#!/bin/bash +# +# This script tries to pull gprof profiling information generated by aFreeRDP +# from the target using adb and generating human readable profiling data from +# it. +# +# Any arguments supplied to the script will be appended to adb. +# +# Requirements: +# - ANDROID_SDK is set to the android SDK directory or adb is in path. +# + +if [ -d $ANDROID_SDK ]; then + ADB=$ANDROID_SDK/platform-tools/adb +else + ADB=`which adb` +fi + +GCC=@CMAKE_C_COMPILER@ +GPROF=${GCC/gcc/gprof} +LIB=@PROJECT_BINARY_DIR@/client/Android/FreeRDPCore/jni/armeabi-v7a/libfreerdp-android.so + +if [ ! -f $LIB ]; then + echo "Missing libfreerdp-android.so" + echo "Please build the project first." + exit -1 +fi + +if [ ! -f $GPROF ]; then + echo "gprof could not be found at $GPROF." + echo "Please assure, that you are using a GCC based android toolchain." + exit -2 +fi + +if [ ! -f $ADB ] || [ ! -x $ADB ]; then + echo "adb could not be found." + echo "assure, that either ANDROID_SDK is set to the path of your android SDK" + echo "or that adb is in path." + exit -3 +fi + +# Do the acutal work in a temporary directory. +SRC=`mktemp -d` +cd $SRC +$ADB $@ pull /sdcard/gmon.out +if [ ! -f gmon.out ]; then + echo "Could not pull profiling information from device!" + RC=-4 +else + echo "Pulled profiling information from device, starting conversion..." + $GPROF $LIB -PprofCount -QprofCount -P__gnu_mcount_nc -Q__gnu_mcount_nc + RC=0 +fi +rm -rf $SRC + +exit $RC diff --git a/scripts/specBytesToCode.py b/scripts/specBytesToCode.py new file mode 100644 index 0000000..cee7437 --- /dev/null +++ b/scripts/specBytesToCode.py @@ -0,0 +1,69 @@ +#!/usr/bin/python +# +# A script to convert blob from the MS spec to array of byte to use in unitary tests +# +# 00000000 c7 01 00 01 20 54 e2 +# 00000008 c7 01 00 01 20 54 e2 +# taken from the spec, will give: +# 0xc7, 0x01, 0x00, 0x01, 0x20, 0x54, 0xe2, +# 0xc7, 0x01, 0x00, 0x01, 0x20, 0x54, 0xe2, +# +# Notes: +# * the script reads the two first lines to detect the number of items per lines, so you need a blob with at least 2 lines +# * the script detects if items are hex values by searching for + or - +# +# sample usage: +# $ python scripts/specBytesToCode.py < image.txt > image.c +# then go edit image.c and paste that in your code +import sys + + +def getOffset(l): + token = l.split(' ')[0] + return int(token, 16) + +def isHex(l): + return l.find('+') == -1 and l.find('-') == -1 + +if __name__ == '__main__': + + lines = [] + itemPerLine = 16 + doHex = True + + # parse the offset to know how many items per line we have + l1 = sys.stdin.readline().strip() + l2 = sys.stdin.readline().strip() + itemsPerLine = getOffset(l2) - getOffset(l1) + + # + doHex = isHex(l1) + + for l in [l1, l2] + sys.stdin.readlines(): + # 00000000 c7 01 00 01 20 54 e2 cc 00 jh.kjkjhkhk + l = l.strip() # in case we have spaces before the offset + pos = l.find(' ') + l = l[pos+1:] + items = [] + + tokens = l.strip().split(' ') + ntokens = 0 + for t in tokens: + if not t: # empty token + continue + + if ntokens == itemPerLine: + break + + item = '' + if doHex: + item += '0x' + item += t + + items.append(item) + + ntokens += 1 + + lines.append(', '.join(items)) + + print(",\n".join(lines)) diff --git a/scripts/test-scard.cpp b/scripts/test-scard.cpp new file mode 100644 index 0000000..d22fca9 --- /dev/null +++ b/scripts/test-scard.cpp @@ -0,0 +1,921 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Smartcard API test program + * + * This simple program can be used to trigger calls for (almost) the + * entire SCARD API. + * Compile on windows, connect with FreeRDP via RDP with smartcard + * redirection enabled and run this test program on the windows + * machine. + * + * Copyright 2020 Armin Novak <armin.novak@thincast.com> + * Copyright 2020 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <iostream> +#include <string> +#include <sstream> +#include <locale> +#include <codecvt> + +#include <comdef.h> +#include <winscard.h> + +static const WCHAR* listW[] = { nullptr, L"SCard$AllReaders\000", L"SCard$DefaultReaders\000", + L"SCard$LocalReaders\000", L"SCard$SystemReaders\000" }; +static const char* listA[] = { nullptr, "SCard$AllReaders\000", "SCard$DefaultReaders\000", + "SCard$LocalReaders\000", "SCard$SystemReaders\000" }; + +static std::string scope2str(DWORD scope) +{ + switch (scope) + { + case SCARD_SCOPE_USER: + return "SCARD_SCOPE_USER"; + case SCARD_SCOPE_TERMINAL: + return "SCARD_SCOPE_TERMINAL"; + case SCARD_SCOPE_SYSTEM: + return "SCARD_SCOPE_SYSTEM"; + default: + return "UNKNOWN"; + } +} + +static std::string err2str(LONG code) +{ + switch (code) + { + case ERROR_BROKEN_PIPE: + return "ERROR_BROKEN_PIPE"; + case SCARD_E_BAD_SEEK: + return "SCARD_E_BAD_SEEK"; + case SCARD_E_CANCELLED: + return "SCARD_E_CANCELLED"; + case SCARD_E_CANT_DISPOSE: + return "SCARD_E_CANT_DISPOSE"; + case SCARD_E_CARD_UNSUPPORTED: + return "SCARD_E_CARD_UNSUPPORTED"; + case SCARD_E_CERTIFICATE_UNAVAILABLE: + return "SCARD_E_CERTIFICATE_UNAVAILABLE"; + case SCARD_E_COMM_DATA_LOST: + return "SCARD_E_COMM_DATA_LOST"; + case SCARD_E_DIR_NOT_FOUND: + return "SCARD_E_DIR_NOT_FOUND"; + case SCARD_E_DUPLICATE_READER: + return "SCARD_E_DUPLICATE_READER"; + case SCARD_E_FILE_NOT_FOUND: + return "SCARD_E_FILE_NOT_FOUND"; + case SCARD_E_ICC_CREATEORDER: + return "SCARD_E_ICC_CREATEORDER"; + case SCARD_E_ICC_INSTALLATION: + return "SCARD_E_ICC_INSTALLATION"; + case SCARD_E_INSUFFICIENT_BUFFER: + return "SCARD_E_INSUFFICIENT_BUFFER"; + case SCARD_E_INVALID_ATR: + return "SCARD_E_INVALID_ATR"; + case SCARD_E_INVALID_CHV: + return "SCARD_E_INVALID_CHV"; + case SCARD_E_INVALID_HANDLE: + return "SCARD_E_INVALID_HANDLE"; + case SCARD_E_INVALID_PARAMETER: + return "SCARD_E_INVALID_PARAMETER"; + case SCARD_E_INVALID_TARGET: + return "SCARD_E_INVALID_TARGET"; + case SCARD_E_INVALID_VALUE: + return "SCARD_E_INVALID_VALUE"; + case SCARD_E_NO_ACCESS: + return "SCARD_E_NO_ACCESS"; + case SCARD_E_NO_DIR: + return "SCARD_E_NO_DIR"; + case SCARD_E_NO_FILE: + return "SCARD_E_NO_FILE"; + case SCARD_E_NO_KEY_CONTAINER: + return "SCARD_E_NO_KEY_CONTAINER"; + case SCARD_E_NO_MEMORY: + return "SCARD_E_NO_MEMORY"; + case SCARD_E_NO_PIN_CACHE: + return "SCARD_E_NO_PIN_CACHE"; + case SCARD_E_NO_READERS_AVAILABLE: + return "SCARD_E_NO_READERS_AVAILABLE"; + case SCARD_E_NO_SERVICE: + return "SCARD_E_NO_SERVICE"; + case SCARD_E_NO_SMARTCARD: + return "SCARD_E_NO_SMARTCARD"; + case SCARD_E_NO_SUCH_CERTIFICATE: + return "SCARD_E_NO_SUCH_CERTIFICATE"; + case SCARD_E_NOT_READY: + return "SCARD_E_NOT_READY"; + case SCARD_E_NOT_TRANSACTED: + return "SCARD_E_NOT_TRANSACTED"; + case SCARD_E_PCI_TOO_SMALL: + return "SCARD_E_PCI_TOO_SMALL"; + case SCARD_E_PIN_CACHE_EXPIRED: + return "SCARD_E_PIN_CACHE_EXPIRED"; + case SCARD_E_PROTO_MISMATCH: + return "SCARD_E_PROTO_MISMATCH"; + case SCARD_E_READ_ONLY_CARD: + return "SCARD_E_READ_ONLY_CARD"; + case SCARD_E_READER_UNAVAILABLE: + return "SCARD_E_READER_UNAVAILABLE"; + case SCARD_E_READER_UNSUPPORTED: + return "SCARD_E_READER_UNSUPPORTED"; + case SCARD_E_SERVER_TOO_BUSY: + return "SCARD_E_SERVER_TOO_BUSY"; + case SCARD_E_SERVICE_STOPPED: + return "SCARD_E_SERVICE_STOPPED"; + case SCARD_E_SHARING_VIOLATION: + return "SCARD_E_SHARING_VIOLATION"; + case SCARD_E_SYSTEM_CANCELLED: + return "SCARD_E_SYSTEM_CANCELLED"; + case SCARD_E_TIMEOUT: + return "SCARD_E_TIMEOUT"; + case SCARD_E_UNEXPECTED: + return "SCARD_E_UNEXPECTED"; + case SCARD_E_UNKNOWN_CARD: + return "SCARD_E_UNKNOWN_CARD"; + case SCARD_E_UNKNOWN_READER: + return "SCARD_E_UNKNOWN_READER"; + case SCARD_E_UNKNOWN_RES_MNG: + return "SCARD_E_UNKNOWN_RES_MNG"; + case SCARD_E_UNSUPPORTED_FEATURE: + return "SCARD_E_UNSUPPORTED_FEATURE"; + case SCARD_E_WRITE_TOO_MANY: + return "SCARD_E_WRITE_TOO_MANY"; + case SCARD_F_COMM_ERROR: + return "SCARD_F_COMM_ERROR"; + case SCARD_F_INTERNAL_ERROR: + return "SCARD_F_INTERNAL_ERROR"; + case SCARD_F_UNKNOWN_ERROR: + return "SCARD_F_UNKNOWN_ERROR"; + case SCARD_F_WAITED_TOO_LONG: + return "SCARD_F_WAITED_TOO_LONG"; + case SCARD_P_SHUTDOWN: + return "SCARD_P_SHUTDOWN"; + case SCARD_S_SUCCESS: + return "SCARD_S_SUCCESS"; + case SCARD_W_CANCELLED_BY_USER: + return "SCARD_W_CANCELLED_BY_USER"; + case SCARD_W_CACHE_ITEM_NOT_FOUND: + return "SCARD_W_CACHE_ITEM_NOT_FOUND"; + case SCARD_W_CACHE_ITEM_STALE: + return "SCARD_W_CACHE_ITEM_STALE"; + case SCARD_W_CACHE_ITEM_TOO_BIG: + return "SCARD_W_CACHE_ITEM_TOO_BIG"; + case SCARD_W_CARD_NOT_AUTHENTICATED: + return "SCARD_W_CARD_NOT_AUTHENTICATED"; + case SCARD_W_CHV_BLOCKED: + return "SCARD_W_CHV_BLOCKED"; + case SCARD_W_EOF: + return "SCARD_W_EOF"; + case SCARD_W_REMOVED_CARD: + return "SCARD_W_REMOVED_CARD"; + case SCARD_W_RESET_CARD: + return "SCARD_W_RESET_CARD"; + case SCARD_W_SECURITY_VIOLATION: + return "SCARD_W_SECURITY_VIOLATION"; + case SCARD_W_UNPOWERED_CARD: + return "SCARD_W_UNPOWERED_CARD"; + case SCARD_W_UNRESPONSIVE_CARD: + return "SCARD_W_UNRESPONSIVE_CARD"; + case SCARD_W_UNSUPPORTED_CARD: + return "SCARD_W_UNSUPPORTED_CARD"; + case SCARD_W_WRONG_CHV: + return "SCARD_W_WRONG_CHV"; + default: + return "UNKNOWN"; + } +} + +static std::wstring err2wstr(LONG code) +{ + auto str = err2str(code); + std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; + return converter.from_bytes(str); +} + +#if 0 +static bool test_listreadergroups(SCARDCONTEXT hContext) { + auto rc = SCardListReaderGroupsA(hContext, &groups, &foobar); + rc = SCardListReaderGroupsW(hContext, &groups, &foobar); +} +#endif + +static bool test_valid(SCARDCONTEXT context) +{ + auto rc = SCardIsValidContext(context); + if (rc) + std::cerr << "SCardIsValidContext failed with " << err2str(rc) << std::endl; + return true; +} + +static bool test_list_readers_a(SCARDCONTEXT context) +{ + for (auto cur : listA) + { + LPSTR mszReaders = nullptr; + DWORD chReaders = SCARD_AUTOALLOCATE; + auto rc = SCardListReadersA(context, cur, reinterpret_cast<LPSTR>(&mszReaders), &chReaders); + if (!cur) + { + cur = "NULL"; + } + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardListReadersA [" << cur << "] failed with " << err2str(rc) + << std::endl; + } + else + { + auto start = mszReaders; + auto end = &mszReaders[chReaders]; + + std::cout << "SCardListReadersA [" << cur << "] " << chReaders << " ["; + while (start < end) + { + std::cout << start << ", "; + start += strnlen(start, chReaders) + 2; + } + std::cout << "]" << std::endl; + } + SCardFreeMemory(context, mszReaders); + } + + return true; +} + +static bool test_list_readers_w(SCARDCONTEXT context) +{ + for (auto cur : listW) + { + LPWSTR mszReaders = nullptr; + DWORD chReaders = SCARD_AUTOALLOCATE; + auto rc = + SCardListReadersW(context, cur, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders); + if (!cur) + { + cur = L"NULL"; + } + if (rc != SCARD_S_SUCCESS) + { + std::wcerr << L"SCardListReadersW [" << cur << L"] failed with " << err2wstr(rc) + << std::endl; + } + else + { + auto start = mszReaders; + auto end = &mszReaders[chReaders]; + + std::wcout << L"SCardListReadersW [" << cur << L"] " << chReaders << L" ["; + while (start < end) + { + std::wcout << start << L", "; + start += wcsnlen(start, chReaders) + 2; + } + std::wcout << L"]" << std::endl; + } + SCardFreeMemory(context, mszReaders); + } + + return true; +} + +static bool test_list_reader_groups_a(SCARDCONTEXT context) +{ + LPSTR mszReaders = nullptr; + DWORD chReaders = SCARD_AUTOALLOCATE; + auto rc = SCardListReaderGroupsA(context, reinterpret_cast<LPSTR>(&mszReaders), &chReaders); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardListReaderGroupsA failed with " << err2str(rc) << std::endl; + } + else + { + auto start = mszReaders; + auto end = &mszReaders[chReaders]; + + std::cout << "SCardListReaderGroupsA " << chReaders << " ["; + while (start < end) + { + std::cout << start << ", "; + start += strnlen(start, chReaders) + 2; + } + std::cout << "]" << std::endl; + } + SCardFreeMemory(context, mszReaders); + + return true; +} + +static bool test_list_reader_groups_w(SCARDCONTEXT context) +{ + LPWSTR mszReaders = nullptr; + DWORD chReaders = SCARD_AUTOALLOCATE; + auto rc = SCardListReaderGroupsW(context, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders); + if (rc != SCARD_S_SUCCESS) + { + std::wcerr << L"SCardListReaderGroupsW failed with " << err2wstr(rc) << std::endl; + } + else + { + auto start = mszReaders; + auto end = &mszReaders[chReaders]; + + std::wcout << L"SCardListReaderGroupsW " << chReaders << L" ["; + while (start < end) + { + std::wcout << start << L", "; + start += wcsnlen(start, chReaders) + 2; + } + std::wcout << L"]" << std::endl; + } + SCardFreeMemory(context, mszReaders); + + return true; +} + +static bool test_introduce_forget_reader_groups_a(SCARDCONTEXT context) +{ + LPSTR group = "somefancygroup"; + + auto rc = SCardIntroduceReaderGroupA(context, group); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardIntroduceReaderGroupA failed with " << err2str(rc) << std::endl; + return false; + } + else + { + rc = SCardForgetReaderGroupA(context, group); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardForgetReaderGroupA failed with " << err2str(rc) << std::endl; + return false; + } + return true; + } +} + +static bool test_introduce_forget_reader_groups_w(SCARDCONTEXT context) +{ + LPWSTR group = L"somefancygroup"; + + auto rc = SCardIntroduceReaderGroupW(context, group); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardIntroduceReaderGroupW failed with " << err2str(rc) << std::endl; + return false; + } + else + { + rc = SCardForgetReaderGroupW(context, group); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardForgetReaderGroupW failed with " << err2str(rc) << std::endl; + return false; + } + return true; + } +} + +static bool test_introduce_forget_reader_a(SCARDCONTEXT context) +{ + LPSTR reader = "somefancygroup"; + LPSTR device = "otherfancy"; + + auto rc = SCardIntroduceReaderA(context, reader, device); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardIntroduceReaderA failed with " << err2str(rc) << std::endl; + return false; + } + else + { + rc = SCardForgetReaderA(context, reader); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardForgetReaderA failed with " << err2str(rc) << std::endl; + return false; + } + return true; + } +} + +static bool test_introduce_forget_reader_w(SCARDCONTEXT context) +{ + LPWSTR reader = L"somefancygroup"; + LPWSTR device = L"otherfancy"; + + auto rc = SCardIntroduceReaderW(context, reader, device); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardIntroduceReaderW failed with " << err2str(rc) << std::endl; + return false; + } + else + { + rc = SCardForgetReaderW(context, reader); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardForgetReaderW failed with " << err2str(rc) << std::endl; + return false; + } + return true; + } +} + +static bool test_list_cards_a(SCARDCONTEXT context) +{ + DWORD chCards = SCARD_AUTOALLOCATE; + LPSTR mszCards = nullptr; + auto rc = + SCardListCardsA(context, nullptr, nullptr, 0, reinterpret_cast<LPSTR>(&mszCards), &chCards); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardListCardsA failed with " << err2str(rc) << std::endl; + } + else + { + auto start = mszCards; + auto end = &mszCards[chCards]; + std::cout << "SCardListCardsA " << chCards << " ["; + while (start < end) + { + std::cout << start << ", "; + start += strnlen(start, chCards) + 2; + } + std::cout << "]" << std::endl; + } + return true; +} + +static bool test_list_cards_w(SCARDCONTEXT context) +{ + DWORD chCards = SCARD_AUTOALLOCATE; + LPWSTR mszCards = nullptr; + auto rc = SCardListCardsW(context, nullptr, nullptr, 0, reinterpret_cast<LPWSTR>(&mszCards), + &chCards); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardListCardsW failed with " << err2str(rc) << std::endl; + } + else + { + auto start = mszCards; + auto end = &mszCards[chCards]; + std::cout << "SCardListCardsW " << chCards << " ["; + while (start < end) + { + std::wcout << start << L", "; + start += wcsnlen(start, chCards) + 2; + } + std::cout << "]" << std::endl; + } + return true; +} + +static bool test_cache_a(SCARDCONTEXT context) +{ + BYTE wdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const DWORD wdatalen = sizeof(wdata); + BYTE data[32] = {}; + DWORD datalen = sizeof(data); + LPSTR name = "testdata"; + UUID id = {}; + + auto rc = SCardWriteCacheA(context, &id, 0, name, wdata, wdatalen); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardWriteCacheA failed with " << err2str(rc) << std::endl; + return false; + } + + rc = SCardReadCacheA(context, &id, 0, name, data, &datalen); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardReadCacheA failed with " << err2str(rc) << std::endl; + return false; + } + + if (wdatalen != datalen) + { + std::cerr << "SCardWriteCacheA wrote " << wdatalen << "bytes, SCardReadCacheA read " + << datalen << "bytes" << std::endl; + return false; + } + + if (memcmp(wdata, data, wdatalen) != 0) + { + std::cerr << "SCardWriteCacheA / SCardReadCacheA data corruption detected" << std::endl; + return false; + } + + return true; +} + +static bool test_cache_w(SCARDCONTEXT context) +{ + BYTE wdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const DWORD wdatalen = sizeof(wdata); + BYTE data[32] = {}; + DWORD datalen = sizeof(data); + LPWSTR name = L"testdata"; + UUID id = {}; + + auto rc = SCardWriteCacheW(context, &id, 0, name, wdata, wdatalen); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardWriteCacheW failed with " << err2str(rc) << std::endl; + return false; + } + + rc = SCardReadCacheW(context, &id, 0, name, data, &datalen); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardReadCacheW failed with " << err2str(rc) << std::endl; + return false; + } + + if (wdatalen != datalen) + { + std::cerr << "SCardReadCacheW wrote " << wdatalen << "bytes, SCardReadCacheW read " + << datalen << "bytes" << std::endl; + return false; + } + + if (memcmp(wdata, data, wdatalen) != 0) + { + std::cerr << "SCardReadCacheW / SCardReadCacheW data corruption detected" << std::endl; + return false; + } + + return true; +} + +static bool test_reader_icon_a(SCARDCONTEXT context) +{ + LPSTR name = "Gemalto PC Twin Reader 00 00\0\0"; + LPBYTE pbIcon = nullptr; + DWORD cbIcon = SCARD_AUTOALLOCATE; + + auto rc = SCardGetReaderIconA(context, name, reinterpret_cast<LPBYTE>(&pbIcon), &cbIcon); + SCardFreeMemory(context, pbIcon); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetReaderIconA failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_reader_icon_w(SCARDCONTEXT context) +{ + LPWSTR name = L"Gemalto PC Twin Reader 00 00\0\0"; + LPBYTE pbIcon = nullptr; + DWORD cbIcon = SCARD_AUTOALLOCATE; + + auto rc = SCardGetReaderIconW(context, name, reinterpret_cast<LPBYTE>(&pbIcon), &cbIcon); + SCardFreeMemory(context, pbIcon); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetReaderIconW failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_locate_cards_a(SCARDCONTEXT context) +{ + LPSTR name = "Gemalto PC Twin Reader 00 00\0\0"; + SCARD_READERSTATEA rgReaderStates[16] = {}; + + auto rc = SCardLocateCardsA(context, name, rgReaderStates, ARRAYSIZE(rgReaderStates)); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardLocateCardsA failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_locate_cards_w(SCARDCONTEXT context) +{ + LPWSTR name = L"Gemalto PC Twin Reader 00 00\0\0"; + SCARD_READERSTATEW rgReaderStates[16] = {}; + + auto rc = SCardLocateCardsW(context, name, rgReaderStates, ARRAYSIZE(rgReaderStates)); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardLocateCardsW failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_locate_cards_by_atr_a(SCARDCONTEXT context) +{ + SCARD_READERSTATEA rgReaderStates[16] = {}; + SCARD_ATRMASK rgAtrMasks[16] = {}; + + auto rc = SCardLocateCardsByATRA(context, rgAtrMasks, ARRAYSIZE(rgAtrMasks), rgReaderStates, + ARRAYSIZE(rgReaderStates)); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardLocateCardsByATRA failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_locate_cards_by_atr_w(SCARDCONTEXT context) +{ + SCARD_READERSTATEW rgReaderStates[16] = {}; + SCARD_ATRMASK rgAtrMasks[16] = {}; + + auto rc = SCardLocateCardsByATRW(context, rgAtrMasks, ARRAYSIZE(rgAtrMasks), rgReaderStates, + ARRAYSIZE(rgReaderStates)); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardLocateCardsByATRW failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_devicetype_id_a(SCARDCONTEXT context) +{ + BYTE data[32] = {}; + LPSTR name = "testdata"; + DWORD type; + + auto rc = SCardGetDeviceTypeIdA(context, name, &type); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetDeviceTypeIdA failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_devicetype_id_w(SCARDCONTEXT context) +{ + BYTE data[32] = {}; + LPWSTR name = L"testdata"; + DWORD type; + + auto rc = SCardGetDeviceTypeIdW(context, name, &type); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_transmitcount(SCARDHANDLE handle) +{ + BYTE data[32] = {}; + LPWSTR name = L"testdata"; + DWORD count; + + auto rc = SCardGetTransmitCount(handle, &count); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetTransmitCount failed with " << err2str(rc) << std::endl; + return false; + } + std::cout << "SCardGetTransmitCount() " << count << std::endl; + return true; +} + +static bool test_status_a(SCARDHANDLE handle) +{ + BYTE data[32] = {}; + LPWSTR name = L"testdata"; + DWORD count; + /* + auto rc = SCardStatusA(handle, names, len, &state, &protocol, attr, &attrlen); + if (rc != SCARD_S_SUCCESS) { + std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl; + return false; + } + */ + return true; +} + +static bool test_status_w(SCARDHANDLE handle) +{ + BYTE data[32] = {}; + LPWSTR name = L"testdata"; + DWORD count; + /* + auto rc = SCardStatusA(handle, names, len, &state, &protocol, attr, &attrlen); + if (rc != SCARD_S_SUCCESS) { + std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl; + return false; + } +*/ + return true; +} + +static bool test_get_attrib(SCARDCONTEXT context, SCARDHANDLE handle) +{ + DWORD attrlen = SCARD_AUTOALLOCATE; + LPBYTE attr = nullptr; + + auto rc = + SCardGetAttrib(handle, SCARD_ATTR_ATR_STRING, reinterpret_cast<LPBYTE>(&attr), &attrlen); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetAttrib failed with " << err2str(rc) << std::endl; + return false; + } + std::cout << "SCardGetAttrib [" << attrlen << "]: " << (char*)attr << std::endl; + SCardFreeMemory(context, attr); + + return true; +} + +static bool test_set_attrib(SCARDCONTEXT context, SCARDHANDLE handle) +{ + DWORD attrlen = SCARD_AUTOALLOCATE; + BYTE attr[] = "0123456789"; + + auto rc = SCardSetAttrib(handle, SCARD_ATTR_SUPRESS_T1_IFS_REQUEST, attr, ARRAYSIZE(attr)); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardSetAttrib failed with " << err2str(rc) << std::endl; + return false; + } + std::cout << "SCardSetAttrib [" << attrlen << "]: " << (char*)attr << std::endl; + SCardFreeMemory(context, attr); + + return true; +} + +int main() +{ + std::cout << "Hello World!" << std::endl; + try + { + auto scopes = { SCARD_SCOPE_USER, SCARD_SCOPE_SYSTEM }; + for (auto scope : scopes) + { + SCARDCONTEXT context; + auto rc = SCardEstablishContext(scope, nullptr, nullptr, &context); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardEstablishContext [" << scope2str(scope) << "] failed with " + << err2str(rc) << std::endl; + } + else + { + std::cerr << "SCardEstablishContext [" << scope2str(scope) << "] success" + << std::endl; + + test_valid(context); + + test_list_reader_groups_a(context); + test_list_reader_groups_w(context); + + test_list_readers_a(context); + test_list_readers_w(context); + + test_list_cards_a(context); + test_list_cards_w(context); + + test_introduce_forget_reader_groups_a(context); + test_introduce_forget_reader_groups_w(context); + + test_introduce_forget_reader_a(context); + test_introduce_forget_reader_w(context); + + // TODO: Introduce/Remove reader to group + test_locate_cards_a(context); + test_locate_cards_w(context); + + test_locate_cards_by_atr_a(context); + test_locate_cards_by_atr_w(context); + + test_cache_a(context); + test_cache_w(context); + + test_reader_icon_a(context); + test_reader_icon_w(context); + + test_devicetype_id_a(context); + test_devicetype_id_w(context); + + // TODO: statuschange + // TODO: begin/end transaction + // TODO: state + // TODO: transmit + // TODO: control + + { + DWORD protocol; + SCARDHANDLE handle = 0; + LPSTR mszReaders; + DWORD chReaders = SCARD_AUTOALLOCATE; + + LONG status = SCardListReadersA( + context, nullptr, reinterpret_cast<LPSTR>(&mszReaders), &chReaders); + if (status == SCARD_S_SUCCESS) + status = SCardConnectA(context, mszReaders, SCARD_SHARE_SHARED, + SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 | + SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW, + &handle, &protocol); + SCardFreeMemory(context, mszReaders); + if (status != SCARD_S_SUCCESS) + { + std::cerr << "SCardConnectA [" + << "] failed with " << err2str(status) << std::endl; + } + else + { + test_status_a(handle); + test_status_w(handle); + test_get_attrib(context, handle); + test_set_attrib(context, handle); + test_transmitcount(handle); + + status = SCardDisconnect(handle, 0); + if (status) + { + std::cerr << "SCardDisconnect [" + << "] failed with " << err2str(status) << std::endl; + } + } + } + { + DWORD protocol; + SCARDHANDLE handle = 0; + LPWSTR mszReaders; + DWORD chReaders = SCARD_AUTOALLOCATE; + + LONG status = SCardListReadersW( + context, nullptr, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders); + if (status == SCARD_S_SUCCESS) + status = SCardConnectW(context, mszReaders, SCARD_SHARE_SHARED, + SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 | + SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW, + &handle, &protocol); + SCardFreeMemory(context, mszReaders); + + if (status != SCARD_S_SUCCESS) + { + std::cerr << "SCardConnectW [" + << "] failed with " << err2str(status) << std::endl; + } + else + { + test_status_a(handle); + test_status_w(handle); + test_get_attrib(context, handle); + test_set_attrib(context, handle); + test_transmitcount(handle); + + status = SCardDisconnect(handle, 0); + if (status) + { + std::cerr << "SCardDisconnect [" + << "] failed with " << err2str(status) << std::endl; + } + } + } + + rc = SCardReleaseContext(context); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardReleaseContext [" << scope2str(scope) << "] failed with " + << err2str(rc) << std::endl; + } + } + } + } + catch (...) + { + std::cerr << "exception!!!!" << std::endl; + } + + return 0; +} diff --git a/scripts/toolchains_path.py b/scripts/toolchains_path.py new file mode 100755 index 0000000..a85158a --- /dev/null +++ b/scripts/toolchains_path.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +""" + Get the toolchains path + https://proandroiddev.com/tutorial-compile-openssl-to-1-1-1-for-android-application-87137968fee +""" +import argparse +import atexit +import inspect +import os +import shutil +import stat +import sys +import textwrap + +def get_host_tag_or_die(): + """Return the host tag for this platform. Die if not supported.""" + if sys.platform.startswith('linux'): + return 'linux-x86_64' + elif sys.platform == 'darwin': + return 'darwin-x86_64' + elif sys.platform == 'win32' or sys.platform == 'cygwin': + host_tag = 'windows-x86_64' + if not os.path.exists(os.path.join(NDK_DIR, 'prebuilt', host_tag)): + host_tag = 'windows' + return host_tag + sys.exit('Unsupported platform: ' + sys.platform) + + +def get_toolchain_path_or_die(ndk, host_tag): + """Return the toolchain path or die.""" + toolchain_path = os.path.join(ndk, 'toolchains/llvm/prebuilt', + host_tag, 'bin') + if not os.path.exists(toolchain_path): + sys.exit('Could not find toolchain: {}'.format(toolchain_path)) + return toolchain_path + +def main(): + """Program entry point.""" + parser = argparse.ArgumentParser(description='Optional app description') + parser.add_argument('--ndk', required=True, + help='The NDK Home directory') + args = parser.parse_args() + + host_tag = get_host_tag_or_die() + toolchain_path = get_toolchain_path_or_die(args.ndk, host_tag) + print(toolchain_path) + +if __name__ == '__main__': + main() diff --git a/scripts/update-windows-zones.py b/scripts/update-windows-zones.py new file mode 100755 index 0000000..49b96e6 --- /dev/null +++ b/scripts/update-windows-zones.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +import os +import urllib.request +import xml.etree.ElementTree as ET + +name = os.path.realpath(__file__) +base = os.path.normpath(os.path.join(os.path.dirname(name), '..')) +rname = os.path.relpath(name, base) +zfile = os.path.join(base, 'winpr/libwinpr/timezone/WindowsZones.c') +url = 'https://raw.githubusercontent.com/unicode-org/cldr/latest/common/supplemental/windowsZones.xml' + +try: + with urllib.request.urlopen(url) as response: + xml = response.read() + root = ET.fromstring(xml) + entries = [] + for child in root.iter('mapZone'): + tzid = child.get('type') + windows = child.get('other') + entries += ['\t{ "' + windows + '", "' + tzid + '" },\n'] + entries.sort() + + with open(zfile, 'w') as f: + f.write('/*\n') + f.write(' * Automatically generated with ' + str(rname) + '\n') + f.write(' */\n') + f.write('\n') + f.write('#include "WindowsZones.h"\n') + f.write('\n') + f.write('const WINDOWS_TZID_ENTRY WindowsTimeZoneIdTable[] =\n') + f.write('{\n') + for entry in entries: + f.write(entry) + f.write('};\n') + f.write('\n'); + f.write('const size_t WindowsTimeZoneIdTableNrElements = ARRAYSIZE(WindowsTimeZoneIdTable);\n') +except Exception as e: + print('----------------------------------------------------') + print(str(e)) + print('----------------------------------------------------') diff --git a/scripts/xcode.sh b/scripts/xcode.sh new file mode 100755 index 0000000..f86faa9 --- /dev/null +++ b/scripts/xcode.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# may now be legacy; 2 stage cmake no longer needed + +# 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 diff --git a/scripts/xkb.pl b/scripts/xkb.pl new file mode 100755 index 0000000..976ee3b --- /dev/null +++ b/scripts/xkb.pl @@ -0,0 +1,303 @@ +#!/usr/bin/perl + +# FreeRDP: A Remote Desktop Protocol Implementation +# XKB database conversion script + +# Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Description: +# Script to export XKB configuration files to keycode -> virtual key code keymaps that are +# easy to use in FreeRDP. This makes keymap maintenance easier to make as all bugs can +# simply be reported to the XKB Configuration Database project, and then this script can +# be used to export newer (and fixed) version of the XKB Configuration Database. + +use Cwd; + +my %sym2virt = ( + "AE00" => "VK_TILDE", + "AE01" => "VK_KEY_1", + "AE02" => "VK_KEY_2", + "AE03" => "VK_KEY_3", + "AE04" => "VK_KEY_4", + "AE05" => "VK_KEY_5", + "AE06" => "VK_KEY_6", + "AE07" => "VK_KEY_7", + "AE08" => "VK_KEY_8", + "AE09" => "VK_KEY_9", + "AE10" => "VK_KEY_0", + "AE11" => "VK_OEM_MINUS", + "AE12" => "VK_OEM_PLUS", + + "AD01" => "VK_KEY_Q", + "AD02" => "VK_KEY_W", + "AD03" => "VK_KEY_E", + "AD04" => "VK_KEY_R", + "AD05" => "VK_KEY_T", + "AD06" => "VK_KEY_Y", + "AD07" => "VK_KEY_U", + "AD08" => "VK_KEY_I", + "AD09" => "VK_KEY_O", + "AD10" => "VK_KEY_P", + "AD11" => "VK_OEM_4", + "AD12" => "VK_OEM_6", + + "AC01" => "VK_KEY_A", + "AC02" => "VK_KEY_S", + "AC03" => "VK_KEY_D", + "AC04" => "VK_KEY_F", + "AC05" => "VK_KEY_G", + "AC06" => "VK_KEY_H", + "AC07" => "VK_KEY_J", + "AC08" => "VK_KEY_K", + "AC09" => "VK_KEY_L", + "AC10" => "VK_OEM_1", + "AC11" => "VK_OEM_7", + "AC12" => "VK_OEM_5", + + "AB00" => "VK_LSHIFT", + "AB01" => "VK_KEY_Z", + "AB02" => "VK_KEY_X", + "AB03" => "VK_KEY_C", + "AB04" => "VK_KEY_V", + "AB05" => "VK_KEY_B", + "AB06" => "VK_KEY_N", + "AB07" => "VK_KEY_M", + "AB08" => "VK_OEM_COMMA", + "AB09" => "VK_OEM_PERIOD", + "AB10" => "VK_OEM_2", + "AB11" => "VK_ABNT_C1", + + "FK01" => "VK_F1", + "FK02" => "VK_F2", + "FK03" => "VK_F3", + "FK04" => "VK_F4", + "FK05" => "VK_F5", + "FK06" => "VK_F6", + "FK07" => "VK_F7", + "FK08" => "VK_F8", + "FK09" => "VK_F9", + "FK10" => "VK_F10", + "FK11" => "VK_F11", + "FK12" => "VK_F12", + "FK13" => "VK_F13", + "FK14" => "VK_F14", + "FK15" => "VK_F15", + "FK16" => "VK_F16", + "FK17" => "VK_F17", + "FK18" => "VK_F18", + "FK19" => "VK_F19", + "FK20" => "VK_F20", + "FK21" => "VK_F21", + "FK22" => "VK_F22", + "FK23" => "VK_F23", + "FK24" => "VK_F24", + + "KP0" => "VK_NUMPAD0", + "KP1" => "VK_NUMPAD1", + "KP2" => "VK_NUMPAD2", + "KP3" => "VK_NUMPAD3", + "KP4" => "VK_NUMPAD4", + "KP5" => "VK_NUMPAD5", + "KP6" => "VK_NUMPAD6", + "KP7" => "VK_NUMPAD7", + "KP8" => "VK_NUMPAD8", + "KP9" => "VK_NUMPAD9", + + "KPDV" => "VK_DIVIDE", + "KPMU" => "VK_MULTIPLY", + "KPSU" => "VK_SUBTRACT", + "KPAD" => "VK_ADD", + "KPDL" => "VK_DECIMAL", + "KPEN" => "VK_RETURN", + + "RTRN" => "VK_RETURN", + "SPCE" => "VK_SPACE", + "BKSP" => "VK_BACK", + "BKSL" => "VK_OEM_5", + "LSGT" => "VK_OEM_102", + "ESC" => "VK_ESCAPE", + "TLDE" => "VK_OEM_3", + "CAPS" => "VK_CAPITAL", + "TAB" => "VK_TAB", + "LFSH" => "VK_LSHIFT", + "RTSH" => "VK_RSHIFT", + "LCTL" => "VK_LCONTROL", + "RCTL" => "VK_RCONTROL", + "LWIN" => "VK_LWIN", + "RWIN" => "VK_RWIN", + "LALT" => "VK_LMENU", + "RALT" => "VK_RMENU", + "COMP" => "VK_APPS", + "MENU" => "VK_APPS", + "UP" => "VK_UP", + "DOWN" => "VK_DOWN", + "LEFT" => "VK_LEFT", + "RGHT" => "VK_RIGHT", + "INS" => "VK_INSERT", + "DELE" => "VK_DELETE", + "PGUP" => "VK_PRIOR", + "PGDN" => "VK_NEXT", + "HOME" => "VK_HOME", + "END" => "VK_END", + "PAUS" => "VK_PAUSE", + "NMLK" => "VK_NUMLOCK", + "SCLK" => "VK_SCROLL", + + # This page helps understanding the keys that follow: + # http://www.stanford.edu/class/cs140/projects/pintos/specs/kbd/scancodes-7.html + + "KANJ" => "VK_KANJI", + "HANJ" => "VK_HANJA", + "MUHE" => "VK_NONCONVERT", + "HIRA" => "VK_KANA", + "PRSC" => "VK_SNAPSHOT", + + "KPF1" => "VK_NUMLOCK", + "KPF2" => "VK_DIVIDE", + "KPF3" => "VK_MULTIPLY", + "KPF4" => "VK_SUBTRACT", + "KPCO" => "VK_ADD", + + "HELP" => "VK_HELP", + "SELE" => "VK_SELECT", + + # We can ignore LDM (Lock Down Modifier) + # What are LCMP/RCMP? + # DO, FIND? + +); + +my $inDir; +my $outDir; + +if(@ARGV < 1) { + $inDir = getcwd() . "/"; + $outDir = $inDir; +} elsif(@ARGV == 1) { + $inDir = $ARGV[0]; + $outDir = getcwd() . "/"; +} elsif(@ARGV == 2) { + $inDir = $ARGV[0]; + $outDir = $ARGV[1]; +} else { + print "Error: Too many arguments\n" . + "Usage:\n" . + "perl xkb.pl <XKB Directory>\n" . + "perl xkb.pl <XKB Directory> <Output Directory>\n\n" . + "In Linux, the XKB directory usually is /usr/share/X11/xkb/\n" . + "The latest version of XKB can always be downloaded at:\n" . + "http://freedesktop.org/wiki/Software/XKeyboardConfig\n"; + exit 0; +} + + + +open("SPEC", $inDir . "xkeyboard-config.spec"); + +$xkbVersion = ""; +while($line = <SPEC>) { + if($line =~ m/Version:\s+(.\..)/) { + $xkbVersion = "version $1"; + } +} + +# Create directory if it does not exists +if(not -e $outDir) { + mkdir $outDir or die("Error: Can't create directory $outDir\n"); +} + +open("KCD", $inDir . "keycodes/keycodes.dir") or die("Error: Can't open $inDir" . "keycodes/keycodes.dir\n"); + +$previousFile = ""; +while($line = <KCD>) { + if($line =~ m/........ -------- (.+)\((.+)\)/) { + if($1 ne $previousFile) { + push(@keymapFiles, $1); + $previousFile = $1; + } + } +} +close("KCD"); + +foreach $keymapFile (@keymapFiles) { + + print "File $keymapFile:\n"; + + @directories = split(/\//, $keymapFile); + splice(@directories, @directories - 1, 1); + + if(@directories > 0) { + $directory = $outDir; + for($i = 0; $i < @directories; $i++) { + $directory .= $directories[$i] . "/"; + if(not -e $directory) { + mkdir $directory or die("Can't create directory $directory\n"); + } + } + } + + open("IN", $inDir . "keycodes/" . $keymapFile); + open("OUT", ">" . "$outDir" . $keymapFile); + + print OUT "# This file was generated with xkb.pl\n"; + print OUT "# and is based on the X Keyboard Configuration Database $xkbVersion\n"; + print OUT "# Please use xkb.pl to re-export newer versions of XKB\n"; + print OUT "\n\n"; + + while($line = <IN>) { + if($line =~ m/xkb_keycodes \"(\w+)\"/) { + + print "Exporting \"$1\"\n"; + print OUT "keyboard \"$1\""; + + + while($line = <IN>) { + if($line =~ m/include\W+\"(.+)\"/) { + print OUT "\n: extends \"$1\""; + last; + } else { + last; + } + } + print OUT "\n{\n"; + + while($line = <IN>) { + if($line =~ m/<(\w{1,4})>\W+=\W+(\w+);/) { + if($sym2virt{$1} ne undef) { + $vkcode = $sym2virt{$1}; + print OUT "\t$vkcode"; + + if(length($vkcode) < 8) { + print OUT "\t"; + } + print OUT "\t<$2>\n"; + } else { + # If undef, then this symbolic key code is + # missing from the sym2virt hash table + # print "\t$1\t$2\n"; + } + } elsif($line =~ m/};/) { + print OUT "};\n\n"; + last; + } + } + } + } + + close("IN"); + close("OUT"); +} + |