diff --git a/.gitignore b/.gitignore index 93fab928b..9eae137ec 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,10 @@ _CPack_Packages *.cproject *.settings +# .rdp files +*.rdp +*.RDP + # Documentation docs/api client/X11/xfreerdp.1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 28f501edb..503d7458f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,9 +63,12 @@ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() -# Default to build shared libs if(NOT DEFINED BUILD_SHARED_LIBS) - set(BUILD_SHARED_LIBS ON) + if(ANDROID) + set(BUILD_SHARED_LIBS OFF) + else() + set(BUILD_SHARED_LIBS ON) + endif() endif() if(NOT DEFINED EXPORT_ALL_SYMBOLS) @@ -182,9 +185,8 @@ endif() if(NOT WIN32) find_required_package(ZLIB) - find_optional_package(PulseAudio) - find_optional_package(MacAudio) find_optional_package(PCSC) + find_optional_package(PulseAudio) if(NOT ANDROID) find_suggested_package(Cups) @@ -198,7 +200,7 @@ if(NOT WIN32) endif() endif() - if(NOT ANDROID) + if((NOT ANDROID) AND (NOT APPLE)) find_suggested_package(FFmpeg) endif() endif() diff --git a/build/winpr/libwinpr/asn1/test/TestAsn1.c b/build/winpr/libwinpr/asn1/test/TestAsn1.c deleted file mode 100644 index 059f434f9..000000000 --- a/build/winpr/libwinpr/asn1/test/TestAsn1.c +++ /dev/null @@ -1,215 +0,0 @@ -#include -#include -#include -#include - - - - -/* Forward declare test functions. */ -int TestAsn1Module(int, char*[]); -int TestAsn1Encoder(int, char*[]); -int TestAsn1Decoder(int, char*[]); -int TestAsn1Encode(int, char*[]); -int TestAsn1Decode(int, char*[]); -int TestAsn1String(int, char*[]); -int TestAsn1Integer(int, char*[]); -int TestAsn1Compare(int, char*[]); -int TestAsn1BerEnc(int, char*[]); -int TestAsn1BerDec(int, char*[]); -int TestAsn1DerEnc(int, char*[]); -int TestAsn1DerDec(int, char*[]); - - -/* Create map. */ - -typedef int (*MainFuncPointer)(int , char*[]); -typedef struct -{ - const char* name; - MainFuncPointer func; -} functionMapEntry; - -functionMapEntry cmakeGeneratedFunctionMapEntries[] = { - { - "TestAsn1Module", - TestAsn1Module - }, - { - "TestAsn1Encoder", - TestAsn1Encoder - }, - { - "TestAsn1Decoder", - TestAsn1Decoder - }, - { - "TestAsn1Encode", - TestAsn1Encode - }, - { - "TestAsn1Decode", - TestAsn1Decode - }, - { - "TestAsn1String", - TestAsn1String - }, - { - "TestAsn1Integer", - TestAsn1Integer - }, - { - "TestAsn1Compare", - TestAsn1Compare - }, - { - "TestAsn1BerEnc", - TestAsn1BerEnc - }, - { - "TestAsn1BerDec", - TestAsn1BerDec - }, - { - "TestAsn1DerEnc", - TestAsn1DerEnc - }, - { - "TestAsn1DerDec", - TestAsn1DerDec - }, - - {0,0} -}; - -/* Allocate and create a lowercased copy of string - (note that it has to be free'd manually) */ - -char* lowercase(const char *string) -{ - char *new_string, *p; - -#ifdef __cplusplus - new_string = static_cast(malloc(sizeof(char) * - static_cast(strlen(string) + 1))); -#else - new_string = (char *)(malloc(sizeof(char) * (size_t)(strlen(string) + 1))); -#endif - - if (!new_string) - { - return 0; - } - strcpy(new_string, string); - p = new_string; - while (*p != 0) - { -#ifdef __cplusplus - *p = static_cast(tolower(*p)); -#else - *p = (char)(tolower(*p)); -#endif - - ++p; - } - return new_string; -} - -int main(int ac, char *av[]) -{ - int i, NumTests, testNum, partial_match; - char *arg, *test_name; - int count; - int testToRun = -1; - - - - for(count =0; cmakeGeneratedFunctionMapEntries[count].name != 0; count++) - { - } - NumTests = count; - /* If no test name was given */ - /* process command line with user function. */ - if (ac < 2) - { - /* Ask for a test. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("To run a test, enter the test number: "); - fflush(stdout); - testNum = 0; - if( scanf("%d", &testNum) != 1 ) - { - printf("Couldn't parse that input as a number\n"); - return -1; - } - if (testNum >= NumTests) - { - printf("%3d is an invalid test number.\n", testNum); - return -1; - } - testToRun = testNum; - ac--; - av++; - } - partial_match = 0; - arg = 0; - /* If partial match is requested. */ - if(testToRun == -1 && ac > 1) - { - partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; - } - if (partial_match && ac < 3) - { - printf("-R needs an additional parameter.\n"); - return -1; - } - if(testToRun == -1) - { - arg = lowercase(av[1 + partial_match]); - } - for (i =0; i < NumTests && testToRun == -1; ++i) - { - test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name); - if (partial_match && strstr(test_name, arg) != NULL) - { - testToRun = i; - ac -=2; - av += 2; - } - else if (!partial_match && strcmp(test_name, arg) == 0) - { - testToRun = i; - ac--; - av++; - } - free(test_name); - } - if(arg) - { - free(arg); - } - if(testToRun != -1) - { - int result; - - result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av); - - return result; - } - - - /* Nothing was run, display the test names. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("Failed: %s is an invalid test name.\n", av[1]); - - return -1; -} diff --git a/build/winpr/libwinpr/crt/test/TestCrt.c b/build/winpr/libwinpr/crt/test/TestCrt.c deleted file mode 100644 index 9cf4f6ddd..000000000 --- a/build/winpr/libwinpr/crt/test/TestCrt.c +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include -#include - - - - -/* Forward declare test functions. */ -int TestAlignment(int, char*[]); - - -/* Create map. */ - -typedef int (*MainFuncPointer)(int , char*[]); -typedef struct -{ - const char* name; - MainFuncPointer func; -} functionMapEntry; - -functionMapEntry cmakeGeneratedFunctionMapEntries[] = { - { - "TestAlignment", - TestAlignment - }, - - {0,0} -}; - -/* Allocate and create a lowercased copy of string - (note that it has to be free'd manually) */ - -char* lowercase(const char *string) -{ - char *new_string, *p; - -#ifdef __cplusplus - new_string = static_cast(malloc(sizeof(char) * - static_cast(strlen(string) + 1))); -#else - new_string = (char *)(malloc(sizeof(char) * (size_t)(strlen(string) + 1))); -#endif - - if (!new_string) - { - return 0; - } - strcpy(new_string, string); - p = new_string; - while (*p != 0) - { -#ifdef __cplusplus - *p = static_cast(tolower(*p)); -#else - *p = (char)(tolower(*p)); -#endif - - ++p; - } - return new_string; -} - -int main(int ac, char *av[]) -{ - int i, NumTests, testNum, partial_match; - char *arg, *test_name; - int count; - int testToRun = -1; - - - - for(count =0; cmakeGeneratedFunctionMapEntries[count].name != 0; count++) - { - } - NumTests = count; - /* If no test name was given */ - /* process command line with user function. */ - if (ac < 2) - { - /* Ask for a test. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("To run a test, enter the test number: "); - fflush(stdout); - testNum = 0; - if( scanf("%d", &testNum) != 1 ) - { - printf("Couldn't parse that input as a number\n"); - return -1; - } - if (testNum >= NumTests) - { - printf("%3d is an invalid test number.\n", testNum); - return -1; - } - testToRun = testNum; - ac--; - av++; - } - partial_match = 0; - arg = 0; - /* If partial match is requested. */ - if(testToRun == -1 && ac > 1) - { - partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; - } - if (partial_match && ac < 3) - { - printf("-R needs an additional parameter.\n"); - return -1; - } - if(testToRun == -1) - { - arg = lowercase(av[1 + partial_match]); - } - for (i =0; i < NumTests && testToRun == -1; ++i) - { - test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name); - if (partial_match && strstr(test_name, arg) != NULL) - { - testToRun = i; - ac -=2; - av += 2; - } - else if (!partial_match && strcmp(test_name, arg) == 0) - { - testToRun = i; - ac--; - av++; - } - free(test_name); - } - if(arg) - { - free(arg); - } - if(testToRun != -1) - { - int result; - - result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av); - - return result; - } - - - /* Nothing was run, display the test names. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("Failed: %s is an invalid test name.\n", av[1]); - - return -1; -} diff --git a/build/winpr/libwinpr/file/test/TestFile.c b/build/winpr/libwinpr/file/test/TestFile.c deleted file mode 100644 index fad18b274..000000000 --- a/build/winpr/libwinpr/file/test/TestFile.c +++ /dev/null @@ -1,190 +0,0 @@ -#include -#include -#include -#include - - - - -/* Forward declare test functions. */ -int TestFileCreateFile(int, char*[]); -int TestFileDeleteFile(int, char*[]); -int TestFileReadFile(int, char*[]); -int TestFileWriteFile(int, char*[]); -int TestFileFindFirstFile(int, char*[]); -int TestFileFindFirstFileEx(int, char*[]); -int TestFileFindNextFile(int, char*[]); - - -/* Create map. */ - -typedef int (*MainFuncPointer)(int , char*[]); -typedef struct -{ - const char* name; - MainFuncPointer func; -} functionMapEntry; - -functionMapEntry cmakeGeneratedFunctionMapEntries[] = { - { - "TestFileCreateFile", - TestFileCreateFile - }, - { - "TestFileDeleteFile", - TestFileDeleteFile - }, - { - "TestFileReadFile", - TestFileReadFile - }, - { - "TestFileWriteFile", - TestFileWriteFile - }, - { - "TestFileFindFirstFile", - TestFileFindFirstFile - }, - { - "TestFileFindFirstFileEx", - TestFileFindFirstFileEx - }, - { - "TestFileFindNextFile", - TestFileFindNextFile - }, - - {0,0} -}; - -/* Allocate and create a lowercased copy of string - (note that it has to be free'd manually) */ - -char* lowercase(const char *string) -{ - char *new_string, *p; - -#ifdef __cplusplus - new_string = static_cast(malloc(sizeof(char) * - static_cast(strlen(string) + 1))); -#else - new_string = (char *)(malloc(sizeof(char) * (size_t)(strlen(string) + 1))); -#endif - - if (!new_string) - { - return 0; - } - strcpy(new_string, string); - p = new_string; - while (*p != 0) - { -#ifdef __cplusplus - *p = static_cast(tolower(*p)); -#else - *p = (char)(tolower(*p)); -#endif - - ++p; - } - return new_string; -} - -int main(int ac, char *av[]) -{ - int i, NumTests, testNum, partial_match; - char *arg, *test_name; - int count; - int testToRun = -1; - - - - for(count =0; cmakeGeneratedFunctionMapEntries[count].name != 0; count++) - { - } - NumTests = count; - /* If no test name was given */ - /* process command line with user function. */ - if (ac < 2) - { - /* Ask for a test. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("To run a test, enter the test number: "); - fflush(stdout); - testNum = 0; - if( scanf("%d", &testNum) != 1 ) - { - printf("Couldn't parse that input as a number\n"); - return -1; - } - if (testNum >= NumTests) - { - printf("%3d is an invalid test number.\n", testNum); - return -1; - } - testToRun = testNum; - ac--; - av++; - } - partial_match = 0; - arg = 0; - /* If partial match is requested. */ - if(testToRun == -1 && ac > 1) - { - partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; - } - if (partial_match && ac < 3) - { - printf("-R needs an additional parameter.\n"); - return -1; - } - if(testToRun == -1) - { - arg = lowercase(av[1 + partial_match]); - } - for (i =0; i < NumTests && testToRun == -1; ++i) - { - test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name); - if (partial_match && strstr(test_name, arg) != NULL) - { - testToRun = i; - ac -=2; - av += 2; - } - else if (!partial_match && strcmp(test_name, arg) == 0) - { - testToRun = i; - ac--; - av++; - } - free(test_name); - } - if(arg) - { - free(arg); - } - if(testToRun != -1) - { - int result; - - result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av); - - return result; - } - - - /* Nothing was run, display the test names. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("Failed: %s is an invalid test name.\n", av[1]); - - return -1; -} diff --git a/build/winpr/libwinpr/interlocked/test/TestInterlocked.c b/build/winpr/libwinpr/interlocked/test/TestInterlocked.c deleted file mode 100644 index e9fcf5718..000000000 --- a/build/winpr/libwinpr/interlocked/test/TestInterlocked.c +++ /dev/null @@ -1,170 +0,0 @@ -#include -#include -#include -#include - - - - -/* Forward declare test functions. */ -int TestInterlockedAccess(int, char*[]); -int TestInterlockedSList(int, char*[]); -int TestInterlockedDList(int, char*[]); - - -/* Create map. */ - -typedef int (*MainFuncPointer)(int , char*[]); -typedef struct -{ - const char* name; - MainFuncPointer func; -} functionMapEntry; - -functionMapEntry cmakeGeneratedFunctionMapEntries[] = { - { - "TestInterlockedAccess", - TestInterlockedAccess - }, - { - "TestInterlockedSList", - TestInterlockedSList - }, - { - "TestInterlockedDList", - TestInterlockedDList - }, - - {0,0} -}; - -/* Allocate and create a lowercased copy of string - (note that it has to be free'd manually) */ - -char* lowercase(const char *string) -{ - char *new_string, *p; - -#ifdef __cplusplus - new_string = static_cast(malloc(sizeof(char) * - static_cast(strlen(string) + 1))); -#else - new_string = (char *)(malloc(sizeof(char) * (size_t)(strlen(string) + 1))); -#endif - - if (!new_string) - { - return 0; - } - strcpy(new_string, string); - p = new_string; - while (*p != 0) - { -#ifdef __cplusplus - *p = static_cast(tolower(*p)); -#else - *p = (char)(tolower(*p)); -#endif - - ++p; - } - return new_string; -} - -int main(int ac, char *av[]) -{ - int i, NumTests, testNum, partial_match; - char *arg, *test_name; - int count; - int testToRun = -1; - - - - for(count =0; cmakeGeneratedFunctionMapEntries[count].name != 0; count++) - { - } - NumTests = count; - /* If no test name was given */ - /* process command line with user function. */ - if (ac < 2) - { - /* Ask for a test. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("To run a test, enter the test number: "); - fflush(stdout); - testNum = 0; - if( scanf("%d", &testNum) != 1 ) - { - printf("Couldn't parse that input as a number\n"); - return -1; - } - if (testNum >= NumTests) - { - printf("%3d is an invalid test number.\n", testNum); - return -1; - } - testToRun = testNum; - ac--; - av++; - } - partial_match = 0; - arg = 0; - /* If partial match is requested. */ - if(testToRun == -1 && ac > 1) - { - partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; - } - if (partial_match && ac < 3) - { - printf("-R needs an additional parameter.\n"); - return -1; - } - if(testToRun == -1) - { - arg = lowercase(av[1 + partial_match]); - } - for (i =0; i < NumTests && testToRun == -1; ++i) - { - test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name); - if (partial_match && strstr(test_name, arg) != NULL) - { - testToRun = i; - ac -=2; - av += 2; - } - else if (!partial_match && strcmp(test_name, arg) == 0) - { - testToRun = i; - ac--; - av++; - } - free(test_name); - } - if(arg) - { - free(arg); - } - if(testToRun != -1) - { - int result; - - result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av); - - return result; - } - - - /* Nothing was run, display the test names. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("Failed: %s is an invalid test name.\n", av[1]); - - return -1; -} diff --git a/build/winpr/libwinpr/library/test/TestLibrary.c b/build/winpr/libwinpr/library/test/TestLibrary.c deleted file mode 100644 index e3997c967..000000000 --- a/build/winpr/libwinpr/library/test/TestLibrary.c +++ /dev/null @@ -1,185 +0,0 @@ -#include -#include -#include -#include - - - - -/* Forward declare test functions. */ -int TestLibraryAddDllDirectory(int, char*[]); -int TestLibraryRemoveDllDirectory(int, char*[]); -int TestLibrarySetDefaultDllDirectories(int, char*[]); -int TestLibraryLoadLibrary(int, char*[]); -int TestLibraryFreeLibrary(int, char*[]); -int TestLibraryGetProcAddress(int, char*[]); - - -/* Create map. */ - -typedef int (*MainFuncPointer)(int , char*[]); -typedef struct -{ - const char* name; - MainFuncPointer func; -} functionMapEntry; - -functionMapEntry cmakeGeneratedFunctionMapEntries[] = { - { - "TestLibraryAddDllDirectory", - TestLibraryAddDllDirectory - }, - { - "TestLibraryRemoveDllDirectory", - TestLibraryRemoveDllDirectory - }, - { - "TestLibrarySetDefaultDllDirectories", - TestLibrarySetDefaultDllDirectories - }, - { - "TestLibraryLoadLibrary", - TestLibraryLoadLibrary - }, - { - "TestLibraryFreeLibrary", - TestLibraryFreeLibrary - }, - { - "TestLibraryGetProcAddress", - TestLibraryGetProcAddress - }, - - {0,0} -}; - -/* Allocate and create a lowercased copy of string - (note that it has to be free'd manually) */ - -char* lowercase(const char *string) -{ - char *new_string, *p; - -#ifdef __cplusplus - new_string = static_cast(malloc(sizeof(char) * - static_cast(strlen(string) + 1))); -#else - new_string = (char *)(malloc(sizeof(char) * (size_t)(strlen(string) + 1))); -#endif - - if (!new_string) - { - return 0; - } - strcpy(new_string, string); - p = new_string; - while (*p != 0) - { -#ifdef __cplusplus - *p = static_cast(tolower(*p)); -#else - *p = (char)(tolower(*p)); -#endif - - ++p; - } - return new_string; -} - -int main(int ac, char *av[]) -{ - int i, NumTests, testNum, partial_match; - char *arg, *test_name; - int count; - int testToRun = -1; - - - - for(count =0; cmakeGeneratedFunctionMapEntries[count].name != 0; count++) - { - } - NumTests = count; - /* If no test name was given */ - /* process command line with user function. */ - if (ac < 2) - { - /* Ask for a test. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("To run a test, enter the test number: "); - fflush(stdout); - testNum = 0; - if( scanf("%d", &testNum) != 1 ) - { - printf("Couldn't parse that input as a number\n"); - return -1; - } - if (testNum >= NumTests) - { - printf("%3d is an invalid test number.\n", testNum); - return -1; - } - testToRun = testNum; - ac--; - av++; - } - partial_match = 0; - arg = 0; - /* If partial match is requested. */ - if(testToRun == -1 && ac > 1) - { - partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; - } - if (partial_match && ac < 3) - { - printf("-R needs an additional parameter.\n"); - return -1; - } - if(testToRun == -1) - { - arg = lowercase(av[1 + partial_match]); - } - for (i =0; i < NumTests && testToRun == -1; ++i) - { - test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name); - if (partial_match && strstr(test_name, arg) != NULL) - { - testToRun = i; - ac -=2; - av += 2; - } - else if (!partial_match && strcmp(test_name, arg) == 0) - { - testToRun = i; - ac--; - av++; - } - free(test_name); - } - if(arg) - { - free(arg); - } - if(testToRun != -1) - { - int result; - - result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av); - - return result; - } - - - /* Nothing was run, display the test names. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("Failed: %s is an invalid test name.\n", av[1]); - - return -1; -} diff --git a/build/winpr/libwinpr/path/test/TestPath.c b/build/winpr/libwinpr/path/test/TestPath.c deleted file mode 100644 index e7db8fa95..000000000 --- a/build/winpr/libwinpr/path/test/TestPath.c +++ /dev/null @@ -1,265 +0,0 @@ -#include -#include -#include -#include - - - - -/* Forward declare test functions. */ -int TestPathCchAddBackslash(int, char*[]); -int TestPathCchRemoveBackslash(int, char*[]); -int TestPathCchAddBackslashEx(int, char*[]); -int TestPathCchRemoveBackslashEx(int, char*[]); -int TestPathCchAddExtension(int, char*[]); -int TestPathCchAppend(int, char*[]); -int TestPathCchAppendEx(int, char*[]); -int TestPathCchCanonicalize(int, char*[]); -int TestPathCchCanonicalizeEx(int, char*[]); -int TestPathAllocCanonicalize(int, char*[]); -int TestPathCchCombine(int, char*[]); -int TestPathCchCombineEx(int, char*[]); -int TestPathAllocCombine(int, char*[]); -int TestPathCchFindExtension(int, char*[]); -int TestPathCchRenameExtension(int, char*[]); -int TestPathCchRemoveExtension(int, char*[]); -int TestPathCchIsRoot(int, char*[]); -int TestPathIsUNCEx(int, char*[]); -int TestPathCchSkipRoot(int, char*[]); -int TestPathCchStripToRoot(int, char*[]); -int TestPathCchStripPrefix(int, char*[]); -int TestPathCchRemoveFileSpec(int, char*[]); - - -/* Create map. */ - -typedef int (*MainFuncPointer)(int , char*[]); -typedef struct -{ - const char* name; - MainFuncPointer func; -} functionMapEntry; - -functionMapEntry cmakeGeneratedFunctionMapEntries[] = { - { - "TestPathCchAddBackslash", - TestPathCchAddBackslash - }, - { - "TestPathCchRemoveBackslash", - TestPathCchRemoveBackslash - }, - { - "TestPathCchAddBackslashEx", - TestPathCchAddBackslashEx - }, - { - "TestPathCchRemoveBackslashEx", - TestPathCchRemoveBackslashEx - }, - { - "TestPathCchAddExtension", - TestPathCchAddExtension - }, - { - "TestPathCchAppend", - TestPathCchAppend - }, - { - "TestPathCchAppendEx", - TestPathCchAppendEx - }, - { - "TestPathCchCanonicalize", - TestPathCchCanonicalize - }, - { - "TestPathCchCanonicalizeEx", - TestPathCchCanonicalizeEx - }, - { - "TestPathAllocCanonicalize", - TestPathAllocCanonicalize - }, - { - "TestPathCchCombine", - TestPathCchCombine - }, - { - "TestPathCchCombineEx", - TestPathCchCombineEx - }, - { - "TestPathAllocCombine", - TestPathAllocCombine - }, - { - "TestPathCchFindExtension", - TestPathCchFindExtension - }, - { - "TestPathCchRenameExtension", - TestPathCchRenameExtension - }, - { - "TestPathCchRemoveExtension", - TestPathCchRemoveExtension - }, - { - "TestPathCchIsRoot", - TestPathCchIsRoot - }, - { - "TestPathIsUNCEx", - TestPathIsUNCEx - }, - { - "TestPathCchSkipRoot", - TestPathCchSkipRoot - }, - { - "TestPathCchStripToRoot", - TestPathCchStripToRoot - }, - { - "TestPathCchStripPrefix", - TestPathCchStripPrefix - }, - { - "TestPathCchRemoveFileSpec", - TestPathCchRemoveFileSpec - }, - - {0,0} -}; - -/* Allocate and create a lowercased copy of string - (note that it has to be free'd manually) */ - -char* lowercase(const char *string) -{ - char *new_string, *p; - -#ifdef __cplusplus - new_string = static_cast(malloc(sizeof(char) * - static_cast(strlen(string) + 1))); -#else - new_string = (char *)(malloc(sizeof(char) * (size_t)(strlen(string) + 1))); -#endif - - if (!new_string) - { - return 0; - } - strcpy(new_string, string); - p = new_string; - while (*p != 0) - { -#ifdef __cplusplus - *p = static_cast(tolower(*p)); -#else - *p = (char)(tolower(*p)); -#endif - - ++p; - } - return new_string; -} - -int main(int ac, char *av[]) -{ - int i, NumTests, testNum, partial_match; - char *arg, *test_name; - int count; - int testToRun = -1; - - - - for(count =0; cmakeGeneratedFunctionMapEntries[count].name != 0; count++) - { - } - NumTests = count; - /* If no test name was given */ - /* process command line with user function. */ - if (ac < 2) - { - /* Ask for a test. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("To run a test, enter the test number: "); - fflush(stdout); - testNum = 0; - if( scanf("%d", &testNum) != 1 ) - { - printf("Couldn't parse that input as a number\n"); - return -1; - } - if (testNum >= NumTests) - { - printf("%3d is an invalid test number.\n", testNum); - return -1; - } - testToRun = testNum; - ac--; - av++; - } - partial_match = 0; - arg = 0; - /* If partial match is requested. */ - if(testToRun == -1 && ac > 1) - { - partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; - } - if (partial_match && ac < 3) - { - printf("-R needs an additional parameter.\n"); - return -1; - } - if(testToRun == -1) - { - arg = lowercase(av[1 + partial_match]); - } - for (i =0; i < NumTests && testToRun == -1; ++i) - { - test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name); - if (partial_match && strstr(test_name, arg) != NULL) - { - testToRun = i; - ac -=2; - av += 2; - } - else if (!partial_match && strcmp(test_name, arg) == 0) - { - testToRun = i; - ac--; - av++; - } - free(test_name); - } - if(arg) - { - free(arg); - } - if(testToRun != -1) - { - int result; - - result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av); - - return result; - } - - - /* Nothing was run, display the test names. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("Failed: %s is an invalid test name.\n", av[1]); - - return -1; -} diff --git a/build/winpr/libwinpr/pipe/test/TestPipe.c b/build/winpr/libwinpr/pipe/test/TestPipe.c deleted file mode 100644 index 861e9d400..000000000 --- a/build/winpr/libwinpr/pipe/test/TestPipe.c +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include -#include - - - - -/* Forward declare test functions. */ -int TestPipeCreatePipe(int, char*[]); - - -/* Create map. */ - -typedef int (*MainFuncPointer)(int , char*[]); -typedef struct -{ - const char* name; - MainFuncPointer func; -} functionMapEntry; - -functionMapEntry cmakeGeneratedFunctionMapEntries[] = { - { - "TestPipeCreatePipe", - TestPipeCreatePipe - }, - - {0,0} -}; - -/* Allocate and create a lowercased copy of string - (note that it has to be free'd manually) */ - -char* lowercase(const char *string) -{ - char *new_string, *p; - -#ifdef __cplusplus - new_string = static_cast(malloc(sizeof(char) * - static_cast(strlen(string) + 1))); -#else - new_string = (char *)(malloc(sizeof(char) * (size_t)(strlen(string) + 1))); -#endif - - if (!new_string) - { - return 0; - } - strcpy(new_string, string); - p = new_string; - while (*p != 0) - { -#ifdef __cplusplus - *p = static_cast(tolower(*p)); -#else - *p = (char)(tolower(*p)); -#endif - - ++p; - } - return new_string; -} - -int main(int ac, char *av[]) -{ - int i, NumTests, testNum, partial_match; - char *arg, *test_name; - int count; - int testToRun = -1; - - - - for(count =0; cmakeGeneratedFunctionMapEntries[count].name != 0; count++) - { - } - NumTests = count; - /* If no test name was given */ - /* process command line with user function. */ - if (ac < 2) - { - /* Ask for a test. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("To run a test, enter the test number: "); - fflush(stdout); - testNum = 0; - if( scanf("%d", &testNum) != 1 ) - { - printf("Couldn't parse that input as a number\n"); - return -1; - } - if (testNum >= NumTests) - { - printf("%3d is an invalid test number.\n", testNum); - return -1; - } - testToRun = testNum; - ac--; - av++; - } - partial_match = 0; - arg = 0; - /* If partial match is requested. */ - if(testToRun == -1 && ac > 1) - { - partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; - } - if (partial_match && ac < 3) - { - printf("-R needs an additional parameter.\n"); - return -1; - } - if(testToRun == -1) - { - arg = lowercase(av[1 + partial_match]); - } - for (i =0; i < NumTests && testToRun == -1; ++i) - { - test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name); - if (partial_match && strstr(test_name, arg) != NULL) - { - testToRun = i; - ac -=2; - av += 2; - } - else if (!partial_match && strcmp(test_name, arg) == 0) - { - testToRun = i; - ac--; - av++; - } - free(test_name); - } - if(arg) - { - free(arg); - } - if(testToRun != -1) - { - int result; - - result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av); - - return result; - } - - - /* Nothing was run, display the test names. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("Failed: %s is an invalid test name.\n", av[1]); - - return -1; -} diff --git a/build/winpr/libwinpr/sspi/test/TestSspi.c b/build/winpr/libwinpr/sspi/test/TestSspi.c deleted file mode 100644 index 273d8b952..000000000 --- a/build/winpr/libwinpr/sspi/test/TestSspi.c +++ /dev/null @@ -1,175 +0,0 @@ -#include -#include -#include -#include - - - - -/* Forward declare test functions. */ -int TestQuerySecurityPackageInfo(int, char*[]); -int TestEnumerateSecurityPackages(int, char*[]); -int TestInitializeSecurityContext(int, char*[]); -int TestAcquireCredentialsHandle(int, char*[]); - - -/* Create map. */ - -typedef int (*MainFuncPointer)(int , char*[]); -typedef struct -{ - const char* name; - MainFuncPointer func; -} functionMapEntry; - -functionMapEntry cmakeGeneratedFunctionMapEntries[] = { - { - "TestQuerySecurityPackageInfo", - TestQuerySecurityPackageInfo - }, - { - "TestEnumerateSecurityPackages", - TestEnumerateSecurityPackages - }, - { - "TestInitializeSecurityContext", - TestInitializeSecurityContext - }, - { - "TestAcquireCredentialsHandle", - TestAcquireCredentialsHandle - }, - - {0,0} -}; - -/* Allocate and create a lowercased copy of string - (note that it has to be free'd manually) */ - -char* lowercase(const char *string) -{ - char *new_string, *p; - -#ifdef __cplusplus - new_string = static_cast(malloc(sizeof(char) * - static_cast(strlen(string) + 1))); -#else - new_string = (char *)(malloc(sizeof(char) * (size_t)(strlen(string) + 1))); -#endif - - if (!new_string) - { - return 0; - } - strcpy(new_string, string); - p = new_string; - while (*p != 0) - { -#ifdef __cplusplus - *p = static_cast(tolower(*p)); -#else - *p = (char)(tolower(*p)); -#endif - - ++p; - } - return new_string; -} - -int main(int ac, char *av[]) -{ - int i, NumTests, testNum, partial_match; - char *arg, *test_name; - int count; - int testToRun = -1; - - - - for(count =0; cmakeGeneratedFunctionMapEntries[count].name != 0; count++) - { - } - NumTests = count; - /* If no test name was given */ - /* process command line with user function. */ - if (ac < 2) - { - /* Ask for a test. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("To run a test, enter the test number: "); - fflush(stdout); - testNum = 0; - if( scanf("%d", &testNum) != 1 ) - { - printf("Couldn't parse that input as a number\n"); - return -1; - } - if (testNum >= NumTests) - { - printf("%3d is an invalid test number.\n", testNum); - return -1; - } - testToRun = testNum; - ac--; - av++; - } - partial_match = 0; - arg = 0; - /* If partial match is requested. */ - if(testToRun == -1 && ac > 1) - { - partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; - } - if (partial_match && ac < 3) - { - printf("-R needs an additional parameter.\n"); - return -1; - } - if(testToRun == -1) - { - arg = lowercase(av[1 + partial_match]); - } - for (i =0; i < NumTests && testToRun == -1; ++i) - { - test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name); - if (partial_match && strstr(test_name, arg) != NULL) - { - testToRun = i; - ac -=2; - av += 2; - } - else if (!partial_match && strcmp(test_name, arg) == 0) - { - testToRun = i; - ac--; - av++; - } - free(test_name); - } - if(arg) - { - free(arg); - } - if(testToRun != -1) - { - int result; - - result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av); - - return result; - } - - - /* Nothing was run, display the test names. */ - printf("Available tests:\n"); - for (i =0; i < NumTests; ++i) - { - printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name); - } - printf("Failed: %s is an invalid test name.\n", av[1]); - - return -1; -} diff --git a/channels/CMakeLists.txt b/channels/CMakeLists.txt index 102161138..6eebd5436 100644 --- a/channels/CMakeLists.txt +++ b/channels/CMakeLists.txt @@ -18,6 +18,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) include(CMakeParseArguments) +include(CMakeDependentOption) macro(define_channel_options) set(PREFIX "CHANNEL") @@ -38,8 +39,18 @@ macro(define_channel_client_options _channel_client_default) string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT" CHANNEL_CLIENT_OPTION) set(CHANNEL_CLIENT_OPTION_DOC "Build ${CHANNEL_NAME} ${CHANNEL_TYPE} channel client") option(${CHANNEL_CLIENT_OPTION} "${CHANNEL_CLIENT_OPTION_DOC}" ${_channel_client_default}) + cmake_dependent_option(${CHANNEL_CLIENT_OPTION} "${CHANNEL_CLIENT_OPTION_DOC}" + ${_channel_client_default} "${CHANNEL_OPTION}" OFF) endmacro(define_channel_client_options) +macro(define_channel_server_options _channel_server_default) + string(TOUPPER "CHANNEL_${CHANNEL_NAME}_SERVER" CHANNEL_SERVER_OPTION) + set(CHANNEL_SERVER_OPTION_DOC "Build ${CHANNEL_NAME} ${CHANNEL_TYPE} channel server") + option(${CHANNEL_SERVER_OPTION} "${CHANNEL_SERVER_OPTION_DOC}" ${_channel_server_default}) + cmake_dependent_option(${CHANNEL_SERVER_OPTION} "${CHANNEL_SERVER_OPTION_DOC}" + ${_channel_server_default} "${CHANNEL_OPTION}" OFF) +endmacro(define_channel_server_options) + macro(define_channel _channel_name) set(CHANNEL_NAME ${_channel_name}) set(MODULE_NAME ${CHANNEL_NAME}) @@ -81,7 +92,7 @@ endmacro(define_channel_server_subsystem) macro(add_channel_client _channel_prefix _channel_name) add_subdirectory(client) - if(${_channel_prefix}_CLIENT_STATIC) + if(${${_channel_prefix}_CLIENT_STATIC}) set(CHANNEL_STATIC_CLIENT_MODULES ${CHANNEL_STATIC_CLIENT_MODULES} ${_channel_prefix} PARENT_SCOPE) set(${_channel_prefix}_CLIENT_NAME ${${_channel_prefix}_CLIENT_NAME} PARENT_SCOPE) set(${_channel_prefix}_CLIENT_CHANNEL ${${_channel_prefix}_CLIENT_CHANNEL} PARENT_SCOPE) @@ -92,7 +103,7 @@ endmacro(add_channel_client) macro(add_channel_server _channel_prefix _channel_name) add_subdirectory(server) - if(${_channel_prefix}_SERVER_STATIC) + if(${${_channel_prefix}_SERVER_STATIC}) set(CHANNEL_STATIC_SERVER_MODULES ${CHANNEL_STATIC_SERVER_MODULES} ${_channel_prefix} PARENT_SCOPE) set(${_channel_prefix}_SERVER_NAME ${${_channel_prefix}_SERVER_NAME} PARENT_SCOPE) set(${_channel_prefix}_SERVER_CHANNEL ${${_channel_prefix}_SERVER_CHANNEL} PARENT_SCOPE) @@ -103,11 +114,11 @@ endmacro(add_channel_server) macro(add_channel_client_library _module_prefix _module_name _channel_name _plugin _entry) - if(_plugin AND MSVC AND (NOT STATIC_CHANNELS)) + if(${_plugin} AND MSVC AND (NOT STATIC_CHANNELS)) set(${_module_prefix}_SRCS ${${_module_prefix}_SRCS} module.def) endif() - if(_plugin AND (NOT STATIC_CHANNELS)) + if(${_plugin} AND (NOT STATIC_CHANNELS)) add_library(${_module_name} ${${_module_prefix}_SRCS}) else() set(${_module_prefix}_STATIC ON PARENT_SCOPE) @@ -121,11 +132,11 @@ endmacro(add_channel_client_library) macro(add_channel_server_library _module_prefix _module_name _channel_name _plugin _entry) - if(_plugin AND MSVC AND (NOT STATIC_CHANNELS)) + if(${_plugin} AND MSVC AND (NOT STATIC_CHANNELS)) set(${_module_prefix}_SRCS ${${_module_prefix}_SRCS} module.def) endif() - if(_plugin AND (NOT STATIC_CHANNELS)) + if(${_plugin} AND (NOT STATIC_CHANNELS)) add_library(${_module_name} ${${_module_prefix}_SRCS}) else() set(${_module_prefix}_STATIC ON PARENT_SCOPE) @@ -146,7 +157,16 @@ foreach(FILEPATH ${FILEPATHS}) set(CHANNEL_OPTION) include(${FILEPATH}) if(${CHANNEL_OPTION}) - message(STATUS "Adding ${CHANNEL_TYPE} channel \"${CHANNEL_NAME}\": ${CHANNEL_DESCRIPTION}") + set(CHANNEL_MESSAGE "Adding ${CHANNEL_TYPE} channel") + if(${CHANNEL_CLIENT_OPTION}) + set(CHANNEL_MESSAGE "${CHANNEL_MESSAGE} client") + endif() + if(${CHANNEL_SERVER_OPTION}) + set(CHANNEL_MESSAGE "${CHANNEL_MESSAGE} server") + endif() + set(CHANNEL_MESSAGE "${CHANNEL_MESSAGE} \"${CHANNEL_NAME}\"") + set(CHANNEL_MESSAGE "${CHANNEL_MESSAGE}: ${CHANNEL_DESCRIPTION}") + message(STATUS "${CHANNEL_MESSAGE}") add_subdirectory(${DIR}) endif() endif() diff --git a/channels/audin/ChannelOptions.cmake b/channels/audin/ChannelOptions.cmake index 8e0a9fbcb..662f53559 100644 --- a/channels/audin/ChannelOptions.cmake +++ b/channels/audin/ChannelOptions.cmake @@ -1,8 +1,21 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT ON) + +if(ANDROID) + set(OPTION_CLIENT_DEFAULT OFF) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) +endif() define_channel_options(NAME "audin" TYPE "dynamic" DESCRIPTION "Audio Input Redirection Virtual Channel Extension" SPECIFICATIONS "[MS-RDPEAI]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) diff --git a/channels/cliprdr/ChannelOptions.cmake b/channels/cliprdr/ChannelOptions.cmake index f4ad8a0b9..fed6d4da5 100644 --- a/channels/cliprdr/ChannelOptions.cmake +++ b/channels/cliprdr/ChannelOptions.cmake @@ -1,8 +1,17 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT OFF) + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) +endif() define_channel_options(NAME "cliprdr" TYPE "static" DESCRIPTION "Clipboard Virtual Channel Extension" SPECIFICATIONS "[MS-RDPECLIP]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/disk/ChannelOptions.cmake b/channels/disk/ChannelOptions.cmake index de9fe0062..47df3a81b 100644 --- a/channels/disk/ChannelOptions.cmake +++ b/channels/disk/ChannelOptions.cmake @@ -1,8 +1,15 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT OFF) if(ANDROID) - set(OPTION_DEFAULT OFF) + set(OPTION_CLIENT_DEFAULT OFF) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) endif() define_channel_options(NAME "disk" TYPE "device" @@ -10,3 +17,6 @@ define_channel_options(NAME "disk" TYPE "device" SPECIFICATIONS "[MS-RDPEFS]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/drdynvc/ChannelOptions.cmake b/channels/drdynvc/ChannelOptions.cmake index 243b2e15d..5212b1a51 100644 --- a/channels/drdynvc/ChannelOptions.cmake +++ b/channels/drdynvc/ChannelOptions.cmake @@ -1,8 +1,17 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT OFF) + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) +endif() define_channel_options(NAME "drdynvc" TYPE "static" DESCRIPTION "Dynamic Virtual Channel Extension" SPECIFICATIONS "[MS-RDPEDYC]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/parallel/ChannelOptions.cmake b/channels/parallel/ChannelOptions.cmake index 23d692663..7864540a6 100644 --- a/channels/parallel/ChannelOptions.cmake +++ b/channels/parallel/ChannelOptions.cmake @@ -1,8 +1,20 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT OFF) if(WIN32) - set(OPTION_DEFAULT OFF) + set(OPTION_CLIENT_DEFAULT OFF) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(ANDROID) + set(OPTION_CLIENT_DEFAULT OFF) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) endif() define_channel_options(NAME "parallel" TYPE "device" @@ -10,3 +22,6 @@ define_channel_options(NAME "parallel" TYPE "device" SPECIFICATIONS "[MS-RDPESP]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/printer/ChannelOptions.cmake b/channels/printer/ChannelOptions.cmake index 808322084..13f680892 100644 --- a/channels/printer/ChannelOptions.cmake +++ b/channels/printer/ChannelOptions.cmake @@ -1,12 +1,21 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT OFF) if(WIN32) - set(OPTION_DEFAULT ON) + set(OPTION_CLIENT_DEFAULT ON) + set(OPTION_SERVER_DEFAULT OFF) elseif(WITH_CUPS) - set(OPTION_DEFAULT ON) + set(OPTION_CLIENT_DEFAULT ON) + set(OPTION_SERVER_DEFAULT OFF) else() - set(OPTION_DEFAULT OFF) + set(OPTION_CLIENT_DEFAULT OFF) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) endif() define_channel_options(NAME "printer" TYPE "device" @@ -14,3 +23,6 @@ define_channel_options(NAME "printer" TYPE "device" SPECIFICATIONS "[MS-RDPEPC]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/rail/ChannelOptions.cmake b/channels/rail/ChannelOptions.cmake index 5df7a64a8..5332e9990 100644 --- a/channels/rail/ChannelOptions.cmake +++ b/channels/rail/ChannelOptions.cmake @@ -1,8 +1,17 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT OFF) + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) +endif() define_channel_options(NAME "rail" TYPE "static" DESCRIPTION "Remote Programs Virtual Channel Extension" SPECIFICATIONS "[MS-RDPERP]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/rdpdr/ChannelOptions.cmake b/channels/rdpdr/ChannelOptions.cmake index fb7bc0e3e..85dc252d3 100644 --- a/channels/rdpdr/ChannelOptions.cmake +++ b/channels/rdpdr/ChannelOptions.cmake @@ -1,8 +1,17 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT OFF) + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) +endif() define_channel_options(NAME "rdpdr" TYPE "static" DESCRIPTION "Device Redirection Virtual Channel Extension" SPECIFICATIONS "[MS-RDPEFS] [MS-RDPEPC] [MS-RDPESC] [MS-RDPESP]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/rdpsnd/ChannelOptions.cmake b/channels/rdpsnd/ChannelOptions.cmake index 0ef94be84..5755b0e5b 100644 --- a/channels/rdpsnd/ChannelOptions.cmake +++ b/channels/rdpsnd/ChannelOptions.cmake @@ -1,8 +1,17 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT ON) + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) +endif() define_channel_options(NAME "rdpsnd" TYPE "static" DESCRIPTION "Audio Output Virtual Channel Extension" SPECIFICATIONS "[MS-RDPEA]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/sample/ChannelOptions.cmake b/channels/sample/ChannelOptions.cmake index 032423b30..d0f239235 100644 --- a/channels/sample/ChannelOptions.cmake +++ b/channels/sample/ChannelOptions.cmake @@ -1,7 +1,14 @@ set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT OFF) +set(OPTION_SERVER_DEFAULT OFF) if(WITH_SAMPLE) + set(OPTION_CLIENT_DEFAULT ON) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) set(OPTION_DEFAULT ON) endif() @@ -10,3 +17,6 @@ define_channel_options(NAME "sample" TYPE "static" SPECIFICATIONS "" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/serial/ChannelOptions.cmake b/channels/serial/ChannelOptions.cmake index ff72beb44..808205506 100644 --- a/channels/serial/ChannelOptions.cmake +++ b/channels/serial/ChannelOptions.cmake @@ -1,8 +1,20 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT OFF) if(WIN32) - set(OPTION_DEFAULT OFF) + set(OPTION_CLIENT_DEFAULT OFF) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(ANDROID) + set(OPTION_CLIENT_DEFAULT OFF) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) endif() define_channel_options(NAME "serial" TYPE "device" @@ -10,3 +22,6 @@ define_channel_options(NAME "serial" TYPE "device" SPECIFICATIONS "[MS-RDPESP]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/server/CMakeLists.txt b/channels/server/CMakeLists.txt index 6e35cf5ac..8f94f0aa7 100644 --- a/channels/server/CMakeLists.txt +++ b/channels/server/CMakeLists.txt @@ -26,7 +26,6 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_SERVER_MODULES}) set(STATIC_MODULE_NAME ${${STATIC_MODULE}_SERVER_NAME}) set(STATIC_MODULE_CHANNEL ${${STATIC_MODULE}_SERVER_CHANNEL}) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${STATIC_MODULE_NAME}) - message(STATUS "Adding static server channel: ${STATIC_MODULE_CHANNEL}") endforeach() add_library(${MODULE_NAME} STATIC ${${MODULE_PREFIX}_SRCS}) diff --git a/channels/smartcard/ChannelOptions.cmake b/channels/smartcard/ChannelOptions.cmake index 2c05968aa..7ff221a5c 100644 --- a/channels/smartcard/ChannelOptions.cmake +++ b/channels/smartcard/ChannelOptions.cmake @@ -1,7 +1,14 @@ set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT OFF) +set(OPTION_SERVER_DEFAULT OFF) if(WITH_PCSC) + set(OPTION_CLIENT_DEFAULT ON) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) set(OPTION_DEFAULT ON) endif() @@ -10,3 +17,6 @@ define_channel_options(NAME "smartcard" TYPE "device" SPECIFICATIONS "[MS-RDPESC]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/tsmf/ChannelOptions.cmake b/channels/tsmf/ChannelOptions.cmake index 1ac5e942c..a0d78f847 100644 --- a/channels/tsmf/ChannelOptions.cmake +++ b/channels/tsmf/ChannelOptions.cmake @@ -1,8 +1,20 @@ -set(OPTION_DEFAULT ON) +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT OFF) if(WIN32) - set(OPTION_DEFAULT OFF) + set(OPTION_CLIENT_DEFAULT OFF) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(ANDROID) + set(OPTION_CLIENT_DEFAULT OFF) + set(OPTION_SERVER_DEFAULT OFF) +endif() + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) endif() define_channel_options(NAME "tsmf" TYPE "dynamic" @@ -10,3 +22,6 @@ define_channel_options(NAME "tsmf" TYPE "dynamic" SPECIFICATIONS "[MS-RDPEV]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/urbdrc/ChannelOptions.cmake b/channels/urbdrc/ChannelOptions.cmake index 9d4dc0729..92424c967 100644 --- a/channels/urbdrc/ChannelOptions.cmake +++ b/channels/urbdrc/ChannelOptions.cmake @@ -1,8 +1,17 @@ set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT OFF) +set(OPTION_SERVER_DEFAULT OFF) + +if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT}) + set(OPTION_DEFAULT ON) +endif() define_channel_options(NAME "urbdrc" TYPE "dynamic" DESCRIPTION "USB Devices Virtual Channel Extension" SPECIFICATIONS "[MS-RDPEUSB]" DEFAULT ${OPTION_DEFAULT}) +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +#define_channel_server_options(${OPTION_SERVER_DEFAULT}) + diff --git a/channels/urbdrc/client/CMakeLists.txt b/channels/urbdrc/client/CMakeLists.txt index 943d8abb5..ebf4d9417 100644 --- a/channels/urbdrc/client/CMakeLists.txt +++ b/channels/urbdrc/client/CMakeLists.txt @@ -35,6 +35,8 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} libusb-devman) + set(${MODULE_PREFIX}_LIBS dbus-glib-1 udev @@ -52,3 +54,4 @@ if(NOT STATIC_CHANNELS) endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client") + diff --git a/channels/urbdrc/libusb/CMakeLists.txt b/channels/urbdrc/libusb/CMakeLists.txt index 5299295b3..b01042be3 100644 --- a/channels/urbdrc/libusb/CMakeLists.txt +++ b/channels/urbdrc/libusb/CMakeLists.txt @@ -28,7 +28,12 @@ set(${MODULE_PREFIX}_SRCS include_directories(../client) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +if(STATIC_CHANNELS) + add_library(${MODULE_NAME} STATIC ${${MODULE_PREFIX}_SRCS}) +else() + add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +endif() + set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") set(${MODULE_PREFIX}_LIBS @@ -39,4 +44,7 @@ set(${MODULE_PREFIX}_LIBS target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) +endif() + diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 000000000..0b5b69245 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,2 @@ +iOS +Android diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 469226214..84ba2e2ee 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -43,3 +43,10 @@ if(APPLE) add_subdirectory(Mac) endif() +if(ANDROID) + if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Android") + message(STATUS "Adding Android client") + add_subdirectory(Android) + endif() +endif() + diff --git a/client/Mac/CMakeLists.txt b/client/Mac/CMakeLists.txt index b20f0150d..3be209d98 100644 --- a/client/Mac/CMakeLists.txt +++ b/client/Mac/CMakeLists.txt @@ -81,7 +81,7 @@ set_target_properties(MacFreeRDP PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH # Set the info plist to the custom instance set_target_properties(MacFreeRDP PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) -find_optional_package(MacAudio) +#find_optional_package(MacAudio) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${EXTRA_LIBS}) diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c index b296bc42c..e51c14224 100644 --- a/client/Windows/wfreerdp.c +++ b/client/Windows/wfreerdp.c @@ -43,6 +43,8 @@ #include #include #include + +#include #include #include @@ -144,6 +146,7 @@ BOOL wf_pre_connect(freerdp* instance) { int i1; wfInfo* wfi; + rdpFile* file; wfContext* context; rdpSettings* settings; @@ -154,6 +157,18 @@ BOOL wf_pre_connect(freerdp* instance) settings = instance->settings; + settings = instance->settings; + + if (settings->connection_file) + { + file = freerdp_client_rdp_file_new(); + + printf("Using connection file: %s\n", settings->connection_file); + + freerdp_client_parse_rdp_file(file, settings->connection_file); + freerdp_client_populate_settings_from_rdp_file(file, settings); + } + settings->os_major_type = OSMAJORTYPE_WINDOWS; settings->os_minor_type = OSMINORTYPE_WINDOWS_NT; settings->order_support[NEG_DSTBLT_INDEX] = TRUE; diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index f39aea11e..865f6085e 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -203,6 +203,7 @@ void xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary) void xf_Pointer_New(rdpContext* context, rdpPointer* pointer) { +#ifdef WITH_XCURSOR XcursorImage ci; xfInfo* xfi = ((xfContext*) context)->xfi; @@ -222,29 +223,36 @@ void xf_Pointer_New(rdpContext* context, rdpPointer* pointer) } ((xfPointer*) pointer)->cursor = XcursorImageLoadCursor(xfi->display, &ci); + free(ci.pixels); +#endif } void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer) { +#ifdef WITH_XCURSOR xfInfo* xfi = ((xfContext*) context)->xfi; if (((xfPointer*) pointer)->cursor != 0) XFreeCursor(xfi->display, ((xfPointer*) pointer)->cursor); +#endif } void xf_Pointer_Set(rdpContext* context, rdpPointer* pointer) { +#ifdef WITH_XCURSOR xfInfo* xfi = ((xfContext*) context)->xfi; /* in RemoteApp mode, window can be null if none has had focus */ if (xfi->window != NULL) XDefineCursor(xfi->display, xfi->window->handle, ((xfPointer*) pointer)->cursor); +#endif } void xf_Pointer_SetNull(rdpContext* context) { +#ifdef WITH_XCURSOR xfInfo* xfi = ((xfContext*) context)->xfi; static Cursor nullcursor = None; @@ -260,16 +268,20 @@ void xf_Pointer_SetNull(rdpContext* context) ci.pixels = &xp; nullcursor = XcursorImageLoadCursor(xfi->display, &ci); } + if (xfi->window != NULL && nullcursor != None) XDefineCursor(xfi->display, xfi->window->handle, nullcursor); +#endif } void xf_Pointer_SetDefault(rdpContext* context) { +#ifdef WITH_XCURSOR xfInfo* xfi = ((xfContext*) context)->xfi; if (xfi->window != NULL) XUndefineCursor(xfi->display, xfi->window->handle); +#endif } /* Glyph Class */ diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index e6b486801..d84be57d6 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -59,6 +59,8 @@ #include #include +#include + #include #include @@ -480,6 +482,7 @@ int _xf_error_handler(Display* d, XErrorEvent* ev) BOOL xf_pre_connect(freerdp* instance) { xfInfo* xfi; + rdpFile* file; BOOL bitmap_cache; rdpSettings* settings; int arg_parse_result; @@ -504,6 +507,17 @@ BOOL xf_pre_connect(freerdp* instance) } settings = instance->settings; + + if (settings->connection_file) + { + file = freerdp_client_rdp_file_new(); + + printf("Using connection file: %s\n", settings->connection_file); + + freerdp_client_parse_rdp_file(file, settings->connection_file); + freerdp_client_populate_settings_from_rdp_file(file, settings); + } + bitmap_cache = settings->bitmap_cache; settings->os_major_type = OSMAJORTYPE_UNIX; diff --git a/client/common/CMakeLists.txt b/client/common/CMakeLists.txt index 6b5346ab6..7464b142c 100644 --- a/client/common/CMakeLists.txt +++ b/client/common/CMakeLists.txt @@ -38,9 +38,19 @@ set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION_FULL} set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FREERDP_CHANNELS_CLIENT_LIBS}) +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-crt) + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + set_target_properties(${MODULE_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "") install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries) set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Common") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() + diff --git a/client/common/file.c b/client/common/file.c index ac85eb064..5803e5867 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -30,3 +30,528 @@ * RDP Settings for Remote Desktop Services in Windows Server 2008 R2: * http://technet.microsoft.com/en-us/library/ff393699/ */ + +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include + +#define DEBUG_CLIENT_FILE 1 + +static BYTE BOM_UTF16_LE[2] = { 0xFF, 0xFE }; +static WCHAR CR_LF_STR_W[] = { '\r', '\n', '\0' }; + +#define INVALID_INTEGER_VALUE 0xFFFFFFFF + +BOOL freerdp_client_rdp_file_set_integer(rdpFile* file, char* name, int value) +{ +#ifdef DEBUG_CLIENT_FILE + printf("%s:i:%d\n", name, value); +#endif + + if (_stricmp(name, "use multimon") == 0) + file->UseMultiMon = value; + else if (_stricmp(name, "screen mode id") == 0) + file->ScreenModeId = value; + else if (_stricmp(name, "span monitors") == 0) + file->SpanMonitors = value; + else if (_stricmp(name, "smartsizing") == 0) + file->SmartSizing = value; + else if (_stricmp(name, "enablesuperpan") == 0) + file->EnableSuperSpan = value; + else if (_stricmp(name, "superpanaccelerationfactor") == 0) + file->SuperSpanAccelerationFactor = value; + else if (_stricmp(name, "desktopwidth") == 0) + file->DesktopWidth = value; + else if (_stricmp(name, "desktopheight") == 0) + file->DesktopHeight = value; + else if (_stricmp(name, "desktop size id") == 0) + file->DesktopSizeId = value; + else if (_stricmp(name, "session bpp") == 0) + file->SessionBpp = value; + else if (_stricmp(name, "compression") == 0) + file->Compression = value; + else if (_stricmp(name, "keyboardhook") == 0) + file->KeyboardHook = value; + else if (_stricmp(name, "disable ctrl+alt+del") == 0) + file->DisableCtrlAltDel = value; + else if (_stricmp(name, "audiomode") == 0) + file->AudioMode = value; + else if (_stricmp(name, "audioqualitymode") == 0) + file->AudioQualityMode = value; + else if (_stricmp(name, "audiocapturemode") == 0) + file->AudioCaptureMode = value; + else if (_stricmp(name, "videoplaybackmode") == 0) + file->VideoPlaybackMode = value; + else if (_stricmp(name, "connection type") == 0) + file->ConnectionType = value; + else if (_stricmp(name, "networkautodetect") == 0) + file->NetworkAutoDetect = value; + else if (_stricmp(name, "bandwidthautodetect") == 0) + file->BandwidthAutoDetect = value; + else if (_stricmp(name, "pinconnectionbar") == 0) + file->PinConnectionBar = value; + else if (_stricmp(name, "displayconnectionbar") == 0) + file->DisplayConnectionBar = value; + else if (_stricmp(name, "workspaceid") == 0) + file->WorkspaceId = value; + else if (_stricmp(name, "enableworkspacereconnect") == 0) + file->EnableWorkspaceReconnect = value; + else if (_stricmp(name, "disable wallpaper") == 0) + file->DisableWallpaper = value; + else if (_stricmp(name, "allow font smoothing") == 0) + file->AllowFontSmoothing = value; + else if (_stricmp(name, "allow desktop composition") == 0) + file->AllowDesktopComposition = value; + else if (_stricmp(name, "disable full window drag") == 0) + file->DisableFullWindowDrag = value; + else if (_stricmp(name, "disable menu anims") == 0) + file->DisableMenuAnims = value; + else if (_stricmp(name, "disable themes") == 0) + file->DisableThemes = value; + else if (_stricmp(name, "disable cursor setting") == 0) + file->DisableCursorSetting = value; + else if (_stricmp(name, "bitmapcachesize") == 0) + file->BitmapCacheSize = value; + else if (_stricmp(name, "bitmapcachepersistenable") == 0) + file->BitmapCachePersistEnable = value; + else if (_stricmp(name, "server port") == 0) + file->ServerPort = value; + else if (_stricmp(name, "redirectdrives") == 0) + file->RedirectDrives = value; + else if (_stricmp(name, "redirectprinters") == 0) + file->RedirectPrinters = value; + else if (_stricmp(name, "redirectcomports") == 0) + file->RedirectComPorts = value; + else if (_stricmp(name, "redirectsmartcards") == 0) + file->RedirectSmartCards = value; + else if (_stricmp(name, "redirectclipboard") == 0) + file->RedirectClipboard = value; + else if (_stricmp(name, "redirectposdevices") == 0) + file->RedirectPosDevices = value; + else if (_stricmp(name, "redirectdirectx") == 0) + file->RedirectDirectX = value; + else if (_stricmp(name, "disableprinterredirection") == 0) + file->DisablePrinterRedirection = value; + else if (_stricmp(name, "disableclipboardredirection") == 0) + file->DisableClipboardRedirection = value; + else if (_stricmp(name, "connect to console") == 0) + file->ConnectToConsole = value; + else if (_stricmp(name, "administrative session") == 0) + file->AdministrativeSession = value; + else if (_stricmp(name, "autoreconnection enabled") == 0) + file->AutoReconnectionEnabled = value; + else if (_stricmp(name, "autoreconnect max retries") == 0) + file->AutoReconnectMaxRetries = value; + else if (_stricmp(name, "public mode") == 0) + file->PublicMode = value; + else if (_stricmp(name, "authentication level") == 0) + file->AuthenticationLevel = value; + else if (_stricmp(name, "promptcredentialonce") == 0) + file->PromptCredentialOnce = value; + else if (_stricmp(name, "prompt for credentials") == 0) + file->PromptForCredentials = value; + else if (_stricmp(name, "promptcredentialonce") == 0) + file->PromptForCredentialsOnce = value; + else if (_stricmp(name, "negotiate security layer") == 0) + file->NegotiateSecurityLayer = value; + else if (_stricmp(name, "enablecredsspsupport") == 0) + file->EnableCredSSPSupport = value; + else if (_stricmp(name, "remoteapplicationmode") == 0) + file->RemoteApplicationMode = value; + else if (_stricmp(name, "remoteapplicationexpandcmdline") == 0) + file->RemoteApplicationExpandCmdLine = value; + else if (_stricmp(name, "remoteapplicationexpandworkingdir") == 0) + file->RemoteApplicationExpandWorkingDir = value; + else if (_stricmp(name, "disableconnectionsharing") == 0) + file->DisableConnectionSharing = value; + else if (_stricmp(name, "disableremoteappcapscheck") == 0) + file->DisableRemoteAppCapsCheck = value; + else if (_stricmp(name, "gatewayusagemethod") == 0) + file->GatewayUsageMethod = value; + else if (_stricmp(name, "gatewayprofileusagemethod") == 0) + file->GatewayProfileUsageMethod = value; + else if (_stricmp(name, "gatewaycredentialssource") == 0) + file->GatewayCredentialsSource = value; + else if (_stricmp(name, "use redirection server name") == 0) + file->UseRedirectionServerName = value; + else if (_stricmp(name, "rdgiskdcproxy") == 0) + file->RdgIsKdcProxy = value; + else + return FALSE; + + return TRUE; +} + +void freerdp_client_parse_rdp_file_integer_unicode(rdpFile* file, WCHAR* name, WCHAR* value) +{ + int length; + int ivalue; + char* nameA; + char* valueA; + + length = _wcslen(name); + nameA = (char*) malloc(length + 1); + WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL); + nameA[length] = '\0'; + + length = _wcslen(value); + valueA = (char*) malloc(length + 1); + WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL); + valueA[length] = '\0'; + + ivalue = atoi(valueA); + freerdp_client_rdp_file_set_integer(file, nameA, ivalue); + + free(nameA); + free(valueA); +} + +void freerdp_client_parse_rdp_file_integer_ascii(rdpFile* file, char* name, char* value) +{ + int ivalue = atoi(value); + freerdp_client_rdp_file_set_integer(file, name, ivalue); +} + +BOOL freerdp_client_rdp_file_set_string(rdpFile* file, char* name, char* value) +{ +#ifdef DEBUG_CLIENT_FILE + printf("%s:s:%s\n", name, value); +#endif + + if (_stricmp(name, "username") == 0) + file->Username = value; + else if (_stricmp(name, "domain") == 0) + file->Domain = value; + else if (_stricmp(name, "full address") == 0) + file->FullAddress = value; + else if (_stricmp(name, "alternate full address") == 0) + file->AlternateFullAddress = value; + else if (_stricmp(name, "usbdevicestoredirect") == 0) + file->UsbDevicesToRedirect = value; + else if (_stricmp(name, "loadbalanceinfo") == 0) + file->LoadBalanceInfo = value; + else if (_stricmp(name, "remoteapplicationname") == 0) + file->RemoteApplicationName = value; + else if (_stricmp(name, "remoteapplicationicon") == 0) + file->RemoteApplicationIcon = value; + else if (_stricmp(name, "remoteapplicationprogram") == 0) + file->RemoteApplicationProgram = value; + else if (_stricmp(name, "remoteapplicationfile") == 0) + file->RemoteApplicationFile = value; + else if (_stricmp(name, "remoteapplicationcmdline") == 0) + file->RemoteApplicationCmdLine = value; + else if (_stricmp(name, "alternate shell") == 0) + file->AlternateShell = value; + else if (_stricmp(name, "shell working directory") == 0) + file->ShellWorkingDirectory = value; + else if (_stricmp(name, "gatewayhostname") == 0) + file->GatewayHostname = value; + else if (_stricmp(name, "kdcproxyname") == 0) + file->KdcProxyName = value; + else if (_stricmp(name, "drivestoredirect") == 0) + file->DrivesToRedirect = value; + else if (_stricmp(name, "devicestoredirect") == 0) + file->DevicesToRedirect = value; + else if (_stricmp(name, "winposstr") == 0) + file->WinPosStr = value; + else + return FALSE; + + return TRUE; +} + +void freerdp_client_parse_rdp_file_string_unicode(rdpFile* file, WCHAR* name, WCHAR* value) +{ + int length; + char* nameA; + char* valueA; + + length = _wcslen(name); + nameA = (char*) malloc(length + 1); + WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL); + nameA[length] = '\0'; + + length = _wcslen(value); + valueA = (char*) malloc(length + 1); + WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL); + valueA[length] = '\0'; + + if (!freerdp_client_rdp_file_set_string(file, nameA, valueA)) + free(valueA); + + free(nameA); +} + +void freerdp_client_parse_rdp_file_string_ascii(rdpFile* file, char* name, char* value) +{ + freerdp_client_rdp_file_set_string(file, name, value); +} + +BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, BYTE* buffer, size_t size) +{ + int length; + char* line; + char* type; + char* context; + char *d1, *d2; + char *beg, *end; + char *name, *value; + + line = strtok_s((char*) buffer, "\r\n", &context); + + while (line != NULL) + { + length = strlen(line); + + if (length > 1) + { + beg = line; + end = &line[length - 1]; + + d1 = strchr(line, ':'); + + if (!d1) + goto next_line; /* not first delimiter */ + + type = &d1[1]; + d2 = strchr(type, ':'); + + if (!d2) + goto next_line; /* no second delimiter */ + + if ((d2 - d1) != 2) + goto next_line; /* improper type length */ + + if (d2 == end) + goto next_line; /* no value */ + + *d1 = 0; + *d2 = 0; + name = beg; + value = &d2[1]; + + if (*type == 'i') + { + /* integer type */ + freerdp_client_parse_rdp_file_integer_ascii(file, name, value); + } + else if (*type == 's') + { + /* string type */ + freerdp_client_parse_rdp_file_string_ascii(file, name, value); + } + else if (*type == 'b') + { + /* binary type */ + } + } + +next_line: + line = strtok_s(NULL, "\r\n", &context); + } + + return TRUE; +} + +BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, BYTE* buffer, size_t size) +{ + int length; + WCHAR* line; + WCHAR* type; + WCHAR* context; + WCHAR *d1, *d2; + WCHAR *beg, *end; + WCHAR *name, *value; + + line = wcstok_s((WCHAR*) buffer, CR_LF_STR_W, &context); + + while (line != NULL) + { + length = _wcslen(line); + + if (length > 1) + { + beg = line; + end = &line[length - 1]; + + d1 = _wcschr(line, ':'); + + if (!d1) + goto next_line; /* not first delimiter */ + + type = &d1[1]; + d2 = _wcschr(type, ':'); + + if (!d2) + goto next_line; /* no second delimiter */ + + if ((d2 - d1) != 2) + goto next_line; /* improper type length */ + + if (d2 == end) + goto next_line; /* no value */ + + *d1 = 0; + *d2 = 0; + name = beg; + value = &d2[1]; + + if (*type == 'i') + { + /* integer type */ + freerdp_client_parse_rdp_file_integer_unicode(file, name, value); + } + else if (*type == 's') + { + /* string type */ + freerdp_client_parse_rdp_file_string_unicode(file, name, value); + } + else if (*type == 'b') + { + /* binary type */ + } + } + +next_line: + line = wcstok_s(NULL, CR_LF_STR_W, &context); + } + + return TRUE; +} + +BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t size) +{ + if (size < 2) + return FALSE; + + if ((buffer[0] == BOM_UTF16_LE[0]) && (buffer[1] == BOM_UTF16_LE[1])) + return freerdp_client_parse_rdp_file_buffer_unicode(file, &buffer[2], size - 2); + + return freerdp_client_parse_rdp_file_buffer_ascii(file, buffer, size); +} + +BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name) +{ + BYTE* buffer; + FILE* fp = NULL; + size_t read_size; + long int file_size; + + fp = fopen(name, "r"); + + if (!fp) + return FALSE; + + fseek(fp, 0, SEEK_END); + file_size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + if (file_size < 1) + return FALSE; + + buffer = (BYTE*) malloc(file_size); + + read_size = fread(buffer, file_size, 1, fp); + + if (!read_size) + { + if (!ferror(fp)) + read_size = file_size; + } + + if (read_size < 1) + { + free(buffer); + buffer = NULL; + return FALSE; + } + + return freerdp_client_parse_rdp_file_buffer(file, buffer, file_size); +} + +BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings) +{ + if (~((size_t) file->Domain)) + settings->domain = file->Domain; + + if (~((size_t) file->Username)) + { + char* p; + size_t size; + + p = strchr(file->Username, '\\'); + + if (p) + { + size = p - file->Username; + settings->domain = (char*) malloc(size + 1); + CopyMemory(settings->domain, file->Username, size); + settings->domain[size] = 0; + + size = strlen(file->Username) - size - 1; + settings->username = (char*) malloc(size + 1); + CopyMemory(settings->username, &file->Username[p - file->Username + 1], size); + settings->username[size] = 0; + } + else + { + settings->username = file->Username; + } + } + + if (~file->ServerPort) + settings->port = file->ServerPort; + if (~((size_t) file->FullAddress)) + settings->hostname = file->FullAddress; + if (~file->DesktopWidth) + settings->width = file->DesktopWidth; + if (~file->DesktopHeight) + settings->height = file->DesktopHeight; + if (~file->SessionBpp) + settings->color_depth = file->SessionBpp; + if (~file->ConnectToConsole) + settings->console_session = file->ConnectToConsole; + if (~file->AdministrativeSession) + settings->console_session = file->AdministrativeSession; + if (~file->NegotiateSecurityLayer) + settings->security_layer_negotiation = file->NegotiateSecurityLayer; + if (~file->EnableCredSSPSupport) + settings->nla_security = file->EnableCredSSPSupport; + if (~((size_t) file->AlternateShell)) + settings->shell = file->AlternateShell; + if (~((size_t) file->ShellWorkingDirectory)) + settings->directory = file->ShellWorkingDirectory; + + if (~((size_t) file->GatewayHostname)) + settings->tsg_hostname = file->GatewayHostname; + if (~file->GatewayUsageMethod) + settings->ts_gateway = TRUE; + if (~file->PromptCredentialOnce) + settings->tsg_same_credentials = TRUE; + + if (~file->RemoteApplicationMode) + settings->remote_app = file->RemoteApplicationMode; + + return TRUE; +} + +rdpFile* freerdp_client_rdp_file_new() +{ + rdpFile* file; + + file = (rdpFile*) malloc(sizeof(rdpFile)); + FillMemory(file, sizeof(rdpFile), 0xFF); + + return file; +} + +void freerdp_client_rdp_file_free(rdpFile* file) +{ + free(file); +} diff --git a/client/common/test/.gitignore b/client/common/test/.gitignore new file mode 100644 index 000000000..30cac2bab --- /dev/null +++ b/client/common/test/.gitignore @@ -0,0 +1,3 @@ +TestClient +TestClient.c + diff --git a/client/common/test/CMakeLists.txt b/client/common/test/CMakeLists.txt new file mode 100644 index 000000000..dcdeab17e --- /dev/null +++ b/client/common/test/CMakeLists.txt @@ -0,0 +1,28 @@ + +set(MODULE_NAME "TestClient") +set(MODULE_PREFIX "TEST_CLIENT") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestClientRdpFile.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Client/Test") + diff --git a/client/common/test/TestClientRdpFile.c b/client/common/test/TestClientRdpFile.c new file mode 100644 index 000000000..7381903b1 --- /dev/null +++ b/client/common/test/TestClientRdpFile.c @@ -0,0 +1,330 @@ + +#include +#include +#include + +#include + +static BYTE testRdpFileUTF16[] = +{ + 0xff, 0xfe, 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, + 0x6e, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, + 0x20, 0x00, 0x69, 0x00, 0x64, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, + 0x32, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, + 0x20, 0x00, 0x6d, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x74, 0x00, 0x69, 0x00, + 0x6d, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, + 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, 0x65, 0x00, 0x73, 0x00, + 0x6b, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x77, 0x00, 0x69, 0x00, + 0x64, 0x00, 0x74, 0x00, 0x68, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, + 0x31, 0x00, 0x39, 0x00, 0x32, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6b, 0x00, 0x74, 0x00, 0x6f, 0x00, + 0x70, 0x00, 0x68, 0x00, 0x65, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, + 0x74, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x30, 0x00, + 0x38, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x73, 0x00, 0x65, 0x00, + 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, + 0x62, 0x00, 0x70, 0x00, 0x70, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, + 0x33, 0x00, 0x32, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x69, 0x00, + 0x6e, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x73, 0x00, 0x74, 0x00, + 0x72, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x2c, 0x00, + 0x31, 0x00, 0x2c, 0x00, 0x35, 0x00, 0x35, 0x00, 0x33, 0x00, 0x2c, 0x00, + 0x32, 0x00, 0x31, 0x00, 0x31, 0x00, 0x2c, 0x00, 0x31, 0x00, 0x33, 0x00, + 0x35, 0x00, 0x33, 0x00, 0x2c, 0x00, 0x38, 0x00, 0x31, 0x00, 0x31, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, + 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, + 0x6e, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, + 0x0a, 0x00, 0x6b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x62, 0x00, 0x6f, 0x00, + 0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x6f, 0x00, + 0x6b, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x32, 0x00, 0x0d, 0x00, + 0x0a, 0x00, 0x61, 0x00, 0x75, 0x00, 0x64, 0x00, 0x69, 0x00, 0x6f, 0x00, + 0x63, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, + 0x65, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x3a, 0x00, + 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x76, 0x00, + 0x69, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x6c, 0x00, + 0x61, 0x00, 0x79, 0x00, 0x62, 0x00, 0x61, 0x00, 0x63, 0x00, 0x6b, 0x00, + 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x3a, 0x00, 0x69, 0x00, + 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x63, 0x00, 0x6f, 0x00, + 0x6e, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, + 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x74, 0x00, 0x79, 0x00, 0x70, 0x00, + 0x65, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x37, 0x00, 0x0d, 0x00, + 0x0a, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x74, 0x00, 0x77, 0x00, 0x6f, 0x00, + 0x72, 0x00, 0x6b, 0x00, 0x61, 0x00, 0x75, 0x00, 0x74, 0x00, 0x6f, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x74, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, + 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, + 0x62, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x77, 0x00, 0x69, 0x00, + 0x64, 0x00, 0x74, 0x00, 0x68, 0x00, 0x61, 0x00, 0x75, 0x00, 0x74, 0x00, + 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x74, 0x00, 0x65, 0x00, 0x63, 0x00, + 0x74, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, + 0x0a, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x70, 0x00, 0x6c, 0x00, + 0x61, 0x00, 0x79, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6e, 0x00, + 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, + 0x62, 0x00, 0x61, 0x00, 0x72, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, + 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, + 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x77, 0x00, 0x6f, 0x00, 0x72, 0x00, + 0x6b, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, 0x00, + 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6e, 0x00, + 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, + 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, + 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x77, 0x00, + 0x61, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x70, 0x00, 0x61, 0x00, 0x70, 0x00, + 0x65, 0x00, 0x72, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, + 0x77, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, + 0x20, 0x00, 0x73, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x74, 0x00, + 0x68, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x3a, 0x00, 0x69, 0x00, + 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, 0x6c, 0x00, + 0x6c, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x20, 0x00, 0x64, 0x00, 0x65, 0x00, + 0x73, 0x00, 0x6b, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x20, 0x00, + 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x73, 0x00, + 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x3a, 0x00, + 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, + 0x69, 0x00, 0x73, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, + 0x20, 0x00, 0x66, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, + 0x77, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x77, 0x00, + 0x20, 0x00, 0x64, 0x00, 0x72, 0x00, 0x61, 0x00, 0x67, 0x00, 0x3a, 0x00, + 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, + 0x69, 0x00, 0x73, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, + 0x20, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x20, 0x00, + 0x61, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x6d, 0x00, 0x73, 0x00, 0x3a, 0x00, + 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, + 0x69, 0x00, 0x73, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, + 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, + 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, + 0x0a, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x61, 0x00, 0x62, 0x00, + 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x63, 0x00, 0x75, 0x00, 0x72, 0x00, + 0x73, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, + 0x74, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x3a, 0x00, + 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x62, 0x00, + 0x69, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x70, 0x00, 0x63, 0x00, + 0x61, 0x00, 0x63, 0x00, 0x68, 0x00, 0x65, 0x00, 0x70, 0x00, 0x65, 0x00, + 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, 0x00, + 0x6e, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x3a, 0x00, + 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x66, 0x00, + 0x75, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x64, 0x00, + 0x64, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x3a, 0x00, + 0x73, 0x00, 0x3a, 0x00, 0x4c, 0x00, 0x41, 0x00, 0x42, 0x00, 0x31, 0x00, + 0x2d, 0x00, 0x57, 0x00, 0x37, 0x00, 0x2d, 0x00, 0x44, 0x00, 0x4d, 0x00, + 0x2d, 0x00, 0x30, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x6c, 0x00, 0x61, 0x00, + 0x62, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x77, 0x00, 0x61, 0x00, + 0x6b, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x63, 0x00, + 0x61, 0x00, 0x6c, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, 0x75, 0x00, + 0x64, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, + 0x65, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, + 0x0a, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x72, 0x00, + 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x70, 0x00, 0x72, 0x00, 0x69, 0x00, + 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x3a, 0x00, + 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x72, 0x00, + 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, + 0x74, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x6f, 0x00, + 0x72, 0x00, 0x74, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, + 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, + 0x69, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x73, 0x00, + 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x63, 0x00, 0x61, 0x00, + 0x72, 0x00, 0x64, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, + 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, + 0x69, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x63, 0x00, + 0x6c, 0x00, 0x69, 0x00, 0x70, 0x00, 0x62, 0x00, 0x6f, 0x00, 0x61, 0x00, + 0x72, 0x00, 0x64, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, + 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x70, 0x00, 0x6f, 0x00, + 0x73, 0x00, 0x64, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, + 0x65, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, 0x75, 0x00, 0x74, 0x00, 0x6f, 0x00, + 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6e, 0x00, + 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, + 0x20, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, + 0x65, 0x00, 0x64, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, 0x75, 0x00, 0x74, 0x00, 0x68, 0x00, + 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, + 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6c, 0x00, + 0x65, 0x00, 0x76, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x3a, 0x00, 0x69, 0x00, + 0x3a, 0x00, 0x32, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x72, 0x00, + 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x74, 0x00, 0x20, 0x00, 0x66, 0x00, + 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x63, 0x00, 0x72, 0x00, 0x65, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x61, 0x00, + 0x6c, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x67, 0x00, 0x6f, 0x00, + 0x74, 0x00, 0x69, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, + 0x73, 0x00, 0x65, 0x00, 0x63, 0x00, 0x75, 0x00, 0x72, 0x00, 0x69, 0x00, + 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00, + 0x65, 0x00, 0x72, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x6f, 0x00, + 0x74, 0x00, 0x65, 0x00, 0x61, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6c, 0x00, + 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, + 0x6e, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x3a, 0x00, + 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x61, 0x00, + 0x6c, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x61, 0x00, + 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, 0x68, 0x00, 0x65, 0x00, + 0x6c, 0x00, 0x6c, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x0d, 0x00, + 0x0a, 0x00, 0x73, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, + 0x20, 0x00, 0x77, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x69, 0x00, + 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x72, 0x00, + 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x79, 0x00, + 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x67, 0x00, + 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x77, 0x00, 0x61, 0x00, 0x79, 0x00, + 0x68, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x74, 0x00, 0x6e, 0x00, 0x61, 0x00, + 0x6d, 0x00, 0x65, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x4c, 0x00, + 0x41, 0x00, 0x42, 0x00, 0x31, 0x00, 0x2d, 0x00, 0x57, 0x00, 0x32, 0x00, + 0x4b, 0x00, 0x38, 0x00, 0x52, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x47, 0x00, + 0x57, 0x00, 0x2e, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x62, 0x00, 0x31, 0x00, + 0x2e, 0x00, 0x61, 0x00, 0x77, 0x00, 0x61, 0x00, 0x6b, 0x00, 0x65, 0x00, + 0x2e, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6c, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, + 0x77, 0x00, 0x61, 0x00, 0x79, 0x00, 0x75, 0x00, 0x73, 0x00, 0x61, 0x00, + 0x67, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x74, 0x00, 0x68, 0x00, + 0x6f, 0x00, 0x64, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, + 0x77, 0x00, 0x61, 0x00, 0x79, 0x00, 0x63, 0x00, 0x72, 0x00, 0x65, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x61, 0x00, + 0x6c, 0x00, 0x73, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, + 0x63, 0x00, 0x65, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, + 0x77, 0x00, 0x61, 0x00, 0x79, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, + 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x75, 0x00, 0x73, 0x00, + 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x74, 0x00, + 0x68, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, + 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, + 0x6d, 0x00, 0x70, 0x00, 0x74, 0x00, 0x63, 0x00, 0x72, 0x00, 0x65, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x61, 0x00, + 0x6c, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x3a, 0x00, + 0x69, 0x00, 0x3a, 0x00, 0x31, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x75, 0x00, + 0x73, 0x00, 0x65, 0x00, 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, + 0x69, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, + 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, + 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x61, 0x00, + 0x6d, 0x00, 0x65, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, 0x30, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x72, 0x00, 0x64, 0x00, 0x67, 0x00, 0x69, 0x00, + 0x73, 0x00, 0x6b, 0x00, 0x64, 0x00, 0x63, 0x00, 0x70, 0x00, 0x72, 0x00, + 0x6f, 0x00, 0x78, 0x00, 0x79, 0x00, 0x3a, 0x00, 0x69, 0x00, 0x3a, 0x00, + 0x30, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x6b, 0x00, 0x64, 0x00, 0x63, 0x00, + 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x78, 0x00, 0x79, 0x00, 0x6e, 0x00, + 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x64, 0x00, 0x72, 0x00, 0x69, 0x00, 0x76, 0x00, + 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, + 0x64, 0x00, 0x69, 0x00, 0x72, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, + 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x2a, 0x00, 0x0d, 0x00, 0x0a, 0x00, + 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x61, 0x00, + 0x6d, 0x00, 0x65, 0x00, 0x3a, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x4c, 0x00, + 0x41, 0x00, 0x42, 0x00, 0x31, 0x00, 0x5c, 0x00, 0x4a, 0x00, 0x6f, 0x00, + 0x68, 0x00, 0x6e, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x65, 0x00, 0x0d, 0x00, + 0x0a, 0x00 +}; + +static char testRdpFileUTF8[] = + "screen mode id:i:2\n" + "use multimon:i:0\n" + "desktopwidth:i:1920\n" + "desktopheight:i:1080\n" + "session bpp:i:32\n" + "winposstr:s:0,1,553,211,1353,811\n" + "compression:i:1\n" + "keyboardhook:i:2\n" + "audiocapturemode:i:0\n" + "videoplaybackmode:i:1\n" + "connection type:i:7\n" + "networkautodetect:i:1\n" + "bandwidthautodetect:i:1\n" + "displayconnectionbar:i:1\n" + "enableworkspacereconnect:i:0\n" + "disable wallpaper:i:0\n" + "allow font smoothing:i:0\n" + "allow desktop composition:i:0\n" + "disable full window drag:i:1\n" + "disable menu anims:i:1\n" + "disable themes:i:0\n" + "disable cursor setting:i:0\n" + "bitmapcachepersistenable:i:1\n" + "full address:s:LAB1-W7-DM-01.lab1.awake.local\n" + "audiomode:i:0\n" + "redirectprinters:i:1\n" + "redirectcomports:i:0\n" + "redirectsmartcards:i:1\n" + "redirectclipboard:i:1\n" + "redirectposdevices:i:0\n" + "autoreconnection enabled:i:1\n" + "authentication level:i:2\n" + "prompt for credentials:i:0\n" + "negotiate security layer:i:1\n" + "remoteapplicationmode:i:0\n" + "alternate shell:s:\n" + "shell working directory:s:\n" + "gatewayhostname:s:LAB1-W2K8R2-GW.lab1.awake.local\n" + "gatewayusagemethod:i:1\n" + "gatewaycredentialssource:i:0\n" + "gatewayprofileusagemethod:i:1\n" + "promptcredentialonce:i:1\n" + "use redirection server name:i:0\n" + "rdgiskdcproxy:i:0\n" + "kdcproxyname:s:\n" + "drivestoredirect:s:*\n" + "username:s:LAB1\\JohnDoe\n"; + +int TestClientRdpFile(int argc, char* argv[]) +{ + rdpFile* file; + + /* Unicode */ + + file = freerdp_client_rdp_file_new(); + freerdp_client_parse_rdp_file_buffer(file, testRdpFileUTF16, sizeof(testRdpFileUTF16)); + + if (file->UseMultiMon != 0) + { + printf("UseMultiMon mismatch: Actual: %d, Expected: %d\n", file->UseMultiMon, 0); + return -1; + } + + if (file->ScreenModeId != 2) + { + printf("ScreenModeId mismatch: Actual: %d, Expected: %d\n", file->ScreenModeId, 2); + return -1; + } + + if (file->GatewayProfileUsageMethod != 1) + { + printf("GatewayProfileUsageMethod mismatch: Actual: %d, Expected: %d\n", file->GatewayProfileUsageMethod, 1); + return -1; + } + + if (strcmp(file->GatewayHostname, "LAB1-W2K8R2-GW.lab1.awake.local") != 0) + { + printf("GatewayHostname mismatch: Actual: %s, Expected: %s\n", + file->GatewayHostname, "LAB1-W2K8R2-GW.lab1.awake.local"); + return -1; + } + + freerdp_client_rdp_file_free(file); + + /* Ascii */ + + file = freerdp_client_rdp_file_new(); + freerdp_client_parse_rdp_file_buffer(file, (BYTE*) testRdpFileUTF8, sizeof(testRdpFileUTF8)); + + if (file->UseMultiMon != 0) + { + printf("UseMultiMon mismatch: Actual: %d, Expected: %d\n", file->UseMultiMon, 0); + return -1; + } + + if (file->ScreenModeId != 2) + { + printf("ScreenModeId mismatch: Actual: %d, Expected: %d\n", file->ScreenModeId, 2); + return -1; + } + + if (file->GatewayProfileUsageMethod != 1) + { + printf("GatewayProfileUsageMethod mismatch: Actual: %d, Expected: %d\n", file->GatewayProfileUsageMethod, 1); + return -1; + } + + if (strcmp(file->GatewayHostname, "LAB1-W2K8R2-GW.lab1.awake.local") != 0) + { + printf("GatewayHostname mismatch: Actual: %s, Expected: %s\n", + file->GatewayHostname, "LAB1-W2K8R2-GW.lab1.awake.local"); + return -1; + } + + freerdp_client_rdp_file_free(file); + + return 0; +} diff --git a/cmake/AndroidToolchain.cmake b/cmake/AndroidToolchain.cmake new file mode 100644 index 000000000..e6271d9d8 --- /dev/null +++ b/cmake/AndroidToolchain.cmake @@ -0,0 +1,1125 @@ +# ------------------------------------------------------------------------------ +# Android CMake toolchain file, for use with the Android NDK r5-r8 +# Requires cmake 2.6.3 or newer (2.8.5 or newer is recommended). +# See home page: http://code.google.com/p/android-cmake/ +# +# The file is mantained by the OpenCV project. And also can be found at +# http://code.opencv.org/projects/opencv/repository/revisions/master/changes/android/android.toolchain.cmake +# +# Usage Linux: +# $ export ANDROID_NDK=/absolute/path/to/the/android-ndk +# $ mkdir build && cd build +# $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake .. +# $ make -j8 +# +# Usage Linux (using standalone toolchain): +# $ export ANDROID_STANDALONE_TOOLCHAIN=/absolute/path/to/android-toolchain +# $ mkdir build && cd build +# $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake .. +# $ make -j8 +# +# Usage Windows: +# You need native port of make to build your project. +# Android NDK r7 (or newer) already has make.exe on board. +# For older NDK you have to install it separately. +# For example, this one: http://gnuwin32.sourceforge.net/packages/make.htm +# +# $ SET ANDROID_NDK=C:\absolute\path\to\the\android-ndk +# $ mkdir build && cd build +# $ cmake.exe -G"MinGW Makefiles" +# -DCMAKE_TOOLCHAIN_FILE=path\to\the\android.toolchain.cmake +# -DCMAKE_MAKE_PROGRAM="%ANDROID_NDK%\prebuilt\windows\bin\make.exe" .. +# $ "%ANDROID_NDK%\prebuilt\windows\bin\make.exe" +# +# +# Options (can be set as cmake parameters: -D=): +# ANDROID_NDK=/opt/android-ndk - path to the NDK root. +# Can be set as environment variable. Can be set only at first cmake run. +# +# ANDROID_STANDALONE_TOOLCHAIN=/opt/android-toolchain - path to the +# standalone toolchain. This option is not used if full NDK is found +# (ignored if ANDROID_NDK is set). +# Can be set as environment variable. Can be set only at first cmake run. +# +# ANDROID_ABI=armeabi-v7a - specifies the target Application Binary +# Interface (ABI). This option nearly matches to the APP_ABI variable +# used by ndk-build tool from Android NDK. +# +# Possible targets are: +# "armeabi" - matches to the NDK ABI with the same name. +# See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation. +# "armeabi-v7a" - matches to the NDK ABI with the same name. +# See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation. +# "armeabi-v7a with NEON" - same as armeabi-v7a, but +# sets NEON as floating-point unit +# "armeabi-v7a with VFPV3" - same as armeabi-v7a, but +# sets VFPV3 as floating-point unit (has 32 registers instead of 16). +# "armeabi-v6 with VFP" - tuned for ARMv6 processors having VFP. +# "x86" - matches to the NDK ABI with the same name. +# See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation. +# "mips" - matches to the NDK ABI with the same name +# (not testes on real devices) +# +# ANDROID_NATIVE_API_LEVEL=android-8 - level of Android API compile for. +# Option is read-only when standalone toolchain used. +# +# ANDROID_FORCE_ARM_BUILD=OFF - set true to generate 32-bit ARM instructions +# instead of Thumb-1. Is not available for "x86" (inapplicable) and +# "armeabi-v6 with VFP" (forced) ABIs. +# +# ANDROID_NO_UNDEFINED=ON - set true to show all undefined symbols as linker +# errors even if they are not used. +# +# ANDROID_SO_UNDEFINED=OFF - set true to allow undefined symbols in shared +# libraries. Automatically turned on for NDK r5x and r6x due to GLESv2 +# problems. +# +# LIBRARY_OUTPUT_PATH_ROOT=${CMAKE_SOURCE_DIR} - where to output binary +# files. See additional details below. +# +# ANDROID_SET_OBSOLETE_VARIABLES=ON - it set, then toolchain defines some +# obsolete variables which were set by previous versions of this file for +# backward compatibility. +# +# +# What?: +# android-cmake toolchain searches for NDK/toolchain in the following order: +# ANDROID_NDK - cmake parameter +# ANDROID_NDK - environment variable +# ANDROID_STANDALONE_TOOLCHAIN - cmake parameter +# ANDROID_STANDALONE_TOOLCHAIN - environment variable +# ANDROID_NDK - default locations +# ANDROID_STANDALONE_TOOLCHAIN - default locations +# +# Make sure to do the following in your scripts: +# SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${my_cxx_flags}" ) +# SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${my_cxx_flags}" ) +# The flags will be prepopulated with critical flags, so don't loose them. +# Also be aware that toolchain also sets configuration-specific compiler +# flags and linker flags. +# +# ANDROID and BUILD_ANDROID will be set to true, you may test any of these +# variables to make necessary Android-specific configuration changes. +# +# Also ARMEABI or ARMEABI_V7A or X86 will be set true, mutually exclusive. +# NEON option will be set true if VFP is set to NEON. +# +# LIBRARY_OUTPUT_PATH_ROOT should be set in cache to determine where Android +# libraries will be installed. +# Default is ${CMAKE_SOURCE_DIR}, and the android libs will always be +# under the ${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME} +# (depending on the target ABI). This is convenient for Android packaging. +# +# Authors: +# Ethan Rublee ethan.ruble@gmail.com +# Andrey Kamaev andrey.kamaev@itseez.com +# +# Change Log: +# - initial version December 2010 +# - modified April 2011 +# [+] added possibility to build with NDK (without standalone toolchain) +# [+] support cross-compilation on Windows (native, no cygwin support) +# [+] added compiler option to force "char" type to be signed +# [+] added toolchain option to compile to 32-bit ARM instructions +# [+] added toolchain option to disable SWIG search +# [+] added platform "armeabi-v7a with VFPV3" +# [~] ARM_TARGETS renamed to ARM_TARGET +# [+] EXECUTABLE_OUTPUT_PATH is set by toolchain (required on Windows) +# [~] Fixed bug with ANDROID_API_LEVEL variable +# [~] turn off SWIG search if it is not found first time +# - modified May 2011 +# [~] ANDROID_LEVEL is renamed to ANDROID_API_LEVEL +# [+] ANDROID_API_LEVEL is detected by toolchain if not specified +# [~] added guard to prevent changing of output directories on the first +# cmake pass +# [~] toolchain exits with error if ARM_TARGET is not recognized +# - modified June 2011 +# [~] default NDK path is updated for version r5c +# [+] variable CMAKE_SYSTEM_PROCESSOR is set based on ARM_TARGET +# [~] toolchain install directory is added to linker paths +# [-] removed SWIG-related stuff from toolchain +# [+] added macro find_host_package, find_host_program to search +# packages/programs on the host system +# [~] fixed path to STL library +# - modified July 2011 +# [~] fixed options caching +# [~] search for all supported NDK versions +# [~] allowed spaces in NDK path +# - modified September 2011 +# [~] updated for NDK r6b +# - modified November 2011 +# [*] rewritten for NDK r7 +# [+] x86 toolchain support (experimental) +# [+] added "armeabi-v6 with VFP" ABI for ARMv6 processors. +# [~] improved compiler and linker flags management +# [+] support different build flags for Release and Debug configurations +# [~] by default compiler flags the same as used by ndk-build (but only +# where reasonable) +# [~] ANDROID_NDK_TOOLCHAIN_ROOT is splitted to ANDROID_STANDALONE_TOOLCHAIN +# and ANDROID_TOOLCHAIN_ROOT +# [~] ARM_TARGET is renamed to ANDROID_ABI +# [~] ARMEABI_NDK_NAME is renamed to ANDROID_NDK_ABI_NAME +# [~] ANDROID_API_LEVEL is renamed to ANDROID_NATIVE_API_LEVEL +# - modified January 2012 +# [+] added stlport_static support (experimental) +# [+] added special check for cygwin +# [+] filtered out hidden files (starting with .) while globbing inside NDK +# [+] automatically applied GLESv2 linkage fix for NDK revisions 5-6 +# [+] added ANDROID_GET_ABI_RAWNAME to get NDK ABI names by CMake flags +# - modified February 2012 +# [+] updated for NDK r7b +# [~] fixed cmake try_compile() command +# [~] Fix for missing install_name_tool on OS X +# - modified March 2012 +# [~] fixed incorrect C compiler flags +# [~] fixed CMAKE_SYSTEM_PROCESSOR change on ANDROID_ABI change +# [+] improved toolchain loading speed +# [+] added assembler language support (.S) +# [+] allowed preset search paths and extra search suffixes +# - modified April 2012 +# [+] updated for NDK r7c +# [~] fixed most of problems with compiler/linker flags and caching +# [+] added option ANDROID_FUNCTION_LEVEL_LINKING +# - modified May 2012 +# [+] updated for NDK r8 +# [+] added mips architecture support +# - modified August 2012 +# [+] updated for NDK r8b +# [~] all intermediate files generated by toolchain are moved into CMakeFiles +# [~] libstdc++ and libsupc are removed from explicit link libraries +# ------------------------------------------------------------------------------ + +cmake_minimum_required( VERSION 2.6.3 ) + +if( DEFINED CMAKE_CROSSCOMPILING ) + # subsequent toolchain loading is not really needed + return() +endif() + +get_property(_CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if( _CMAKE_IN_TRY_COMPILE ) + include( "${CMAKE_CURRENT_SOURCE_DIR}/../android.toolchain.config.cmake" OPTIONAL ) +endif() + +# this one is important +set( CMAKE_SYSTEM_NAME Linux ) +# this one not so much +set( CMAKE_SYSTEM_VERSION 1 ) + +set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" ) +if(NOT DEFINED ANDROID_NDK_SEARCH_PATHS) + if( CMAKE_HOST_WIN32 ) + file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS ) + set( ANDROID_NDK_SEARCH_PATHS "${ANDROID_NDK_SEARCH_PATHS}/android-ndk" "$ENV{SystemDrive}/NVPACK/android-ndk" ) + else() + file( TO_CMAKE_PATH "$ENV{HOME}" ANDROID_NDK_SEARCH_PATHS ) + set( ANDROID_NDK_SEARCH_PATHS /opt/android-ndk "${ANDROID_NDK_SEARCH_PATHS}/NVPACK/android-ndk" ) + endif() +endif() +if(NOT DEFINED ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH) + set( ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH /opt/android-toolchain ) +endif() + +set( ANDROID_SUPPORTED_ABIS_arm "armeabi-v7a;armeabi;armeabi-v7a with NEON;armeabi-v7a with VFPV3;armeabi-v6 with VFP" ) +set( ANDROID_SUPPORTED_ABIS_x86 "x86" ) +set( ANDROID_SUPPORTED_ABIS_mipsel "mips" ) + +set( ANDROID_DEFAULT_NDK_API_LEVEL 8 ) +set( ANDROID_DEFAULT_NDK_API_LEVEL_x86 9 ) +set( ANDROID_DEFAULT_NDK_API_LEVEL_mips 9 ) + + +macro( __LIST_FILTER listvar regex ) + if( ${listvar} ) + foreach( __val ${${listvar}} ) + if( __val MATCHES "${regex}" ) + list( REMOVE_ITEM ${listvar} "${__val}" ) + endif() + endforeach() + endif() +endmacro() + +macro( __INIT_VARIABLE var_name ) + set( __test_path 0 ) + foreach( __var ${ARGN} ) + if( __var STREQUAL "PATH" ) + set( __test_path 1 ) + break() + endif() + endforeach() + if( __test_path AND NOT EXISTS "${${var_name}}" ) + unset( ${var_name} CACHE ) + endif() + if( "${${var_name}}" STREQUAL "" ) + set( __values 0 ) + foreach( __var ${ARGN} ) + if( __var STREQUAL "VALUES" ) + set( __values 1 ) + elseif( NOT __var STREQUAL "PATH" ) + set( __obsolete 0 ) + if( __var MATCHES "^OBSOLETE_.*$" ) + string( REPLACE "OBSOLETE_" "" __var "${__var}" ) + set( __obsolete 1 ) + endif() + if( __var MATCHES "^ENV_.*$" ) + string( REPLACE "ENV_" "" __var "${__var}" ) + set( __value "$ENV{${__var}}" ) + elseif( DEFINED ${__var} ) + set( __value "${${__var}}" ) + else() + if( __values ) + set( __value "${__var}" ) + else() + set( __value "" ) + endif() + endif() + if( NOT "${__value}" STREQUAL "" ) + if( __test_path ) + if( EXISTS "${__value}" ) + set( ${var_name} "${__value}" ) + if( __obsolete ) + message( WARNING "Using value of obsolete variable ${__var} as initial value for ${var_name}. Please note, that ${__var} can be completely removed in future versions of the toolchain." ) + endif() + break() + endif() + else() + set( ${var_name} "${__value}" ) + if( __obsolete ) + message( WARNING "Using value of obsolete variable ${__var} as initial value for ${var_name}. Please note, that ${__var} can be completely removed in future versions of the toolchain." ) + endif() + break() + endif() + endif() + endif() + endforeach() + unset( __value ) + unset( __values ) + unset( __obsolete ) + endif() + unset( __test_path ) +endmacro() + +macro( __DETECT_NATIVE_API_LEVEL _var _path ) + SET( __ndkApiLevelRegex "^[\t ]*#define[\t ]+__ANDROID_API__[\t ]+([0-9]+)[\t ]*$" ) + FILE( STRINGS ${_path} __apiFileContent REGEX "${__ndkApiLevelRegex}" ) + if( NOT __apiFileContent ) + message( SEND_ERROR "Could not get Android native API level. Probably you have specified invalid level value, or your copy of NDK/toolchain is broken." ) + endif() + string( REGEX REPLACE "${__ndkApiLevelRegex}" "\\1" ${_var} "${__apiFileContent}" ) + unset( __apiFileContent ) + unset( __ndkApiLevelRegex ) +endmacro() + +macro( __DETECT_TOOLCHAIN_MACHINE_NAME _var _root ) + file( GLOB __gccExePath "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" ) + __LIST_FILTER( __gccExePath "bin/[.].*-gcc${TOOL_OS_SUFFIX}$" ) + list( LENGTH __gccExePath __gccExePathsCount ) + if( NOT __gccExePathsCount EQUAL 1 ) + message( WARNING "Could not uniquely determine machine name for compiler from ${_root}." ) + set( ${_var} "" ) + else() + get_filename_component( __gccExeName "${__gccExePath}" NAME_WE ) + string( REPLACE "-gcc" "" ${_var} "${__gccExeName}" ) + endif() + unset( __gccExePath ) + unset( __gccExePathsCount ) + unset( __gccExeName ) +endmacro() + +macro( __COPY_IF_DIFFERENT _source _destination ) + execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${_source}" "${_destination}" RESULT_VARIABLE __fileCopyProcess ) + if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${_destination}") + message( SEND_ERROR "Failed copying of ${_source} to the ${_destination}" ) + endif() + unset( __fileCopyProcess ) +endmacro() + + +# stl version: by default gnustl_static will be used +set( ANDROID_USE_STLPORT FALSE CACHE BOOL "Experimental: use stlport_static instead of gnustl_static") +mark_as_advanced( ANDROID_USE_STLPORT ) + +# fight against cygwin +set( ANDROID_FORBID_SYGWIN TRUE CACHE BOOL "Prevent cmake from working under cygwin and using cygwin tools") +mark_as_advanced( ANDROID_FORBID_SYGWIN ) +if( ANDROID_FORBID_SYGWIN ) + if( CYGWIN ) + message( FATAL_ERROR "Android NDK and android-cmake toolchain are not welcome Cygwin. It is unlikely that this cmake toolchain will work under cygwin. But if you want to try then you can set cmake variable ANDROID_FORBID_SYGWIN to FALSE and rerun cmake." ) + endif() + + if( CMAKE_HOST_WIN32 ) + # remove cygwin from PATH + set( __new_path "$ENV{PATH}") + __LIST_FILTER( __new_path "cygwin" ) + set(ENV{PATH} "${__new_path}") + unset(__new_path) + endif() +endif() + +# detect current host platform +set( TOOL_OS_SUFFIX "" ) +if( CMAKE_HOST_APPLE ) + set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86" ) +elseif( CMAKE_HOST_WIN32 ) + set( ANDROID_NDK_HOST_SYSTEM_NAME "windows" ) + set( TOOL_OS_SUFFIX ".exe" ) +elseif( CMAKE_HOST_UNIX ) + set( ANDROID_NDK_HOST_SYSTEM_NAME "linux-x86" ) +else() + message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" ) +endif() + +# see if we have path to Android NDK +__INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK ) +if( NOT ANDROID_NDK ) + # see if we have path to Android standalone toolchain + __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ENV_ANDROID_STANDALONE_TOOLCHAIN OBSOLETE_ANDROID_NDK_TOOLCHAIN_ROOT OBSOLETE_ENV_ANDROID_NDK_TOOLCHAIN_ROOT ) + + if( NOT ANDROID_STANDALONE_TOOLCHAIN ) + #try to find Android NDK in one of the the default locations + set( __ndkSearchPaths ) + foreach( __ndkSearchPath ${ANDROID_NDK_SEARCH_PATHS} ) + foreach( suffix ${ANDROID_SUPPORTED_NDK_VERSIONS} ) + list( APPEND __ndkSearchPaths "${__ndkSearchPath}${suffix}" ) + endforeach() + endforeach() + __INIT_VARIABLE( ANDROID_NDK PATH VALUES ${__ndkSearchPaths} ) + unset( __ndkSearchPaths ) + + if( ANDROID_NDK ) + message( STATUS "Using default path for Android NDK: ${ANDROID_NDK}" ) + message( STATUS " If you prefer to use a different location, please define a cmake or environment variable: ANDROID_NDK" ) + else() + #try to find Android standalone toolchain in one of the the default locations + __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH ) + + if( ANDROID_STANDALONE_TOOLCHAIN ) + message( STATUS "Using default path for standalone toolchain ${ANDROID_STANDALONE_TOOLCHAIN}" ) + message( STATUS " If you prefer to use a different location, please define the variable: ANDROID_STANDALONE_TOOLCHAIN" ) + endif( ANDROID_STANDALONE_TOOLCHAIN ) + endif( ANDROID_NDK ) + endif( NOT ANDROID_STANDALONE_TOOLCHAIN ) +endif( NOT ANDROID_NDK ) + +# remember found paths +if( ANDROID_NDK ) + get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE ) + # try to detect change + if( CMAKE_AR ) + string( LENGTH "${ANDROID_NDK}" __length ) + string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath ) + if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK ) + message( FATAL_ERROR "It is not possible to change path to the NDK on subsequent run." ) + endif() + unset( __androidNdkPreviousPath ) + unset( __length ) + endif() + set( ANDROID_NDK "${ANDROID_NDK}" CACHE INTERNAL "Path of the Android NDK" ) + set( BUILD_WITH_ANDROID_NDK True ) +elseif( ANDROID_STANDALONE_TOOLCHAIN ) + get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE ) + # try to detect change + if( CMAKE_AR ) + string( LENGTH "${ANDROID_STANDALONE_TOOLCHAIN}" __length ) + string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidStandaloneToolchainPreviousPath ) + if( NOT __androidStandaloneToolchainPreviousPath STREQUAL ANDROID_STANDALONE_TOOLCHAIN ) + message( FATAL_ERROR "It is not possible to change path to the Android standalone toolchain on subsequent run." ) + endif() + unset( __androidStandaloneToolchainPreviousPath ) + unset( __length ) + endif() + set( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" CACHE INTERNAL "Path of the Android standalone toolchain" ) + set( BUILD_WITH_STANDALONE_TOOLCHAIN True ) +else() + list(GET ANDROID_NDK_SEARCH_PATHS 0 ANDROID_NDK_SEARCH_PATH) + message( FATAL_ERROR "Could not find neither Android NDK nor Android standalone toolcahin. + You should either set an environment variable: + export ANDROID_NDK=~/my-android-ndk + or + export ANDROID_STANDALONE_TOOLCHAIN=~/my-android-toolchain + or put the toolchain or NDK in the default path: + sudo ln -s ~/my-android-ndk ${ANDROID_NDK_SEARCH_PATH} + sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" ) +endif() + +# get all the details about standalone toolchain +if( BUILD_WITH_STANDALONE_TOOLCHAIN ) + __DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" ) + set( ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} ) + set( __availableToolchains "standalone" ) + __DETECT_TOOLCHAIN_MACHINE_NAME( __availableToolchainMachines "${ANDROID_STANDALONE_TOOLCHAIN}" ) + if( NOT __availableToolchainMachines ) + message( FATAL_ERROR "Could not determine machine name of your toolchain. Probably your Android standalone toolchain is broken." ) + endif() + if( __availableToolchainMachines MATCHES i686 ) + set( __availableToolchainArchs "x86" ) + elseif( __availableToolchainMachines MATCHES arm ) + set( __availableToolchainArchs "arm" ) + elseif( __availableToolchainMachines MATCHES mipsel ) + set( __availableToolchainArchs "mipsel" ) + endif() + if( ANDROID_COMPILER_VERSION ) + # do not run gcc every time because it is relatevely expencive + set( __availableToolchainCompilerVersions "${ANDROID_COMPILER_VERSION}" ) + else() + execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" --version + OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE ) + string( REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" ) + endif() +endif() + +# get all the details about NDK +if( BUILD_WITH_ANDROID_NDK ) + file( GLOB ANDROID_SUPPORTED_NATIVE_API_LEVELS RELATIVE "${ANDROID_NDK}/platforms" "${ANDROID_NDK}/platforms/android-*" ) + string( REPLACE "android-" "" ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_SUPPORTED_NATIVE_API_LEVELS}" ) + file( GLOB __availableToolchains RELATIVE "${ANDROID_NDK}/toolchains" "${ANDROID_NDK}/toolchains/*" ) + __LIST_FILTER( __availableToolchains "^[.]" ) + set( __availableToolchainMachines "" ) + set( __availableToolchainArchs "" ) + set( __availableToolchainCompilerVersions "" ) + foreach( __toolchain ${__availableToolchains} ) + __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) + if( __machine ) + string( REGEX MATCH "[0-9]+[.][0-9]+[.]*[0-9]*$" __version "${__toolchain}" ) + string( REGEX MATCH "^[^-]+" __arch "${__toolchain}" ) + list( APPEND __availableToolchainMachines "${__machine}" ) + list( APPEND __availableToolchainArchs "${__arch}" ) + list( APPEND __availableToolchainCompilerVersions "${__version}" ) + else() + list( REMOVE_ITEM __availableToolchains "${__toolchain}" ) + endif() + endforeach() + if( NOT __availableToolchains ) + message( FATAL_ERROR "Could not any working toolchain in the NDK. Probably your Android NDK is broken." ) + endif() +endif() + +# build list of available ABIs +if( NOT ANDROID_SUPPORTED_ABIS ) + set( ANDROID_SUPPORTED_ABIS "" ) + set( __uniqToolchainArchNames ${__availableToolchainArchs} ) + list( REMOVE_DUPLICATES __uniqToolchainArchNames ) + list( SORT __uniqToolchainArchNames ) + foreach( __arch ${__uniqToolchainArchNames} ) + list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} ) + endforeach() + unset( __uniqToolchainArchNames ) + if( NOT ANDROID_SUPPORTED_ABIS ) + message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." ) + endif() +endif() + +# choose target ABI +__INIT_VARIABLE( ANDROID_ABI OBSOLETE_ARM_TARGET OBSOLETE_ARM_TARGETS VALUES ${ANDROID_SUPPORTED_ABIS} ) +# verify that target ABI is supported +list( FIND ANDROID_SUPPORTED_ABIS "${ANDROID_ABI}" __androidAbiIdx ) +if( __androidAbiIdx EQUAL -1 ) + string( REPLACE ";" "\", \"", PRINTABLE_ANDROID_SUPPORTED_ABIS "${ANDROID_SUPPORTED_ABIS}" ) + message( FATAL_ERROR "Specified ANDROID_ABI = \"${ANDROID_ABI}\" is not supported by this cmake toolchain or your NDK/toolchain. + Supported values are: \"${PRINTABLE_ANDROID_SUPPORTED_ABIS}\" + " ) +endif() +unset( __androidAbiIdx ) + +# remember target ABI +set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE ) + +# set target ABI options +if( ANDROID_ABI STREQUAL "x86" ) + set( X86 true ) + set( ANDROID_NDK_ABI_NAME "x86" ) + set( ANDROID_ARCH_NAME "x86" ) + set( ANDROID_ARCH_FULLNAME "x86" ) + set( CMAKE_SYSTEM_PROCESSOR "i686" ) +elseif( ANDROID_ABI STREQUAL "mips" ) + set( MIPS true ) + set( ANDROID_NDK_ABI_NAME "mips" ) + set( ANDROID_ARCH_NAME "mips" ) + set( ANDROID_ARCH_FULLNAME "mipsel" ) + set( CMAKE_SYSTEM_PROCESSOR "mips" ) +elseif( ANDROID_ABI STREQUAL "armeabi" ) + set( ARMEABI true ) + set( ANDROID_NDK_ABI_NAME "armeabi" ) + set( ANDROID_ARCH_NAME "arm" ) + set( ANDROID_ARCH_FULLNAME "arm" ) + set( CMAKE_SYSTEM_PROCESSOR "armv5te" ) +elseif( ANDROID_ABI STREQUAL "armeabi-v6 with VFP" ) + set( ARMEABI_V6 true ) + set( ANDROID_NDK_ABI_NAME "armeabi" ) + set( ANDROID_ARCH_NAME "arm" ) + set( ANDROID_ARCH_FULLNAME "arm" ) + set( CMAKE_SYSTEM_PROCESSOR "armv6" ) + # need always fallback to older platform + set( ARMEABI true ) +elseif( ANDROID_ABI STREQUAL "armeabi-v7a") + set( ARMEABI_V7A true ) + set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) + set( ANDROID_ARCH_NAME "arm" ) + set( ANDROID_ARCH_FULLNAME "arm" ) + set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) +elseif( ANDROID_ABI STREQUAL "armeabi-v7a with VFPV3" ) + set( ARMEABI_V7A true ) + set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) + set( ANDROID_ARCH_NAME "arm" ) + set( ANDROID_ARCH_FULLNAME "arm" ) + set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) + set( VFPV3 true ) +elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" ) + set( ARMEABI_V7A true ) + set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) + set( ANDROID_ARCH_NAME "arm" ) + set( ANDROID_ARCH_FULLNAME "arm" ) + set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) + set( VFPV3 true ) + set( NEON true ) +else() + message( SEND_ERROR "Unknown ANDROID_ABI=\"${ANDROID_ABI}\" is specified." ) +endif() + +if( CMAKE_BINARY_DIR AND EXISTS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" ) + # really dirty hack + # it is not possible to change CMAKE_SYSTEM_PROCESSOR after the first run... + file( APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" "SET(CMAKE_SYSTEM_PROCESSOR \"${CMAKE_SYSTEM_PROCESSOR}\")\n" ) +endif() + +set( ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} CACHE INTERNAL "ANDROID_ABI can be changed only to one of these ABIs. Changing to any other ABI requires to reset cmake cache." ) +if( CMAKE_VERSION VERSION_GREATER "2.8" ) + list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME} ) + set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} ) +endif() + +if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 ) + __INIT_VARIABLE( ANDROID_FORCE_ARM_BUILD OBSOLETE_FORCE_ARM VALUES OFF ) + set( ANDROID_FORCE_ARM_BUILD ${ANDROID_FORCE_ARM_BUILD} CACHE BOOL "Use 32-bit ARM instructions instead of Thumb-1" FORCE ) + mark_as_advanced( ANDROID_FORCE_ARM_BUILD ) +else() + unset( ANDROID_FORCE_ARM_BUILD CACHE ) +endif() + +# choose toolchain +if( ANDROID_TOOLCHAIN_NAME ) + list( FIND __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" __toolchainIdx ) + if( __toolchainIdx EQUAL -1 ) + message( FATAL_ERROR "Previously selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing. You need to remove CMakeCache.txt and rerun cmake manually to change the toolchain" ) + endif() + list( GET __availableToolchainArchs ${__toolchainIdx} __toolchainArch ) + if( NOT __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME ) + message( SEND_ERROR "Previously selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." ) + endif() +else() + set( __toolchainIdx -1 ) + set( __applicableToolchains "" ) + set( __toolchainMaxVersion "0.0.0" ) + list( LENGTH __availableToolchains __availableToolchainsCount ) + math( EXPR __availableToolchainsCount "${__availableToolchainsCount}-1" ) + foreach( __idx RANGE ${__availableToolchainsCount} ) + list( GET __availableToolchainArchs ${__idx} __toolchainArch ) + if( __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME ) + list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion ) + if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion ) + set( __toolchainMaxVersion "${__toolchainVersion}" ) + set( __toolchainIdx ${__idx} ) + endif() + endif() + endforeach() + unset( __availableToolchainsCount ) + unset( __toolchainMaxVersion ) + unset( __toolchainVersion ) +endif() +unset( __toolchainArch ) +if( __toolchainIdx EQUAL -1 ) + message( FATAL_ERROR "No one of available compiler toolchains is able to compile for ${ANDROID_ARCH_NAME} platform." ) +endif() +list( GET __availableToolchains ${__toolchainIdx} ANDROID_TOOLCHAIN_NAME ) +list( GET __availableToolchainMachines ${__toolchainIdx} ANDROID_TOOLCHAIN_MACHINE_NAME ) +list( GET __availableToolchainCompilerVersions ${__toolchainIdx} ANDROID_COMPILER_VERSION ) +set( ANDROID_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" CACHE INTERNAL "Name of toolchain used" ) +set( ANDROID_COMPILER_VERSION "${ANDROID_COMPILER_VERSION}" CACHE INTERNAL "compiler version from selected toolchain" ) +unset( __toolchainIdx ) +unset( __availableToolchains ) +unset( __availableToolchainMachines ) +unset( __availableToolchainArchs ) +unset( __availableToolchainCompilerVersions ) + +# choose native API level +__INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL ) +string( REGEX MATCH "[0-9]+" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" ) +# validate +list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx ) +if( __levelIdx EQUAL -1 ) + message( SEND_ERROR "Specified Android native API level (${ANDROID_NATIVE_API_LEVEL}) is not supported by your NDK/toolchain." ) +endif() +unset( __levelIdx ) +if( BUILD_WITH_ANDROID_NDK ) + __DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" ) + if( NOT __realApiLevel EQUAL ANDROID_NATIVE_API_LEVEL ) + message( SEND_ERROR "Specified Android API level (${ANDROID_NATIVE_API_LEVEL}) does not match to the level found (${__realApiLevel}). Probably your copy of NDK is broken." ) + endif() + unset( __realApiLevel ) +endif() +set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE ) +if( CMAKE_VERSION VERSION_GREATER "2.8" ) + list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS ) + set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} ) +endif() + +# setup paths +if( BUILD_WITH_STANDALONE_TOOLCHAIN ) + set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" ) + set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" ) + set( __stlLibPath "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib" ) +endif() +if( BUILD_WITH_ANDROID_NDK ) + set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) + set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" ) + if( ANDROID_USE_STLPORT ) + set( __stlIncludePath "${ANDROID_NDK}/sources/cxx-stl/stlport/stlport" ) + set( __stlLibPath "${ANDROID_NDK}/sources/cxx-stl/stlport/libs/${ANDROID_NDK_ABI_NAME}" ) + else() + if( EXISTS "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" ) + set( __stlIncludePath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/include" ) + set( __stlLibPath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}" ) + else() + set( __stlIncludePath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/include" ) + set( __stlLibPath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}" ) + endif() + endif() +endif() + +# specify the cross compiler +set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "gcc" ) +set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "g++" ) +set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "Assembler" ) +if( CMAKE_VERSION VERSION_LESS 2.8.5 ) + set( CMAKE_ASM_COMPILER_ARG1 "-c" ) +endif() +# there may be a way to make cmake deduce these TODO deduce the rest of the tools +set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" ) +set( CMAKE_AR "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" ) +set( CMAKE_LINKER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ld${TOOL_OS_SUFFIX}" CACHE PATH "linker" ) +set( CMAKE_NM "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-nm${TOOL_OS_SUFFIX}" CACHE PATH "nm" ) +set( CMAKE_OBJCOPY "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" ) +set( CMAKE_OBJDUMP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump" ) +set( CMAKE_RANLIB "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ranlib${TOOL_OS_SUFFIX}" CACHE PATH "ranlib" ) +set( _CMAKE_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_MACHINE_NAME}-" ) +if( APPLE ) + find_program( CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool ) + if( NOT CMAKE_INSTALL_NAME_TOOL ) + message( FATAL_ERROR "Could not find install_name_tool, please check your installation." ) + endif() + mark_as_advanced( CMAKE_INSTALL_NAME_TOOL ) +endif() + +# export directories +set( ANDROID_SYSTEM_INCLUDE_DIRS "" ) +set( ANDROID_SYSTEM_LIB_DIRS "" ) + +# setup output directories +set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" ) +set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" ) + +if(NOT _CMAKE_IN_TRY_COMPILE) + if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" ) + set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" ) + else() + set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" ) + endif() + set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" ) +endif() + +# includes +list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_SYSROOT}/usr/include" ) +if( __stlIncludePath AND EXISTS "${__stlIncludePath}" ) + list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${__stlIncludePath}" ) +endif() + +# c++ bits includes +if( __stlLibPath AND EXISTS "${__stlLibPath}/include" ) + list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${__stlLibPath}/include" ) +endif() +if( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/thumb/bits" ) + list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/thumb" ) +elseif( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" ) + list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" ) +elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" ) + list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb" ) +elseif( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/bits" ) + list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" ) +endif() + +# flags and definitions +if(ANDROID_SYSROOT MATCHES "[ ;\"]") + set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" ) + # quotes will break try_compile and compiler identification + message(WARNING "Your Android system root has non-alphanumeric symbols. It can break compiler features detection and the whole build.") +else() + set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" ) +endif() + +remove_definitions( -DANDROID ) +add_definitions( -DANDROID ) + +# Force set compilers because standard identification works badly for us +include( CMakeForceCompiler ) +CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU ) +set( CMAKE_C_PLATFORM_ID Linux ) +set( CMAKE_C_SIZEOF_DATA_PTR 4 ) +set( CMAKE_C_HAS_ISYSROOT 1 ) +set( CMAKE_C_COMPILER_ABI ELF ) +CMAKE_FORCE_CXX_COMPILER( "${CMAKE_CXX_COMPILER}" GNU ) +set( CMAKE_CXX_PLATFORM_ID Linux ) +set( CMAKE_CXX_SIZEOF_DATA_PTR 4 ) +set( CMAKE_CXX_HAS_ISYSROOT 1 ) +set( CMAKE_CXX_COMPILER_ABI ELF ) +# force ASM compiler (required for CMake < 2.8.5) +set( CMAKE_ASM_COMPILER_ID_RUN TRUE ) +set( CMAKE_ASM_COMPILER_ID GNU ) +set( CMAKE_ASM_COMPILER_WORKS TRUE ) +set( CMAKE_ASM_COMPILER_FORCED TRUE ) +set( CMAKE_COMPILER_IS_GNUASM 1) + +# NDK flags +if( ARMEABI OR ARMEABI_V7A ) + # NDK also defines -ffunction-sections -funwind-tables but they result in worse OpenCV performance + set( _CMAKE_CXX_FLAGS "-fPIC -Wno-psabi" ) + set( _CMAKE_C_FLAGS "-fPIC -Wno-psabi" ) + remove_definitions( -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ ) + add_definitions( -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ ) + # extra arm-specific flags + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) +elseif( X86 ) + set( _CMAKE_CXX_FLAGS "-funwind-tables" ) + set( _CMAKE_C_FLAGS "-funwind-tables" ) +elseif( MIPS ) + set( _CMAKE_CXX_FLAGS "-fpic -Wno-psabi -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" ) + set( _CMAKE_CXX_FLAGS "-fpic -Wno-psabi -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) +else() + set( _CMAKE_CXX_FLAGS "" ) + set( _CMAKE_C_FLAGS "" ) +endif() + +if( ANDROID_USE_STLPORT ) + set( _CMAKE_CXX_FLAGS "${_CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions" ) + set( _CMAKE_C_FLAGS "${_CMAKE_C_FLAGS} -fno-exceptions" ) +else() + set( _CMAKE_CXX_FLAGS "${_CMAKE_CXX_FLAGS} -frtti -fexceptions" ) + set( _CMAKE_C_FLAGS "${_CMAKE_C_FLAGS} -fexceptions" ) +endif() + +# release and debug flags +if( ARMEABI OR ARMEABI_V7A ) + if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 ) + # It is recommended to use the -mthumb compiler flag to force the generation + # of 16-bit Thumb-1 instructions (the default being 32-bit ARM ones). + # O3 instead of O2/Os in release mode - like cmake sets for desktop gcc + set( _CMAKE_CXX_FLAGS_RELEASE "-mthumb -O3" ) + set( _CMAKE_C_FLAGS_RELEASE "-mthumb -O3" ) + set( _CMAKE_CXX_FLAGS_DEBUG "-marm -Os -finline-limit=64" ) + set( _CMAKE_C_FLAGS_DEBUG "-marm -Os -finline-limit=64" ) + else() + # always compile ARMEABI_V6 in arm mode; otherwise there is no difference from ARMEABI + # O3 instead of O2/Os in release mode - like cmake sets for desktop gcc + set( _CMAKE_CXX_FLAGS_RELEASE "-marm -O3 -fstrict-aliasing" ) + set( _CMAKE_C_FLAGS_RELEASE "-marm -O3 -fstrict-aliasing" ) + set( _CMAKE_CXX_FLAGS_DEBUG "-marm -O0 -finline-limit=300" ) + set( _CMAKE_C_FLAGS_DEBUG "-marm -O0 -finline-limit=300" ) + endif() +elseif( X86 ) + set( _CMAKE_CXX_FLAGS_RELEASE "-O3 -fstrict-aliasing" ) + set( _CMAKE_C_FLAGS_RELEASE "-O3 -fstrict-aliasing" ) + set( _CMAKE_CXX_FLAGS_DEBUG "-O0 -finline-limit=300" ) + set( _CMAKE_C_FLAGS_DEBUG "-O0 -finline-limit=300" ) +elseif( MIPS ) + set( _CMAKE_CXX_FLAGS_RELEASE "-O3 -funswitch-loops -finline-limit=300" ) + set( _CMAKE_C_FLAGS_RELEASE "-O3 -funswitch-loops -finline-limit=300" ) + set( _CMAKE_CXX_FLAGS_DEBUG "-O0 -g" ) + set( _CMAKE_C_FLAGS_DEBUG "-O0 -g" ) +endif() +set( _CMAKE_CXX_FLAGS_RELEASE "${_CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -DNDEBUG" ) +set( _CMAKE_C_FLAGS_RELEASE "${_CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer -DNDEBUG" ) +set( _CMAKE_CXX_FLAGS_DEBUG "${_CMAKE_CXX_FLAGS_DEBUG} -fno-strict-aliasing -fno-omit-frame-pointer -DDEBUG -D_DEBUG" ) +set( _CMAKE_C_FLAGS_DEBUG "${_CMAKE_C_FLAGS_DEBUG} -fno-strict-aliasing -fno-omit-frame-pointer -DDEBUG -D_DEBUG" ) + +# ABI-specific flags +if( ARMEABI_V7A ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv7-a -mfloat-abi=softfp" ) + if( NEON ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=neon" ) + elseif( VFPV3 ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3" ) + else() + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfp" ) + endif() +elseif( ARMEABI_V6 ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" ) +elseif( ARMEABI ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" ) +elseif( X86 ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" )#sse? +endif() + +# linker flags +if( NOT DEFINED __ndklibspath ) + set( __ndklibspath "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/ndklibs/${ANDROID_NDK_ABI_NAME}" ) +endif() +list( APPEND ANDROID_SYSTEM_LIB_DIRS "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" ) +set( ANDROID_LINKER_FLAGS "" ) + +# STL +if( ANDROID_USE_STLPORT ) + if( EXISTS "${__stlLibPath}/libstlport_static.a" ) + set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o \"${__stlLibPath}/libstlport_static.a\"") + set( CMAKE_CXX_CREATE_SHARED_MODULE " -o \"${__stlLibPath}/libstlport_static.a\"") + endif() +else( ANDROID_USE_STLPORT ) + if( EXISTS "${__stlLibPath}/libgnustl_static.a" ) + __COPY_IF_DIFFERENT( "${__stlLibPath}/libgnustl_static.a" "${__ndklibspath}/libstdc++.a" ) + elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" ) + __COPY_IF_DIFFERENT( "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" "${__ndklibspath}/libstdc++.a" ) + elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" ) + __COPY_IF_DIFFERENT( "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" "${__ndklibspath}/libstdc++.a" ) + elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${__stlLibPath}/thumb/libstdc++.a" ) + __COPY_IF_DIFFERENT( "${__stlLibPath}/thumb/libstdc++.a" "${__ndklibspath}/libstdc++.a" ) + elseif( EXISTS "${__stlLibPath}/libstdc++.a" ) + __COPY_IF_DIFFERENT( "${__stlLibPath}/libstdc++.a" "${__ndklibspath}/libstdc++.a" ) + endif() + if( EXISTS "${__stlLibPath}/libsupc++.a" ) + __COPY_IF_DIFFERENT( "${__stlLibPath}/libsupc++.a" "${__ndklibspath}/libsupc++.a" ) + elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" ) + __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" "${__ndklibspath}/libsupc++.a" ) + elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" ) + __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" "${__ndklibspath}/libsupc++.a" ) + elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" ) + __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" "${__ndklibspath}/libsupc++.a" ) + elseif( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" ) + __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" "${__ndklibspath}/libsupc++.a" ) + endif() + list( APPEND ANDROID_SYSTEM_LIB_DIRS "${__ndklibspath}" ) +endif( ANDROID_USE_STLPORT ) + +# cleanup for STL search +unset( __stlIncludePath ) +unset( __stlLibPath ) + +# other linker flags +__INIT_VARIABLE( ANDROID_NO_UNDEFINED OBSOLETE_NO_UNDEFINED VALUES ON ) +set( ANDROID_NO_UNDEFINED ${ANDROID_NO_UNDEFINED} CACHE BOOL "Show all undefined symbols as linker errors" FORCE ) +mark_as_advanced( ANDROID_NO_UNDEFINED ) +if( ANDROID_NO_UNDEFINED ) + set( ANDROID_LINKER_FLAGS "-Wl,--no-undefined ${ANDROID_LINKER_FLAGS}" ) +endif() + +if (ANDROID_NDK MATCHES "-r[56].?$") + # libGLESv2.so in NDK's prior to r7 refers to exteranal symbols. So this flag option is required for all projects using OpenGL from native. + __INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES ON ) +else() + __INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES OFF ) +endif() + +set( ANDROID_SO_UNDEFINED ${ANDROID_SO_UNDEFINED} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" FORCE ) +mark_as_advanced( ANDROID_SO_UNDEFINED ) +if( ANDROID_SO_UNDEFINED ) + set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-allow-shlib-undefined" ) +endif() + +__INIT_VARIABLE( ANDROID_FUNCTION_LEVEL_LINKING VALUES ON ) +set( ANDROID_FUNCTION_LEVEL_LINKING ON CACHE BOOL "Allows or disallows undefined symbols in shared libraries" FORCE ) +mark_as_advanced( ANDROID_FUNCTION_LEVEL_LINKING ) +if( ANDROID_FUNCTION_LEVEL_LINKING ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" ) + set( ANDROID_LINKER_FLAGS "-Wl,--gc-sections ${ANDROID_LINKER_FLAGS}" ) +endif() + +if( ARMEABI_V7A ) + # this is *required* to use the following linker flags that routes around + # a CPU bug in some Cortex-A8 implementations: + set( ANDROID_LINKER_FLAGS "-Wl,--fix-cortex-a8 ${ANDROID_LINKER_FLAGS}" ) +endif() + +# cache flags +set( CMAKE_CXX_FLAGS "${_CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags" ) +set( CMAKE_C_FLAGS "${_CMAKE_C_FLAGS}" CACHE STRING "c flags" ) +set( CMAKE_CXX_FLAGS_RELEASE "${_CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "c++ Release flags" ) +set( CMAKE_C_FLAGS_RELEASE "${_CMAKE_C_FLAGS_RELEASE}" CACHE STRING "c Release flags" ) +set( CMAKE_CXX_FLAGS_DEBUG "${_CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "c++ Debug flags" ) +set( CMAKE_C_FLAGS_DEBUG "${_CMAKE_C_FLAGS_DEBUG}" CACHE STRING "c Debug flags" ) +set( CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "linker flags" ) +set( CMAKE_MODULE_LINKER_FLAGS "" CACHE STRING "linker flags" ) +set( CMAKE_EXE_LINKER_FLAGS "-Wl,-z,nocopyreloc" CACHE STRING "linker flags" ) + +include_directories( SYSTEM ${ANDROID_SYSTEM_INCLUDE_DIRS} ) +link_directories( ${ANDROID_SYSTEM_LIB_DIRS} ) + +# finish flags +set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Extra Android compiler flags") +set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}" CACHE INTERNAL "Extra Android linker flags") +set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" ) +set( CMAKE_C_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" ) +if( MIPS AND BUILD_WITH_ANDROID_NDK ) + set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.xsc ${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" ) + set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.xsc ${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" ) + set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.x ${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" ) +else() + set( CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" ) + set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" ) + set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" ) +endif() + +# set these global flags for cmake client scripts to change behavior +set( ANDROID True ) +set( BUILD_ANDROID True ) + +# where is the target environment +set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_ROOT}/bin" "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" "${ANDROID_SYSROOT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share" ) + +# only search for libraries and includes in the ndk toolchain +set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) +set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) +set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) + + +# macro to find packages on the host OS +macro( find_host_package ) + set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) + set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER ) + set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER ) + if( CMAKE_HOST_WIN32 ) + SET( WIN32 1 ) + SET( UNIX ) + elseif( CMAKE_HOST_APPLE ) + SET( APPLE 1 ) + SET( UNIX ) + endif() + find_package( ${ARGN} ) + SET( WIN32 ) + SET( APPLE ) + SET( UNIX 1 ) + set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) + set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) + set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) +endmacro() + + +# macro to find programs on the host OS +macro( find_host_program ) + set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) + set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER ) + set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER ) + if( CMAKE_HOST_WIN32 ) + SET( WIN32 1 ) + SET( UNIX ) + elseif( CMAKE_HOST_APPLE ) + SET( APPLE 1 ) + SET( UNIX ) + endif() + find_program( ${ARGN} ) + SET( WIN32 ) + SET( APPLE ) + SET( UNIX 1 ) + set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) + set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) + set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) +endmacro() + + +macro( ANDROID_GET_ABI_RAWNAME TOOLCHAIN_FLAG VAR ) + if( "${TOOLCHAIN_FLAG}" STREQUAL "ARMEABI" ) + set( ${VAR} "armeabi" ) + elseif( "${TOOLCHAIN_FLAG}" STREQUAL "ARMEABI_V7A" ) + set( ${VAR} "armeabi-v7a" ) + elseif( "${TOOLCHAIN_FLAG}" STREQUAL "X86" ) + set( ${VAR} "x86" ) + else() + set( ${VAR} "unknown" ) + endif() +endmacro() + + +# export toolchain settings for the try_compile() command +if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" ) + set( __toolchain_config "") + foreach( __var ANDROID_ABI ANDROID_FORCE_ARM_BUILD ANDROID_NATIVE_API_LEVEL ANDROID_NO_UNDEFINED ANDROID_SO_UNDEFINED ANDROID_SET_OBSOLETE_VARIABLES LIBRARY_OUTPUT_PATH_ROOT ANDROID_USE_STLPORT ANDROID_FORBID_SYGWIN ANDROID_NDK ANDROID_STANDALONE_TOOLCHAIN ANDROID_FUNCTION_LEVEL_LINKING __ndklibspath ) + if( DEFINED ${__var} ) + if( "${__var}" MATCHES " ") + set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" CACHE INTERNAL \"\" )\n" ) + else() + set( __toolchain_config "${__toolchain_config}set( ${__var} ${${__var}} CACHE INTERNAL \"\" )\n" ) + endif() + endif() + endforeach() + file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/android.toolchain.config.cmake" "${__toolchain_config}" ) + unset( __toolchain_config ) + unset( __ndklibspath ) +endif() + + +# set some obsolete variables for backward compatibility +set( ANDROID_SET_OBSOLETE_VARIABLES ON CACHE BOOL "Define obsolete Andrid-specific cmake variables" ) +mark_as_advanced( ANDROID_SET_OBSOLETE_VARIABLES ) +if( ANDROID_SET_OBSOLETE_VARIABLES ) + set( ANDROID_API_LEVEL ${ANDROID_NATIVE_API_LEVEL} ) + set( ARM_TARGET "${ANDROID_ABI}" ) + set( ARMEABI_NDK_NAME "${ANDROID_NDK_ABI_NAME}" ) +endif() + + +# Variables controlling behavior or set by cmake toolchain: +# ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips" +# ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14 (depends on NDK version) +# ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF +# ANDROID_USE_STLPORT : OFF/ON - EXPERIMENTAL!!! +# ANDROID_FORBID_SYGWIN : ON/OFF +# ANDROID_NO_UNDEFINED : ON/OFF +# ANDROID_SO_UNDEFINED : OFF/ON (default depends on NDK version) +# ANDROID_FUNCTION_LEVEL_LINKING : ON/OFF +# Variables that takes effect only at first run: +# ANDROID_FORCE_ARM_BUILD : ON/OFF +# LIBRARY_OUTPUT_PATH_ROOT : +# Can be set only at the first run: +# ANDROID_NDK +# ANDROID_STANDALONE_TOOLCHAIN +# ANDROID_TOOLCHAIN_NAME : "arm-linux-androideabi-4.4.3" or "arm-linux-androideabi-4.6" or "mipsel-linux-android-4.4.3" or "mipsel-linux-android-4.6" or "x86-4.4.3" or "x86-4.6" +# Obsolete: +# ANDROID_API_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL +# ARM_TARGET : superseded by ANDROID_ABI +# ARM_TARGETS : superseded by ANDROID_ABI (can be set only) +# ANDROID_NDK_TOOLCHAIN_ROOT : superseded by ANDROID_STANDALONE_TOOLCHAIN (can be set only) +# ANDROID_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL (completely removed) +# +# Primary read-only variables: +# ANDROID : always TRUE +# ARMEABI : TRUE for arm v6 and older devices +# ARMEABI_V6 : TRUE for arm v6 +# ARMEABI_V7A : TRUE for arm v7a +# NEON : TRUE if NEON unit is enabled +# VFPV3 : TRUE if VFP version 3 is enabled +# X86 : TRUE if configured for x86 +# BUILD_ANDROID : always TRUE +# BUILD_WITH_ANDROID_NDK : TRUE if NDK is used +# BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used +# ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform +# ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a" or "x86" depending on ANDROID_ABI +# ANDROID_ARCH_NAME : "arm" or "x86" or "mips" depending on ANDROID_ABI +# TOOL_OS_SUFFIX : "" or ".exe" depending on host platform +# ANDROID_SYSROOT : path to the compiler sysroot +# ANDROID_SYSTEM_INCLUDE_DIRS +# ANDROID_SYSTEM_LIB_DIRS +# Obsolete: +# ARMEABI_NDK_NAME : superseded by ANDROID_NDK_ABI_NAME +# +# Secondary (less stable) read-only variables: +# ANDROID_COMPILER_VERSION : GCC version used +# ANDROID_CXX_FLAGS : C/C++ compiler flags required by Android platform +# ANDROID_SUPPORTED_ABIS : list of currently allowed values for ANDROID_ABI +# ANDROID_TOOLCHAIN_MACHINE_NAME : "arm-linux-androideabi", "arm-eabi" or "i686-android-linux" +# ANDROID_TOOLCHAIN_ROOT : path to the top level of toolchain (standalone or placed inside NDK) +# ANDROID_SUPPORTED_NATIVE_API_LEVELS : list of native API levels found inside NDK +# +# Defaults: +# ANDROID_DEFAULT_NDK_API_LEVEL +# ANDROID_DEFAULT_NDK_API_LEVEL_${ARCH} +# ANDROID_NDK_SEARCH_PATHS +# ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH +# ANDROID_SUPPORTED_ABIS_${ARCH} +# ANDROID_SUPPORTED_NDK_VERSIONS diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index e434bdc35..ebe145f2c 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -3,6 +3,8 @@ if((CMAKE_SYSTEM_PROCESSOR MATCHES "i386|i686|x86") AND (CMAKE_SIZEOF_VOID_P EQU set(TARGET_ARCH "x86") elseif((CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") AND (CMAKE_SIZEOF_VOID_P EQUAL 8)) set(TARGET_ARCH "x64") +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm*") + set(TARGET_ARCH "ARM") endif() option(WITH_MANPAGES "Generate manpages." ON) @@ -14,7 +16,11 @@ else() option(WITH_SSE2 "Enable SSE2 optimization." OFF) endif() -option(WITH_NEON "Enable NEON optimization." OFF) +if((TARGET_ARCH MATCHES "ARM") AND (NOT DEFINED WITH_NEON)) + option(WITH_NEON "Enable NEON optimization." ON) +else() + option(WITH_NEON "Enable NEON optimization." OFF) +endif() option(WITH_JPEG "Use JPEG decoding." OFF) @@ -31,13 +37,18 @@ option(BUILD_TESTING "Build unit tests" OFF) option(WITH_SAMPLE "Build sample code" OFF) if(${CMAKE_VERSION} VERSION_GREATER 2.8.8) - option(MONOLITHIC_BUILD "Use monolithic build" OFF) + if(ANDROID) + option(MONOLITHIC_BUILD "Use monolithic build" ON) + else() + option(MONOLITHIC_BUILD "Use monolithic build" OFF) + endif() endif() option(WITH_CLIENT "Build client binaries" ON) option(WITH_SERVER "Build server binaries" OFF) option(STATIC_CHANNELS "Build channels statically" ON) + option(WITH_CHANNELS "Build virtual channel plugins" ON) if(WITH_CLIENT AND WITH_CHANNELS) diff --git a/include/freerdp/client/file.h b/include/freerdp/client/file.h index d9e7dbc5a..c7f2525f0 100644 --- a/include/freerdp/client/file.h +++ b/include/freerdp/client/file.h @@ -20,6 +20,7 @@ #ifndef FREERDP_CLIENT_RDP_FILE #define FREERDP_CLIENT_RDP_FILE +#include #include struct rdp_file @@ -71,8 +72,8 @@ struct rdp_file LPSTR Domain; /* domain */ PBYTE Password51; /* password 51 */ - LPTSTR FullAddress; /* full address */ - LPTSTR AlternateFullAddress; /* alternate full address */ + LPSTR FullAddress; /* full address */ + LPSTR AlternateFullAddress; /* alternate full address */ DWORD ServerPort; /* server port */ DWORD RedirectDrives; /* redirectdrives */ @@ -98,7 +99,7 @@ struct rdp_file DWORD PromptForCredentialsOnce; /* promptcredentialonce */ DWORD NegotiateSecurityLayer; /* negotiate security layer */ DWORD EnableCredSSPSupport; /* enablecredsspsupport */ - LPSTR LoadBalanceInfo; /* LoadBalanceInfo */ + LPSTR LoadBalanceInfo; /* loadbalanceinfo */ DWORD RemoteApplicationMode; /* remoteapplicationmode */ LPSTR RemoteApplicationName; /* remoteapplicationname */ @@ -115,14 +116,14 @@ struct rdp_file LPSTR ShellWorkingDirectory; /* shell working directory */ LPSTR GatewayHostname; /* gatewayhostname */ - LPSTR GatewayUsageMethod; /* gatewayusagemethod */ - LPSTR GatewayProfileUsageMethod; /* gatewayprofileusagemethod */ - LPSTR GatewayCredentialsSource; /* gatewaycredentialssource */ + DWORD GatewayUsageMethod; /* gatewayusagemethod */ + DWORD GatewayProfileUsageMethod; /* gatewayprofileusagemethod */ + DWORD GatewayCredentialsSource; /* gatewaycredentialssource */ DWORD UseRedirectionServerName; /* use redirection server name */ DWORD RdgIsKdcProxy; /* rdgiskdcproxy */ - DWORD KdcProxyName; /* kdcproxyname */ + LPSTR KdcProxyName; /* kdcproxyname */ LPSTR DrivesToRedirect; /* drivestoredirect */ LPSTR DevicesToRedirect; /* devicestoredirect */ @@ -131,4 +132,11 @@ struct rdp_file typedef struct rdp_file rdpFile; +FREERDP_API BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name); +FREERDP_API BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t size); +FREERDP_API BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings); + +FREERDP_API rdpFile* freerdp_client_rdp_file_new(); +FREERDP_API void freerdp_client_rdp_file_free(rdpFile* file); + #endif /* FREERDP_CLIENT_RDP_FILE */ diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 16d01b0ed..a8577b27d 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -301,7 +301,11 @@ struct rdp_settings ALIGN64 BOOL send_preconnection_pdu; /* 72 */ ALIGN64 UINT32 preconnection_id; /* 73 */ ALIGN64 char* preconnection_blob; /* 74 */ - UINT64 paddingC[80 - 75]; /* 75 */ + ALIGN64 char* computer_name; /* 75 */ + ALIGN64 char* connection_file; /* 76 */ + ALIGN64 char* tsg_domain; /* 77 */ + ALIGN64 BOOL tsg_same_credentials; /* 78 */ + UINT64 paddingC[80 - 79]; /* 79 */ /* User Interface Parameters */ ALIGN64 BOOL sw_gdi; /* 80 */ diff --git a/libfreerdp/codec/CMakeLists.txt b/libfreerdp/codec/CMakeLists.txt index 99a5f381a..6481fa0fd 100644 --- a/libfreerdp/codec/CMakeLists.txt +++ b/libfreerdp/codec/CMakeLists.txt @@ -61,17 +61,24 @@ if(WITH_SSE2) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_SSE2_SRCS}) if(CMAKE_COMPILER_IS_GNUCC) - set_property(SOURCE rfx_sse2.c nsc_sse2.c PROPERTY COMPILE_FLAGS "-msse2") + set_source_files_properties(${${MODULE_PREFIX}_SSE2_SRCS} PROPERTIES COMPILE_FLAGS "-msse2") endif() if(MSVC) - set_property(SOURCE rfx_sse2.c nsc_sse2.c PROPERTY COMPILE_FLAGS "/arch:SSE2") + set_source_files_properties(${${MODULE_PREFIX}_SSE2_SRCS} PROPERTIES COMPILE_FLAGS "/arch:SSE2") endif() endif() if(WITH_NEON) + if(ANDROID) + set(ANDROID_CPU_FEATURES_PATH "${ANDROID_NDK}/sources/android/cpufeatures") + include_directories(${ANDROID_CPU_FEATURES_PATH}) + set(${MODULE_PREFIX}_NEON_SRCS ${${MODULE_PREFIX}_NEON_SRCS} + ${ANDROID_CPU_FEATURES_PATH}/cpu-features.c + ${ANDROID_CPU_FEATURES_PATH}/cpu-features.h) + endif() set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_NEON_SRCS}) - set_property(SOURCE rfx_neon.c PROPERTY COMPILE_FLAGS "-mfpu=neon -mfloat-abi=softfp") + set_source_files_properties(${${MODULE_PREFIX}_NEON_SRCS} PROPERTIES COMPILE_FLAGS "-mfpu=neon -mfloat-abi=softfp -Wno-unused-variable") endif() if(WITH_JPEG) diff --git a/libfreerdp/codec/rfx_neon.c b/libfreerdp/codec/rfx_neon.c index fc84440c4..11965e4b1 100644 --- a/libfreerdp/codec/rfx_neon.c +++ b/libfreerdp/codec/rfx_neon.c @@ -31,28 +31,27 @@ #include "rfx_types.h" #include "rfx_neon.h" -#if defined(ANDROID) -#include +#if ANDROID +#include "cpu-features.h" #endif - void rfx_decode_YCbCr_to_RGB_NEON(INT16 * y_r_buffer, INT16 * cb_g_buffer, INT16 * cr_b_buffer) { int16x8_t zero = vdupq_n_s16(0); int16x8_t max = vdupq_n_s16(255); int16x8_t y_add = vdupq_n_s16(128); - int16x8_t* y_r_buf = (int16x8_t*)y_r_buffer; - int16x8_t* cb_g_buf = (int16x8_t*)cb_g_buffer; - int16x8_t* cr_b_buf = (int16x8_t*)cr_b_buffer; + int16x8_t* y_r_buf = (int16x8_t*) y_r_buffer; + int16x8_t* cb_g_buf = (int16x8_t*) cb_g_buffer; + int16x8_t* cr_b_buf = (int16x8_t*) cr_b_buffer; int i; for (i = 0; i < 4096 / 8; i++) { - int16x8_t y = vld1q_s16((INT16*)&y_r_buf[i]); + int16x8_t y = vld1q_s16((INT16*) &y_r_buf[i]); y = vaddq_s16(y, y_add); - int16x8_t cr = vld1q_s16((INT16*)&cr_b_buf[i]); + int16x8_t cr = vld1q_s16((INT16*) &cr_b_buf[i]); // r = between((y + cr + (cr >> 2) + (cr >> 3) + (cr >> 5)), 0, 255); int16x8_t r = vaddq_s16(y, cr); @@ -295,50 +294,47 @@ rfx_dwt_2d_decode_block_NEON(INT16 * buffer, INT16 * idwt, int subband_width) rfx_dwt_2d_decode_block_vert_NEON(l_dst, h_dst, buffer, subband_width); } -void -rfx_dwt_2d_decode_NEON(INT16 * buffer, INT16 * dwt_buffer) +void rfx_dwt_2d_decode_NEON(INT16 * buffer, INT16 * dwt_buffer) { rfx_dwt_2d_decode_block_NEON(buffer + 3840, dwt_buffer, 8); rfx_dwt_2d_decode_block_NEON(buffer + 3072, dwt_buffer, 16); rfx_dwt_2d_decode_block_NEON(buffer, dwt_buffer, 32); } - - int isNeonSupported() { -#if defined(ANDROID) +#if ANDROID if (android_getCpuFamily() != ANDROID_CPU_FAMILY_ARM) { DEBUG_RFX("NEON optimization disabled - No ARM CPU found"); return 0; } - UINT64_t features = android_getCpuFeatures(); + UINT64 features = android_getCpuFeatures(); + if ((features & ANDROID_CPU_ARM_FEATURE_ARMv7)) { if (features & ANDROID_CPU_ARM_FEATURE_NEON) { DEBUG_RFX("NEON optimization enabled!"); - return 1; + return FALSE; } DEBUG_RFX("NEON optimization disabled - CPU not NEON capable"); } else + { DEBUG_RFX("NEON optimization disabled - No ARMv7 CPU found"); + } - return 0; + return FALSE; #else - return 1; + return TRUE; #endif } - void rfx_init_neon(RFX_CONTEXT * context) { - - - if(isNeonSupported()) + if (isNeonSupported()) { DEBUG_RFX("Using NEON optimizations"); diff --git a/libfreerdp/core/CMakeLists.txt b/libfreerdp/core/CMakeLists.txt index 8c5be64ac..4efe3e00b 100644 --- a/libfreerdp/core/CMakeLists.txt +++ b/libfreerdp/core/CMakeLists.txt @@ -114,7 +114,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE winpr - MODULES winpr-registry winpr-utils winpr-sspi winpr-crt) + MODULES winpr-registry winpr-utils winpr-dsparse winpr-sspi winpr-crt) if(MONOLITHIC_BUILD) set(FREERDP_LIBS ${FREERDP_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index afe472ab3..071c494f6 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -62,7 +62,7 @@ */ /** - * Establish RDP Connection based on the settings given in the 'rdp' paremeter. + * Establish RDP Connection based on the settings given in the 'rdp' parameter. * @msdn{cc240452} * @param rdp RDP module * @return true if the connection succeeded. FALSE otherwise. @@ -74,7 +74,43 @@ BOOL rdp_client_connect(rdpRdp* rdp) nego_init(rdp->nego); nego_set_target(rdp->nego, settings->hostname, settings->port); - nego_set_cookie(rdp->nego, settings->username); + + if (settings->ts_gateway) + { + char* user; + char* domain; + char* cookie; + int user_length; + int domain_length; + int cookie_length; + + user = settings->username; + user_length = strlen(settings->username); + + if (settings->domain) + domain = settings->domain; + else + domain = settings->computer_name; + + domain_length = strlen(domain); + + cookie_length = domain_length + 1 + user_length; + cookie = (char*) malloc(cookie_length + 1); + + CopyMemory(cookie, domain, domain_length); + CharUpperBuffA(cookie, domain_length); + cookie[domain_length] = '\\'; + CopyMemory(&cookie[domain_length + 1], user, user_length); + cookie[cookie_length] = '\0'; + + nego_set_cookie(rdp->nego, cookie); + //nego_set_cookie_max_length(rdp->nego, MSTSC_COOKIE_MAX_LENGTH); + } + else + { + 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); diff --git a/libfreerdp/core/http.c b/libfreerdp/core/http.c index 561174326..6ece2e3ff 100644 --- a/libfreerdp/core/http.c +++ b/libfreerdp/core/http.c @@ -149,24 +149,6 @@ void http_request_set_auth_param(HttpRequest* http_request, char* auth_param) http_request->AuthParam = _strdup(auth_param); } -#ifndef _WIN32 - -errno_t _itoa_s(int value, char* buffer, size_t sizeInCharacters, int radix) -{ - int length; - - length = snprintf(NULL, 0, "%d", value); - - if (sizeInCharacters < length) - return -1; - - snprintf(buffer, length + 1, "%d", value); - - return 0; -} - -#endif - char* http_encode_body_line(char* param, char* value) { char* line; @@ -246,9 +228,9 @@ STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request) for (i = 0; i < http_request->count; i++) { - length += (strlen(http_request->lines[i]) + 1); /* add +1 for each '\n' character */ + length += (strlen(http_request->lines[i]) + 2); /* add +2 for each '\r\n' character */ } - length += 1; /* empty line "\n" at end of header */ + length += 2; /* empty line "\r\n" at end of header */ length += 1; /* null terminator */ s = stream_new(length); @@ -256,10 +238,10 @@ STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request) for (i = 0; i < http_request->count; i++) { stream_write(s, http_request->lines[i], strlen(http_request->lines[i])); - stream_write(s, "\n", 1); + stream_write(s, "\r\n", 2); free(http_request->lines[i]); } - stream_write(s, "\n", 1); + stream_write(s, "\r\n", 2); free(http_request->lines); diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index d5ef12106..88151a133 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -149,7 +149,7 @@ BOOL nego_connect(rdpNego* nego) /* connect to selected security layer */ BOOL nego_security_connect(rdpNego* nego) { - if(!nego->tcp_connected) + if (!nego->tcp_connected) { nego->security_connected = FALSE; } @@ -160,7 +160,7 @@ BOOL nego_security_connect(rdpNego* nego) DEBUG_NEGO("nego_security_connect with PROTOCOL_NLA"); nego->security_connected = transport_connect_nla(nego->transport); } - else if (nego->selected_protocol == PROTOCOL_TLS ) + else if (nego->selected_protocol == PROTOCOL_TLS) { DEBUG_NEGO("nego_security_connect with PROTOCOL_TLS"); nego->security_connected = transport_connect_tls(nego->transport); @@ -175,6 +175,7 @@ BOOL nego_security_connect(rdpNego* nego) DEBUG_NEGO("cannot connect security layer because no protocol has been selected yet."); } } + return nego->security_connected; } @@ -562,6 +563,7 @@ BOOL nego_send_negotiation_request(rdpNego* nego) STREAM* s; int length; BYTE *bm, *em; + int cookie_length; s = transport_send_stream_init(nego->transport, 256); length = TPDU_CONNECTION_REQUEST_LENGTH; @@ -575,7 +577,11 @@ BOOL nego_send_negotiation_request(rdpNego* nego) } else if (nego->cookie != NULL) { - int cookie_length = strlen(nego->cookie); + cookie_length = strlen(nego->cookie); + + if (cookie_length > (int) nego->cookie_max_length) + cookie_length = nego->cookie_max_length; + stream_write(s, "Cookie: mstshash=", 17); stream_write(s, (BYTE*) nego->cookie, cookie_length); stream_write_BYTE(s, 0x0D); /* CR */ @@ -802,6 +808,7 @@ void nego_init(rdpNego* nego) nego->requested_protocols = PROTOCOL_RDP; nego->transport->recv_callback = nego_recv; nego->transport->recv_extra = (void*) nego; + nego->cookie_max_length = DEFAULT_COOKIE_MAX_LENGTH; nego->flags = 0; } @@ -919,6 +926,17 @@ void nego_set_cookie(rdpNego* nego, char* cookie) nego->cookie = cookie; } +/** + * Set cookie maximum length + * @param nego + * @param cookie_max_length + */ + +void nego_set_cookie_max_length(rdpNego* nego, UINT32 cookie_max_length) +{ + nego->cookie_max_length = cookie_max_length; +} + /** * Enable / disable preconnection PDU. * @param nego diff --git a/libfreerdp/core/nego.h b/libfreerdp/core/nego.h index a0b046270..7d8e6a96f 100644 --- a/libfreerdp/core/nego.h +++ b/libfreerdp/core/nego.h @@ -65,14 +65,17 @@ enum RDP_NEG_MSG TYPE_RDP_NEG_FAILURE = 0x3 }; -#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01 +#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_SIZE 16 +#define PRECONNECTION_PDU_V2_MIN_SIZE (PRECONNECTION_PDU_V1_SIZE + 2) #define PRECONNECTION_PDU_V1 1 #define PRECONNECTION_PDU_V2 2 +#define MSTSC_COOKIE_MAX_LENGTH 9 +#define DEFAULT_COOKIE_MAX_LENGTH 0xFF + struct rdp_nego { int port; @@ -88,6 +91,7 @@ struct rdp_nego NEGO_STATE state; BOOL tcp_connected; BOOL security_connected; + UINT32 cookie_max_length; UINT32 selected_protocol; UINT32 requested_protocols; @@ -128,6 +132,7 @@ void nego_enable_nla(rdpNego* nego, BOOL enable_nla); void nego_enable_tls(rdpNego* nego, BOOL enable_tls); void nego_set_routing_token(rdpNego* nego, BYTE* RoutingToken, DWORD RoutingTokenLength); void nego_set_cookie(rdpNego* nego, char* cookie); +void nego_set_cookie_max_length(rdpNego* nego, UINT32 cookie_max_length); void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL send_pcpdu); void nego_set_preconnection_id(rdpNego* nego, UINT32 id); void nego_set_preconnection_blob(rdpNego* nego, char* blob); diff --git a/libfreerdp/core/rpc.c b/libfreerdp/core/rpc.c index 98709f725..ca8067379 100644 --- a/libfreerdp/core/rpc.c +++ b/libfreerdp/core/rpc.c @@ -27,20 +27,26 @@ #include #include +#include +#include + #include #include "http.h" #include "rpc.h" -BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL confidentiality, char* user, char* domain, char* password) +/** + * The Security Support Provider Interface: + * http://technet.microsoft.com/en-us/library/bb742535/ + */ + +BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* password) { SECURITY_STATUS status; sspi_GlobalInit(); - ntlm->confidentiality = confidentiality; - #ifdef WITH_NATIVE_SSPI { HMODULE hSSPI; @@ -62,6 +68,25 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL confidentiality, char* user, char* dom sspi_SetAuthIdentity(&(ntlm->identity), user, domain, password); + if (http) + { + DWORD status; + DWORD SpnLength; + + SpnLength = 0; + status = DsMakeSpn(_T("HTTP"), _T("LAB1-W2K8R2-GW.lab1.awake.local"), NULL, 0, NULL, &SpnLength, NULL); + + if (status != ERROR_BUFFER_OVERFLOW) + { + _tprintf(_T("DsMakeSpn: expected ERROR_BUFFER_OVERFLOW\n")); + return -1; + } + + ntlm->ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR)); + + status = DsMakeSpn(_T("HTTP"), _T("LAB1-W2K8R2-GW.lab1.awake.local"), NULL, 0, NULL, &SpnLength, ntlm->ServicePrincipalName); + } + status = ntlm->table->QuerySecurityPackageInfo(NTLMSP_NAME, &ntlm->pPackageInfo); if (status != SEC_E_OK) @@ -87,10 +112,60 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL confidentiality, char* user, char* dom ZeroMemory(&ntlm->outputBuffer, sizeof(SecBuffer)); ZeroMemory(&ntlm->ContextSizes, sizeof(SecPkgContext_Sizes)); - ntlm->fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_DELEGATE; + ntlm->fContextReq = 0; - if (ntlm->confidentiality) + if (http) + { + /* flags for HTTP authentication */ ntlm->fContextReq |= ISC_REQ_CONFIDENTIALITY; + } + else + { + /** + * flags for RPC authentication: + * RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: + * ISC_REQ_USE_DCE_STYLE | ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH | + * ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT + */ + + ntlm->fContextReq |= ISC_REQ_USE_DCE_STYLE; + ntlm->fContextReq |= ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH; + ntlm->fContextReq |= ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT; + } + + return TRUE; +} + +BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname) +{ + int length; + DWORD status; + DWORD SpnLength; + LPTSTR hostnameX; + + length = 0; + +#ifdef UNICODE + length = strlen(hostname); + hostnameX = (LPWSTR) malloc(length * sizeof(TCHAR)); + MultiByteToWideChar(CP_ACP, 0, hostname, length, hostnameX, length); + hostnameX[length] = 0; +#else + hostnameX = hostname; +#endif + + SpnLength = 0; + status = DsMakeSpn(ServiceClass, hostnameX, NULL, 0, NULL, &SpnLength, NULL); + + if (status != ERROR_BUFFER_OVERFLOW) + return FALSE; + + ntlm->ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR)); + + status = DsMakeSpn(ServiceClass, hostnameX, NULL, 0, NULL, &SpnLength, ntlm->ServicePrincipalName); + + if (status != ERROR_SUCCESS) + return -1; return TRUE; } @@ -116,7 +191,8 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm) status = ntlm->table->InitializeSecurityContext(&ntlm->credentials, (ntlm->haveContext) ? &ntlm->context : NULL, - NULL, ntlm->fContextReq, 0, SECURITY_NATIVE_DREP, + (ntlm->ServicePrincipalName) ? ntlm->ServicePrincipalName : NULL, + ntlm->fContextReq, 0, SECURITY_NATIVE_DREP, (ntlm->haveInputBuffer) ? &ntlm->inputBufferDesc : NULL, 0, &ntlm->context, &ntlm->outputBufferDesc, &ntlm->pfContextAttr, &ntlm->expiration); @@ -212,13 +288,26 @@ STREAM* rpc_ntlm_http_request(rdpRpc* rpc, SecBuffer* ntlm_token, int content_le BOOL rpc_ntlm_http_out_connect(rdpRpc* rpc) { STREAM* s; + rdpSettings* settings; int ntlm_token_length; BYTE* ntlm_token_data; HttpResponse* http_response; rdpNtlm* ntlm = rpc->ntlm_http_out->ntlm; - ntlm_client_init(ntlm, TRUE, rpc->settings->username, - rpc->settings->domain, rpc->settings->password); + settings = rpc->settings; + + if (settings->tsg_same_credentials) + { + ntlm_client_init(ntlm, TRUE, settings->username, + settings->domain, settings->password); + ntlm_client_make_spn(ntlm, _T("HTTP"), settings->tsg_hostname); + } + else + { + ntlm_client_init(ntlm, TRUE, settings->tsg_username, + settings->tsg_domain, settings->tsg_password); + ntlm_client_make_spn(ntlm, _T("HTTP"), settings->tsg_hostname); + } ntlm_authenticate(ntlm); @@ -262,13 +351,26 @@ BOOL rpc_ntlm_http_out_connect(rdpRpc* rpc) BOOL rpc_ntlm_http_in_connect(rdpRpc* rpc) { STREAM* s; + rdpSettings* settings; int ntlm_token_length; BYTE* ntlm_token_data; HttpResponse* http_response; rdpNtlm* ntlm = rpc->ntlm_http_in->ntlm; - ntlm_client_init(ntlm, TRUE, rpc->settings->username, - rpc->settings->domain, rpc->settings->password); + settings = rpc->settings; + + if (settings->tsg_same_credentials) + { + ntlm_client_init(ntlm, TRUE, settings->username, + settings->domain, settings->password); + ntlm_client_make_spn(ntlm, _T("HTTP"), settings->tsg_hostname); + } + else + { + ntlm_client_init(ntlm, TRUE, settings->tsg_username, + settings->tsg_domain, settings->tsg_password); + ntlm_client_make_spn(ntlm, _T("HTTP"), settings->tsg_hostname); + } ntlm_authenticate(ntlm); diff --git a/libfreerdp/core/rpc.h b/libfreerdp/core/rpc.h index 619ac8119..a166f8451 100644 --- a/libfreerdp/core/rpc.h +++ b/libfreerdp/core/rpc.h @@ -540,6 +540,7 @@ struct rdp_ntlm SecBuffer outputBuffer; BOOL haveContext; BOOL haveInputBuffer; + LPTSTR ServicePrincipalName; SecBufferDesc inputBufferDesc; SecBufferDesc outputBufferDesc; CredHandle credentials; diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 5568b47b9..11b386b54 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -31,6 +31,7 @@ #endif #include +#include #include #include @@ -184,6 +185,15 @@ void settings_load_hkey_local_machine(rdpSettings* settings) settings_client_load_hkey_local_machine(settings); } +void settings_get_computer_name(rdpSettings* settings) +{ + DWORD nSize = 0; + + GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize); + settings->computer_name = (char*) malloc(nSize); + GetComputerNameExA(ComputerNameNetBIOS, settings->computer_name, &nSize); +} + rdpSettings* settings_new(void* instance) { rdpSettings* settings; @@ -235,6 +245,8 @@ rdpSettings* settings_new(void* instance) settings->authentication_only = FALSE; settings->from_stdin = FALSE; + settings_get_computer_name(settings); + settings->received_caps = xzalloc(32); settings->order_support = xzalloc(32); diff --git a/libfreerdp/utils/args.c b/libfreerdp/utils/args.c index 86dea02c9..bfec8171b 100644 --- a/libfreerdp/utils/args.c +++ b/libfreerdp/utils/args.c @@ -100,16 +100,31 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, while (index < argc) { + if (index == 1) + { + p = strstr(argv[index], ".rdp"); + + if (!p) + p = strstr(argv[index], ".RDP"); + + if (p) + { + settings->connection_file = _strdup(argv[index]); + index++; + continue; + } + } + if ((strcmp("-h", argv[index]) == 0 ) || (strcmp("--help", argv[index]) == 0 )) { printf("\n" "FreeRDP - A Free Remote Desktop Protocol Client\n" "See http://www.freerdp.com for more information\n" "\n" - "Usage: %s [options] server:port\n" + "Usage: %s [file] [options] server:port\n" " -0: connect to console session\n" " -a: set color depth in bit, default is 16\n" - " -c: initial working directory\n" + " -c: shell working directory\n" " -D: hide window decorations\n" " -T: window title\n" " -d: domain\n" @@ -935,7 +950,7 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, } /* Must have a hostname. Do you? */ - if (NULL == settings->hostname) + if ((settings->hostname == NULL) && (settings->connection_file == NULL)) { printf("missing server name\n"); return FREERDP_ARGS_PARSE_FAILURE; @@ -944,5 +959,4 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, { return index; } - } diff --git a/libfreerdp/utils/msusb.c b/libfreerdp/utils/msusb.c index b143e28ee..27f60c717 100644 --- a/libfreerdp/utils/msusb.c +++ b/libfreerdp/utils/msusb.c @@ -18,7 +18,6 @@ * limitations under the License. */ - #include #include #include @@ -26,18 +25,17 @@ #include #include -static MSUSB_PIPE_DESCRIPTOR * -msusb_mspipe_new() +static MSUSB_PIPE_DESCRIPTOR* msusb_mspipe_new() { - MSUSB_PIPE_DESCRIPTOR * MsPipe = (MSUSB_PIPE_DESCRIPTOR *)malloc(sizeof(MSUSB_PIPE_DESCRIPTOR)); + MSUSB_PIPE_DESCRIPTOR* MsPipe = (MSUSB_PIPE_DESCRIPTOR*) malloc(sizeof(MSUSB_PIPE_DESCRIPTOR)); memset(MsPipe, 0, sizeof(MSUSB_PIPE_DESCRIPTOR)); return MsPipe; } -static void -msusb_mspipes_free(MSUSB_PIPE_DESCRIPTOR ** MsPipes, UINT32 NumberOfPipes) +static void msusb_mspipes_free(MSUSB_PIPE_DESCRIPTOR** MsPipes, UINT32 NumberOfPipes) { int pnum = 0; + if (MsPipes) { for (pnum = 0; pnum < NumberOfPipes && MsPipes[pnum]; pnum++) @@ -48,27 +46,23 @@ msusb_mspipes_free(MSUSB_PIPE_DESCRIPTOR ** MsPipes, UINT32 NumberOfPipes) } } -void -msusb_mspipes_replace(MSUSB_INTERFACE_DESCRIPTOR * MsInterface, MSUSB_PIPE_DESCRIPTOR ** NewMsPipes, UINT32 NewNumberOfPipes) +void msusb_mspipes_replace(MSUSB_INTERFACE_DESCRIPTOR* MsInterface, MSUSB_PIPE_DESCRIPTOR** NewMsPipes, UINT32 NewNumberOfPipes) { /* free orignal MsPipes */ msusb_mspipes_free(MsInterface->MsPipes, MsInterface->NumberOfPipes); /* And replace it */ MsInterface->MsPipes = NewMsPipes; MsInterface->NumberOfPipes = NewNumberOfPipes; - } -static MSUSB_PIPE_DESCRIPTOR ** -msusb_mspipes_read(BYTE * data, UINT32 data_size, UINT32 NumberOfPipes, int * offset) +static MSUSB_PIPE_DESCRIPTOR** msusb_mspipes_read(BYTE* data, UINT32 data_size, UINT32 NumberOfPipes, int* offset) { - MSUSB_PIPE_DESCRIPTOR ** MsPipes; int pnum, move = 0; + MSUSB_PIPE_DESCRIPTOR** MsPipes; - MsPipes = (MSUSB_PIPE_DESCRIPTOR **)malloc(NumberOfPipes * - sizeof(MSUSB_PIPE_DESCRIPTOR *)); + MsPipes = (MSUSB_PIPE_DESCRIPTOR**) malloc(NumberOfPipes * sizeof(MSUSB_PIPE_DESCRIPTOR*)); - for(pnum = 0;pnum < NumberOfPipes; pnum++) + for (pnum = 0; pnum < NumberOfPipes; pnum++) { MSUSB_PIPE_DESCRIPTOR * MsPipe = msusb_mspipe_new(); @@ -91,16 +85,14 @@ msusb_mspipes_read(BYTE * data, UINT32 data_size, UINT32 NumberOfPipes, int * of return MsPipes; } -static MSUSB_INTERFACE_DESCRIPTOR * -msusb_msinterface_new() +static MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_new() { - MSUSB_INTERFACE_DESCRIPTOR * MsInterface = (MSUSB_INTERFACE_DESCRIPTOR *)malloc(sizeof(MSUSB_INTERFACE_DESCRIPTOR)); + MSUSB_INTERFACE_DESCRIPTOR* MsInterface = (MSUSB_INTERFACE_DESCRIPTOR*) malloc(sizeof(MSUSB_INTERFACE_DESCRIPTOR)); memset(MsInterface, 0, sizeof(MSUSB_INTERFACE_DESCRIPTOR)); return MsInterface; } -static void -msusb_msinterface_free(MSUSB_INTERFACE_DESCRIPTOR * MsInterface) +static void msusb_msinterface_free(MSUSB_INTERFACE_DESCRIPTOR* MsInterface) { if (MsInterface) { @@ -110,8 +102,7 @@ msusb_msinterface_free(MSUSB_INTERFACE_DESCRIPTOR * MsInterface) } } -static void -msusb_msinterface_free_list(MSUSB_INTERFACE_DESCRIPTOR ** MsInterfaces, UINT32 NumInterfaces) +static void msusb_msinterface_free_list(MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces, UINT32 NumInterfaces) { int inum = 0; @@ -121,21 +112,20 @@ msusb_msinterface_free_list(MSUSB_INTERFACE_DESCRIPTOR ** MsInterfaces, UINT32 N { msusb_msinterface_free(MsInterfaces[inum]); } + zfree(MsInterfaces); } } -void -msusb_msinterface_replace(MSUSB_CONFIG_DESCRIPTOR * MsConfig, BYTE InterfaceNumber, MSUSB_INTERFACE_DESCRIPTOR * NewMsInterface) +void msusb_msinterface_replace(MSUSB_CONFIG_DESCRIPTOR* MsConfig, BYTE InterfaceNumber, MSUSB_INTERFACE_DESCRIPTOR* NewMsInterface) { msusb_msinterface_free(MsConfig->MsInterfaces[InterfaceNumber]); MsConfig->MsInterfaces[InterfaceNumber] = NewMsInterface; } -MSUSB_INTERFACE_DESCRIPTOR * -msusb_msinterface_read(BYTE * data, UINT32 data_size, int * offset) +MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_read(BYTE* data, UINT32 data_size, int* offset) { - MSUSB_INTERFACE_DESCRIPTOR * MsInterface; + MSUSB_INTERFACE_DESCRIPTOR* MsInterface; MsInterface = msusb_msinterface_new(); @@ -146,12 +136,12 @@ msusb_msinterface_read(BYTE * data, UINT32 data_size, int * offset) data_read_UINT32(data + 8, MsInterface->NumberOfPipes); *offset += 12; - MsInterface->InterfaceHandle = 0; - MsInterface->bInterfaceClass = 0; + MsInterface->InterfaceHandle = 0; + MsInterface->bInterfaceClass = 0; MsInterface->bInterfaceSubClass = 0; MsInterface->bInterfaceProtocol = 0; - MsInterface->InitCompleted = 0; - MsInterface->MsPipes = NULL; + MsInterface->InitCompleted = 0; + MsInterface->MsPipes = NULL; if (MsInterface->NumberOfPipes > 0) { @@ -162,8 +152,7 @@ msusb_msinterface_read(BYTE * data, UINT32 data_size, int * offset) return MsInterface; } -int -msusb_msinterface_write(MSUSB_INTERFACE_DESCRIPTOR * MsInterface, BYTE * data, int * offset) +int msusb_msinterface_write(MSUSB_INTERFACE_DESCRIPTOR* MsInterface, BYTE* data, int* offset) { MSUSB_PIPE_DESCRIPTOR ** MsPipes; MSUSB_PIPE_DESCRIPTOR * MsPipe; @@ -216,38 +205,38 @@ msusb_msinterface_write(MSUSB_INTERFACE_DESCRIPTOR * MsInterface, BYTE * data, i return 0; } -static MSUSB_INTERFACE_DESCRIPTOR ** -msusb_msinterface_read_list(BYTE * data, UINT32 data_size, UINT32 NumInterfaces) +static MSUSB_INTERFACE_DESCRIPTOR** msusb_msinterface_read_list(BYTE * data, UINT32 data_size, UINT32 NumInterfaces) { - MSUSB_INTERFACE_DESCRIPTOR ** MsInterfaces; int inum, offset = 0; + MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces; - MsInterfaces = (MSUSB_INTERFACE_DESCRIPTOR **)malloc(NumInterfaces * - sizeof(MSUSB_INTERFACE_DESCRIPTOR *)); + MsInterfaces = (MSUSB_INTERFACE_DESCRIPTOR**) malloc(NumInterfaces * sizeof(MSUSB_INTERFACE_DESCRIPTOR*)); - for(inum = 0; inum < NumInterfaces; inum++) + for (inum = 0; inum < NumInterfaces; inum++) { MsInterfaces[inum] = msusb_msinterface_read(data + offset, data_size - offset, &offset); } - return MsInterfaces; } -int -msusb_msconfig_write(MSUSB_CONFIG_DESCRIPTOR * MsConfg, BYTE * data, int * offset) +int msusb_msconfig_write(MSUSB_CONFIG_DESCRIPTOR* MsConfg, BYTE* data, int* offset) { - MSUSB_INTERFACE_DESCRIPTOR ** MsInterfaces; - MSUSB_INTERFACE_DESCRIPTOR * MsInterface; int inum = 0; + MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces; + MSUSB_INTERFACE_DESCRIPTOR* MsInterface; /* ConfigurationHandle*/ - data_write_UINT32(data + *offset, MsConfg->ConfigurationHandle); + data_write_UINT32(data + *offset, MsConfg->ConfigurationHandle); + /* NumInterfaces*/ data_write_UINT32(data + *offset + 4, MsConfg->NumInterfaces); *offset += 8; + /* Interfaces */ + MsInterfaces = MsConfg->MsInterfaces; + for(inum = 0; inum < MsConfg->NumInterfaces; inum++) { MsInterface = MsInterfaces[inum]; @@ -257,18 +246,16 @@ msusb_msconfig_write(MSUSB_CONFIG_DESCRIPTOR * MsConfg, BYTE * data, int * offse return 0; } -MSUSB_CONFIG_DESCRIPTOR * -msusb_msconfig_new() +MSUSB_CONFIG_DESCRIPTOR* msusb_msconfig_new() { - MSUSB_CONFIG_DESCRIPTOR * MsConfig = NULL; - MsConfig = (MSUSB_CONFIG_DESCRIPTOR *)malloc(sizeof(MSUSB_CONFIG_DESCRIPTOR)); + MSUSB_CONFIG_DESCRIPTOR* MsConfig = NULL; + MsConfig = (MSUSB_CONFIG_DESCRIPTOR*) malloc(sizeof(MSUSB_CONFIG_DESCRIPTOR)); memset(MsConfig, 0, sizeof(MSUSB_CONFIG_DESCRIPTOR)); return MsConfig; } -void -msusb_msconfig_free(MSUSB_CONFIG_DESCRIPTOR * MsConfig) +void msusb_msconfig_free(MSUSB_CONFIG_DESCRIPTOR* MsConfig) { if (MsConfig) { @@ -278,13 +265,12 @@ msusb_msconfig_free(MSUSB_CONFIG_DESCRIPTOR * MsConfig) } } -MSUSB_CONFIG_DESCRIPTOR * -msusb_msconfig_read(BYTE * data, UINT32 data_size, UINT32 NumInterfaces) +MSUSB_CONFIG_DESCRIPTOR* msusb_msconfig_read(BYTE* data, UINT32 data_size, UINT32 NumInterfaces) { - MSUSB_CONFIG_DESCRIPTOR * MsConfig; - BYTE lenConfiguration, typeConfiguration; - UINT16 lenInterface; int i, offset = 0; + UINT16 lenInterface; + MSUSB_CONFIG_DESCRIPTOR* MsConfig; + BYTE lenConfiguration, typeConfiguration; MsConfig = msusb_msconfig_new(); @@ -293,34 +279,35 @@ msusb_msconfig_read(BYTE * data, UINT32 data_size, UINT32 NumInterfaces) data_read_UINT16(data + offset, lenInterface); offset += lenInterface; } + data_read_BYTE(data + offset, lenConfiguration); data_read_BYTE(data + offset + 1, typeConfiguration); + if (lenConfiguration != 0x9 || typeConfiguration != 0x2) { DEBUG("%s: len and type must be 0x9 and 0x2 , but it is 0x%x and 0x%x", lenConfiguration, typeConfiguration); } + data_read_UINT16(data + offset + 2, MsConfig->wTotalLength); data_read_BYTE(data + offset + 5, MsConfig->bConfigurationValue); - MsConfig->NumInterfaces = NumInterfaces; + + MsConfig->NumInterfaces = NumInterfaces; MsConfig->ConfigurationHandle = 0; - MsConfig->InitCompleted = 0; - MsConfig->MsOutSize = 0; - MsConfig->MsInterfaces = NULL; + MsConfig->InitCompleted = 0; + MsConfig->MsOutSize = 0; + MsConfig->MsInterfaces = NULL; offset = 0; if (NumInterfaces > 0) { - MsConfig->MsInterfaces = - msusb_msinterface_read_list(data, data_size, NumInterfaces); + MsConfig->MsInterfaces = msusb_msinterface_read_list(data, data_size, NumInterfaces); } return MsConfig; - } -void -msusb_msconfig_dump(MSUSB_CONFIG_DESCRIPTOR * MsConfig) +void msusb_msconfig_dump(MSUSB_CONFIG_DESCRIPTOR* MsConfig) { MSUSB_INTERFACE_DESCRIPTOR ** MsInterfaces; MSUSB_INTERFACE_DESCRIPTOR * MsInterface; diff --git a/winpr/include/winpr/crt.h b/winpr/include/winpr/crt.h index ab0aa692a..322cb2e62 100644 --- a/winpr/include/winpr/crt.h +++ b/winpr/include/winpr/crt.h @@ -50,6 +50,10 @@ WINPR_API size_t _aligned_msize(void* memblock, size_t alignment, size_t offset) WINPR_API void _aligned_free(void* memblock); +/* Data Conversion */ + +WINPR_API errno_t _itoa_s(int value, char* buffer, size_t sizeInCharacters, int radix); + /* Buffer Manipulation */ WINPR_API errno_t memmove_s(void* dest, size_t numberOfElements, const void* src, size_t count); diff --git a/winpr/include/winpr/dsparse.h b/winpr/include/winpr/dsparse.h index 9f5f53cf8..ad4fbe5f6 100644 --- a/winpr/include/winpr/dsparse.h +++ b/winpr/include/winpr/dsparse.h @@ -22,13 +22,76 @@ #ifdef _WIN32 +#include #include +#include + #else #include #include #include +#include + +typedef enum +{ + DS_NAME_NO_FLAGS = 0x0, + DS_NAME_FLAG_SYNTACTICAL_ONLY = 0x1, + DS_NAME_FLAG_EVAL_AT_DC = 0x2, + DS_NAME_FLAG_GCVERIFY = 0x4, + DS_NAME_FLAG_TRUST_REFERRAL = 0x8 +} DS_NAME_FLAGS; + +typedef enum +{ + DS_UNKNOWN_NAME = 0, + DS_FQDN_1779_NAME = 1, + DS_NT4_ACCOUNT_NAME = 2, + DS_DISPLAY_NAME = 3, + DS_UNIQUE_ID_NAME = 6, + DS_CANONICAL_NAME = 7, + DS_USER_PRINCIPAL_NAME = 8, + DS_CANONICAL_NAME_EX = 9, + DS_SERVICE_PRINCIPAL_NAME = 10, + DS_SID_OR_SID_HISTORY_NAME = 11, + DS_DNS_DOMAIN_NAME = 12 +} DS_NAME_FORMAT; + +typedef enum +{ + DS_NAME_NO_ERROR = 0, + DS_NAME_ERROR_RESOLVING = 1, + DS_NAME_ERROR_NOT_FOUND = 2, + DS_NAME_ERROR_NOT_UNIQUE = 3, + DS_NAME_ERROR_NO_MAPPING = 4, + DS_NAME_ERROR_DOMAIN_ONLY = 5, + DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 6, + DS_NAME_ERROR_TRUST_REFERRAL = 7 +} DS_NAME_ERROR; + +typedef enum +{ + DS_SPN_DNS_HOST = 0, + DS_SPN_DN_HOST = 1, + DS_SPN_NB_HOST = 2, + DS_SPN_DOMAIN = 3, + DS_SPN_NB_DOMAIN = 4, + DS_SPN_SERVICE = 5 +} DS_SPN_NAME_TYPE; + +typedef struct +{ + DWORD status; + LPTSTR pDomain; + LPTSTR pName; +} DS_NAME_RESULT_ITEM, *PDS_NAME_RESULT_ITEM; + +typedef struct +{ + DWORD cItems; + PDS_NAME_RESULT_ITEM rItems; +} DS_NAME_RESULT, *PDS_NAME_RESULT; WINPR_API DWORD DsCrackSpnW(LPCWSTR pszSpn, DWORD* pcServiceClass, LPWSTR ServiceClass, DWORD* pcServiceName, LPWSTR ServiceName, DWORD* pcInstanceName, LPWSTR InstanceName, USHORT* pInstancePort); diff --git a/winpr/include/winpr/midl.h b/winpr/include/winpr/midl.h index 75a87eb38..0f87efe8d 100644 --- a/winpr/include/winpr/midl.h +++ b/winpr/include/winpr/midl.h @@ -22,7 +22,11 @@ #include +#ifndef _WIN32 + WINPR_API void* MIDL_user_allocate(size_t cBytes); WINPR_API void MIDL_user_free(void* p); +#endif + #endif /* WINPR_RPC_MIDL_H */ diff --git a/winpr/include/winpr/ndr.h b/winpr/include/winpr/ndr.h index b26c75b0a..58ce654cb 100644 --- a/winpr/include/winpr/ndr.h +++ b/winpr/include/winpr/ndr.h @@ -23,6 +23,8 @@ #include #include +#ifndef _WIN32 + #define __RPC_WIN32__ 1 #define TARGET_IS_NT50_OR_LATER 1 @@ -525,4 +527,6 @@ typedef void (*NDR_TYPE_FREE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char WINPR_API CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...); +#endif + #endif /* WINPR_RPC_NDR_H */ diff --git a/winpr/include/winpr/rpc.h b/winpr/include/winpr/rpc.h index 31257d2ce..248f88e78 100644 --- a/winpr/include/winpr/rpc.h +++ b/winpr/include/winpr/rpc.h @@ -20,6 +20,12 @@ #ifndef WINPR_RPC_H #define WINPR_RPC_H +#ifdef _WIN32 + +#include + +#else + #include #include @@ -42,4 +48,6 @@ typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_SERIALIZE; void RpcRaiseException(RPC_STATUS exception); +#endif + #endif /* WINPR_RPC_H */ diff --git a/winpr/include/winpr/string.h b/winpr/include/winpr/string.h index 99bef208b..e3957737c 100644 --- a/winpr/include/winpr/string.h +++ b/winpr/include/winpr/string.h @@ -49,7 +49,13 @@ WINPR_API WCHAR* _wcsdup(const WCHAR* strSource); WINPR_API int _stricmp(const char* string1, const char* string2); +WINPR_API int _wcscmp(const WCHAR* string1, const WCHAR* string2); + +WINPR_API size_t _wcslen(const WCHAR* str); +WINPR_API WCHAR* _wcschr(const WCHAR* str, WCHAR c); + WINPR_API char* strtok_s(char* strToken, const char* strDelimit, char** context); +WINPR_API WCHAR* wcstok_s(WCHAR* strToken, const WCHAR* strDelimit, WCHAR** context); WINPR_API LPSTR CharUpperA(LPSTR lpsz); WINPR_API LPWSTR CharUpperW(LPWSTR lpsz); @@ -149,6 +155,12 @@ WINPR_API int lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2); #define sprintf_s snprintf +#else + +#define _wcscmp wcscmp +#define _wcslen wcslen +#define _wcschr wcschr + #endif #endif /* WINPR_CRT_STRING_H */ diff --git a/winpr/libwinpr/crt/CMakeLists.txt b/winpr/libwinpr/crt/CMakeLists.txt index 7ed9b0a99..d4e035a6f 100644 --- a/winpr/libwinpr/crt/CMakeLists.txt +++ b/winpr/libwinpr/crt/CMakeLists.txt @@ -20,6 +20,7 @@ set(MODULE_PREFIX "WINPR_CRT") set(${MODULE_PREFIX}_SRCS alignment.c + conversion.c buffer.c memory.c string.c) diff --git a/winpr/libwinpr/crt/conversion.c b/winpr/libwinpr/crt/conversion.c new file mode 100644 index 000000000..fb1d3d4ab --- /dev/null +++ b/winpr/libwinpr/crt/conversion.c @@ -0,0 +1,45 @@ +/** + * WinPR: Windows Portable Runtime + * Data Conversion + * + * 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 + +/* Data Conversion: http://msdn.microsoft.com/en-us/library/0heszx3w/ */ + +#ifndef _WIN32 + +errno_t _itoa_s(int value, char* buffer, size_t sizeInCharacters, int radix) +{ + int length; + + length = snprintf(NULL, 0, "%d", value); + + if (sizeInCharacters < length) + return -1; + + snprintf(buffer, length + 1, "%d", value); + + return 0; +} + +#endif + diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c index 3d1baa70b..d55844a4c 100644 --- a/winpr/libwinpr/crt/string.c +++ b/winpr/libwinpr/crt/string.c @@ -74,11 +74,74 @@ int _stricmp(const char* string1, const char* string2) return strcasecmp(string1, string2); } +/* _wcscmp -> wcscmp */ + +int _wcscmp(const WCHAR* string1, const WCHAR* string2) +{ + while (*string1 && (*string1 == *string2)) + { + string1++; + string2++; + } + + return *string1 - *string2; +} + +/* _wcslen -> wcslen */ + +size_t _wcslen(const WCHAR* str) +{ + WCHAR* p = (WCHAR*) str; + + while (*p) + p++; + + return (p - str); +} + +/* _wcschr -> wcschr */ + +WCHAR* _wcschr(const WCHAR* str, WCHAR c) +{ + WCHAR* p = (WCHAR*) str; + + while (*p && (*p != c)) + p++; + + return ((*p == c) ? p : NULL); +} + char* strtok_s(char* strToken, const char* strDelimit, char** context) { return strtok_r(strToken, strDelimit, context); } +WCHAR* wcstok_s(WCHAR* strToken, const WCHAR* strDelimit, WCHAR** context) +{ + WCHAR* nextToken; + + if (!strToken) + strToken = *context; + + while (*strToken && _wcschr(strDelimit, *strToken)) + strToken++; + + if (!*strToken) + return NULL; + + nextToken = strToken++; + + while (*strToken && !(_wcschr(strDelimit, *strToken))) + strToken++; + + if (*strToken) + *strToken++ = 0; + + *context = strToken; + + return nextToken; +} + /* Windows API Sets - api-ms-win-core-string-l2-1-0.dll * http://msdn.microsoft.com/en-us/library/hh802935/ */ diff --git a/winpr/libwinpr/crt/test/CMakeLists.txt b/winpr/libwinpr/crt/test/CMakeLists.txt index 2e974c2e2..962faaa3f 100644 --- a/winpr/libwinpr/crt/test/CMakeLists.txt +++ b/winpr/libwinpr/crt/test/CMakeLists.txt @@ -5,7 +5,8 @@ set(MODULE_PREFIX "TEST_CRT") set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) set(${MODULE_PREFIX}_TESTS - TestAlignment.c) + TestAlignment.c + TestString.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} diff --git a/winpr/libwinpr/crt/test/TestAlignment.c b/winpr/libwinpr/crt/test/TestAlignment.c index bd911db0f..817d29b84 100644 --- a/winpr/libwinpr/crt/test/TestAlignment.c +++ b/winpr/libwinpr/crt/test/TestAlignment.c @@ -1,6 +1,5 @@ #include -#include #include #include diff --git a/winpr/libwinpr/crt/test/TestString.c b/winpr/libwinpr/crt/test/TestString.c new file mode 100644 index 000000000..c19ef5e98 --- /dev/null +++ b/winpr/libwinpr/crt/test/TestString.c @@ -0,0 +1,109 @@ + +#include +#include +#include + +static WCHAR testStringW[] = +{ + 'T', 'h', 'e', ' ', 'q', 'u', 'i', 'c', 'k', ' ', 'b', 'r', 'o', 'w', 'n', ' ', + 'f', 'o', 'x', ' ', 'j', 'u', 'm', 'p', 's', ' ', 'o', 'v', 'e', 'r', ' ', + 't', 'h', 'e', ' ', 'l', 'a', 'z', 'y', ' ', 'd', 'o', 'g', '\0' +}; + +#define testStringW_Length ((sizeof(testStringW) / sizeof(WCHAR)) - 1) + +static WCHAR testToken1W[] = { 'q', 'u', 'i', 'c', 'k', '\0' }; +static WCHAR testToken2W[] = { 'b', 'r', 'o', 'w', 'n', '\0' }; +static WCHAR testToken3W[] = { 'f', 'o', 'x', '\0' }; + +static WCHAR testTokensW[] = +{ + 'q', 'u', 'i', 'c', 'k', '\r', '\n', + 'b', 'r', 'o', 'w', 'n', '\r', '\n', + 'f', 'o', 'x', '\r', '\n', '\0' +}; + +static WCHAR testDelimiter[] = { '\r', '\n', '\0' }; + +int TestString(int argc, char* argv[]) +{ + WCHAR* p; + size_t pos; + size_t length; + WCHAR* context; + + /* _wcslen */ + + length = _wcslen(testStringW); + + if (length != testStringW_Length) + { + printf("_wcslen error: length mismatch: Actual: %d, Expected: %d\n", length, testStringW_Length); + return -1; + } + + /* _wcschr */ + + p = _wcschr(testStringW, 'r'); + pos = (p - testStringW); + + if (pos != 11) + { + printf("_wcschr error: position mismatch: Actual: %d, Expected: %d\n", pos, 11); + return -1; + } + + p = _wcschr(&testStringW[pos + 1], 'r'); + pos = (p - testStringW); + + if (pos != 29) + { + printf("_wcschr error: position mismatch: Actual: %d, Expected: %d\n", pos, 29); + return -1; + } + + p = _wcschr(&testStringW[pos + 1], 'r'); + + if (p != NULL) + { + printf("_wcschr error: return value mismatch: Actual: 0x%08X, Expected: 0x%08X\n", (size_t) p, (size_t) NULL); + return -1; + } + + /* wcstok_s */ + + p = wcstok_s(testTokensW, testDelimiter, &context); + + if (memcmp(p, testToken1W, sizeof(testToken1W)) != 0) + { + printf("wcstok_s error: token #1 mismatch\n"); + return -1; + } + + p = wcstok_s(NULL, testDelimiter, &context); + + if (memcmp(p, testToken2W, sizeof(testToken2W)) != 0) + { + printf("wcstok_s error: token #2 mismatch\n"); + return -1; + } + + p = wcstok_s(NULL, testDelimiter, &context); + + if (memcmp(p, testToken3W, sizeof(testToken3W)) != 0) + { + printf("wcstok_s error: token #3 mismatch\n"); + return -1; + } + + p = wcstok_s(NULL, testDelimiter, &context); + + if (p != NULL) + { + printf("wcstok_s error: return value is not NULL\n"); + return -1; + } + + return 0; +} + diff --git a/winpr/libwinpr/dsparse/CMakeLists.txt b/winpr/libwinpr/dsparse/CMakeLists.txt index 0775a8633..0cbd4452a 100644 --- a/winpr/libwinpr/dsparse/CMakeLists.txt +++ b/winpr/libwinpr/dsparse/CMakeLists.txt @@ -21,16 +21,29 @@ set(MODULE_PREFIX "WINPR_DSPARSE") set(${MODULE_PREFIX}_SRCS dsparse.c) +if(MSVC AND (NOT MONOLITHIC_BUILD)) + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) +endif() + add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" MONOLITHIC ${MONOLITHIC_BUILD} SOURCES ${${MODULE_PREFIX}_SRCS}) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") -if(MONOLITHIC_BUILD) +if(WIN32) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ntdsapi) +endif() +if(MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) else() + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/dsparse/dsparse.c b/winpr/libwinpr/dsparse/dsparse.c index 45ff7ed90..5d8b0aa3c 100644 --- a/winpr/libwinpr/dsparse/dsparse.c +++ b/winpr/libwinpr/dsparse/dsparse.c @@ -66,7 +66,27 @@ DWORD DsMakeSpnW(LPCWSTR ServiceClass, LPCWSTR ServiceName, LPCWSTR InstanceName DWORD DsMakeSpnA(LPCSTR ServiceClass, LPCSTR ServiceName, LPCSTR InstanceName, USHORT InstancePort, LPCSTR Referrer, DWORD* pcSpnLength, LPSTR pszSpn) { - return 0; + DWORD SpnLength; + DWORD ServiceClassLength; + DWORD ServiceNameLength; + + if ((*pcSpnLength != 0) && (pszSpn == NULL)) + return ERROR_INVALID_PARAMETER; + + ServiceClassLength = strlen(ServiceClass); + ServiceNameLength = strlen(ServiceName); + + SpnLength = ServiceClassLength + 1 + ServiceNameLength + 1; + + if ((*pcSpnLength == 0) || (*pcSpnLength < SpnLength)) + { + *pcSpnLength = SpnLength; + return ERROR_BUFFER_OVERFLOW; + } + + sprintf_s(pszSpn, *pcSpnLength, "%s/%s", ServiceClass, ServiceName); + + return ERROR_SUCCESS; } #endif diff --git a/winpr/libwinpr/dsparse/module.def b/winpr/libwinpr/dsparse/module.def new file mode 100644 index 000000000..683aae863 --- /dev/null +++ b/winpr/libwinpr/dsparse/module.def @@ -0,0 +1,3 @@ +LIBRARY "libwinpr-dsparse" +EXPORTS + diff --git a/winpr/libwinpr/dsparse/test/.gitignore b/winpr/libwinpr/dsparse/test/.gitignore new file mode 100644 index 000000000..38ad7151f --- /dev/null +++ b/winpr/libwinpr/dsparse/test/.gitignore @@ -0,0 +1,2 @@ +TestDs +TestDs.c diff --git a/winpr/libwinpr/dsparse/test/CMakeLists.txt b/winpr/libwinpr/dsparse/test/CMakeLists.txt new file mode 100644 index 000000000..e7efe6513 --- /dev/null +++ b/winpr/libwinpr/dsparse/test/CMakeLists.txt @@ -0,0 +1,31 @@ + +set(MODULE_NAME "TestDsParse") +set(MODULE_PREFIX "TEST_DSPARSE") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestDsMakeSpn.c + TestDsCrackNames.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-dsparse) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") diff --git a/winpr/libwinpr/dsparse/test/TestDsCrackNames.c b/winpr/libwinpr/dsparse/test/TestDsCrackNames.c new file mode 100644 index 000000000..b2645442f --- /dev/null +++ b/winpr/libwinpr/dsparse/test/TestDsCrackNames.c @@ -0,0 +1,50 @@ + +#include +#include +#include +#include +#include + +//LPCTSTR testName = _T("LAB1\\JohnDoe"); + +int TestDsCrackNames(int argc, char* argv[]) +{ +#if 0 + HANDLE ds; + DWORD status; + PDS_NAME_RESULT pResult; + + status = DsBind(NULL, NULL, &ds); + + if (status != ERROR_SUCCESS) + { + _tprintf(_T("DsBind: expected ERROR_SUCCESS: 0x%08X\n"), status); + return -1; + } + + status = DsCrackNames(ds, DS_NAME_FLAG_SYNTACTICAL_ONLY, DS_NT4_ACCOUNT_NAME, + DS_USER_PRINCIPAL_NAME, 1, &testName, &pResult); + + if (status != ERROR_SUCCESS) + { + _tprintf(_T("DsCrackNames: expected ERROR_SUCCESS\n")); + return -1; + } + + _tprintf(_T("DsCrackNames: pResult->cItems: %d\n"), pResult->cItems); + + _tprintf(_T("DsCrackNames: pResult->rItems[0]: Domain: %s Name: %s Status: 0x%08X\n"), + pResult->rItems[0].pDomain, pResult->rItems[0].pName, pResult->rItems[0].status); + + status = DsUnBind(&ds); + + if (status != ERROR_SUCCESS) + { + _tprintf(_T("DsUnBind: expected ERROR_SUCCESS\n")); + return -1; + } +#endif + + return 0; +} + diff --git a/winpr/libwinpr/dsparse/test/TestDsMakeSpn.c b/winpr/libwinpr/dsparse/test/TestDsMakeSpn.c new file mode 100644 index 000000000..80e4f6a32 --- /dev/null +++ b/winpr/libwinpr/dsparse/test/TestDsMakeSpn.c @@ -0,0 +1,63 @@ + +#include +#include +#include +#include +#include + +LPCTSTR testServiceClass = _T("HTTP"); +LPCTSTR testServiceName = _T("LAB1-W2K8R2-GW.lab1.awake.local"); +LPCTSTR testSpn = _T("HTTP/LAB1-W2K8R2-GW.lab1.awake.local"); + +int TestDsMakeSpn(int argc, char* argv[]) +{ + LPTSTR Spn; + DWORD status; + DWORD SpnLength; + + SpnLength = -1; + status = DsMakeSpn(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, NULL); + + if (status != ERROR_INVALID_PARAMETER) + { + _tprintf(_T("DsMakeSpn: expected ERROR_INVALID_PARAMETER\n")); + return -1; + } + + SpnLength = 0; + status = DsMakeSpn(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, NULL); + + if (status != ERROR_BUFFER_OVERFLOW) + { + _tprintf(_T("DsMakeSpn: expected ERROR_BUFFER_OVERFLOW\n")); + return -1; + } + + if (SpnLength != 37) + { + _tprintf(_T("DsMakeSpn: SpnLength mismatch: Actual: %d, Expected: %d\n"), SpnLength, 37); + return -1; + } + + /* SpnLength includes null terminator */ + Spn = (LPTSTR) malloc(SpnLength * sizeof(TCHAR)); + + status = DsMakeSpn(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, Spn); + + if (status != ERROR_SUCCESS) + { + _tprintf(_T("DsMakeSpn: expected ERROR_SUCCESS\n")); + return -1; + } + + if (_tcscmp(Spn, testSpn) != 0) + { + _tprintf(_T("DsMakeSpn: SPN mismatch: Actual: %s, Expected: %s\n"), Spn, testSpn); + return -1; + } + + _tprintf(_T("DsMakeSpn: %s\n"), Spn); + + return 0; +} + diff --git a/build/winpr/libwinpr/io/test/TestIo.c b/winpr/libwinpr/dsparse/test/TestDsParse.c similarity index 95% rename from build/winpr/libwinpr/io/test/TestIo.c rename to winpr/libwinpr/dsparse/test/TestDsParse.c index 0274fdb15..98a7e63f5 100644 --- a/build/winpr/libwinpr/io/test/TestIo.c +++ b/winpr/libwinpr/dsparse/test/TestDsParse.c @@ -7,7 +7,8 @@ /* Forward declare test functions. */ -int TestIoGetOverlappedResult(int, char*[]); +int TestDsMakeSpn(int, char*[]); +int TestDsCrackNames(int, char*[]); /* Create map. */ @@ -21,8 +22,12 @@ typedef struct functionMapEntry cmakeGeneratedFunctionMapEntries[] = { { - "TestIoGetOverlappedResult", - TestIoGetOverlappedResult + "TestDsMakeSpn", + TestDsMakeSpn + }, + { + "TestDsCrackNames", + TestDsCrackNames }, {0,0} diff --git a/winpr/libwinpr/interlocked/test/TestInterlockedAccess.c b/winpr/libwinpr/interlocked/test/TestInterlockedAccess.c index 38c557fa0..c6f72c839 100644 --- a/winpr/libwinpr/interlocked/test/TestInterlockedAccess.c +++ b/winpr/libwinpr/interlocked/test/TestInterlockedAccess.c @@ -1,6 +1,5 @@ #include -#include #include #include #include diff --git a/winpr/libwinpr/interlocked/test/TestInterlockedDList.c b/winpr/libwinpr/interlocked/test/TestInterlockedDList.c index fa3a61fe6..b89a48430 100644 --- a/winpr/libwinpr/interlocked/test/TestInterlockedDList.c +++ b/winpr/libwinpr/interlocked/test/TestInterlockedDList.c @@ -1,6 +1,5 @@ #include -#include #include #include #include diff --git a/winpr/libwinpr/interlocked/test/TestInterlockedSList.c b/winpr/libwinpr/interlocked/test/TestInterlockedSList.c index 86f2b4184..380ec772b 100644 --- a/winpr/libwinpr/interlocked/test/TestInterlockedSList.c +++ b/winpr/libwinpr/interlocked/test/TestInterlockedSList.c @@ -1,6 +1,5 @@ #include -#include #include #include #include diff --git a/winpr/libwinpr/library/test/CMakeLists.txt b/winpr/libwinpr/library/test/CMakeLists.txt index 350993cc1..9d85509f8 100644 --- a/winpr/libwinpr/library/test/CMakeLists.txt +++ b/winpr/libwinpr/library/test/CMakeLists.txt @@ -31,7 +31,7 @@ set(TEST_AREA "${MODULE_NAME}Area") foreach(test ${${MODULE_PREFIX}_TESTS}) get_filename_component(TestName ${test} NAME_WE) - add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName} ${TEST_AREA}) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName} "${TESTING_OUTPUT_DIRECTORY}/${TEST_AREA}") endforeach() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") diff --git a/winpr/libwinpr/library/test/TestLibraryA/CMakeLists.txt b/winpr/libwinpr/library/test/TestLibraryA/CMakeLists.txt index b02369682..90c3936d0 100644 --- a/winpr/libwinpr/library/test/TestLibraryA/CMakeLists.txt +++ b/winpr/libwinpr/library/test/TestLibraryA/CMakeLists.txt @@ -27,6 +27,6 @@ endif() add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") -set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}/${TEST_AREA}/${MODULE_NAME}") +set_target_properties(${MODULE_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}/${TEST_AREA}/${MODULE_NAME}") set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test/Extra") diff --git a/winpr/libwinpr/library/test/TestLibraryB/CMakeLists.txt b/winpr/libwinpr/library/test/TestLibraryB/CMakeLists.txt index 45f4c70b8..a90af7f45 100644 --- a/winpr/libwinpr/library/test/TestLibraryB/CMakeLists.txt +++ b/winpr/libwinpr/library/test/TestLibraryB/CMakeLists.txt @@ -27,7 +27,7 @@ endif() add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") -set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}/${TEST_AREA}/${MODULE_NAME}") +set_target_properties(${MODULE_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}/${TEST_AREA}/${MODULE_NAME}") set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test/Extra") diff --git a/winpr/libwinpr/rpc/ndr.c b/winpr/libwinpr/rpc/ndr.c index d90a2a03b..f10439731 100644 --- a/winpr/libwinpr/rpc/ndr.c +++ b/winpr/libwinpr/rpc/ndr.c @@ -27,6 +27,8 @@ #include +#ifndef _WIN32 + #include "ndr_array.h" #include "ndr_context.h" #include "ndr_pointer.h" @@ -344,3 +346,5 @@ CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRIN return client_call_return; } + +#endif diff --git a/winpr/libwinpr/rpc/ndr_array.c b/winpr/libwinpr/rpc/ndr_array.c index d9c53c5ea..54b1ecc02 100644 --- a/winpr/libwinpr/rpc/ndr_array.c +++ b/winpr/libwinpr/rpc/ndr_array.c @@ -28,6 +28,8 @@ #include "ndr_array.h" +#ifndef _WIN32 + void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { /** @@ -139,3 +141,5 @@ void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemo printf("warning: NdrComplexArrayBufferSize unimplemented\n"); } + +#endif diff --git a/winpr/libwinpr/rpc/ndr_array.h b/winpr/libwinpr/rpc/ndr_array.h index 3a6bc2d44..e29629717 100644 --- a/winpr/libwinpr/rpc/ndr_array.h +++ b/winpr/libwinpr/rpc/ndr_array.h @@ -22,10 +22,14 @@ #include +#ifndef _WIN32 + void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +#endif + #endif /* WINPR_RPC_NDR_ARRAY_H */ diff --git a/winpr/libwinpr/rpc/ndr_context.c b/winpr/libwinpr/rpc/ndr_context.c index 531840074..88120bdb2 100644 --- a/winpr/libwinpr/rpc/ndr_context.c +++ b/winpr/libwinpr/rpc/ndr_context.c @@ -25,6 +25,9 @@ #include #include + +#ifndef _WIN32 + #include "ndr_context.h" #include "ndr_private.h" @@ -68,3 +71,5 @@ void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem NdrpIncrementLength(&(pStubMsg->BufferLength), 20); } } + +#endif diff --git a/winpr/libwinpr/rpc/ndr_context.h b/winpr/libwinpr/rpc/ndr_context.h index 7b8770c2a..95b74b290 100644 --- a/winpr/libwinpr/rpc/ndr_context.h +++ b/winpr/libwinpr/rpc/ndr_context.h @@ -22,6 +22,10 @@ #include +#ifndef _WIN32 + void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +#endif + #endif /* WINPR_RPC_NDR_CONTEXT_H */ diff --git a/winpr/libwinpr/rpc/ndr_correlation.c b/winpr/libwinpr/rpc/ndr_correlation.c index 3deb4caca..e048b7bcf 100644 --- a/winpr/libwinpr/rpc/ndr_correlation.c +++ b/winpr/libwinpr/rpc/ndr_correlation.c @@ -25,6 +25,9 @@ #include #include + +#ifndef _WIN32 + #include "ndr_correlation.h" #include "ndr_private.h" @@ -189,3 +192,5 @@ PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* p return pFormat; } + +#endif diff --git a/winpr/libwinpr/rpc/ndr_correlation.h b/winpr/libwinpr/rpc/ndr_correlation.h index 01724b408..03f47b88f 100644 --- a/winpr/libwinpr/rpc/ndr_correlation.h +++ b/winpr/libwinpr/rpc/ndr_correlation.h @@ -22,8 +22,12 @@ #include +#ifndef _WIN32 + PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, ULONG_PTR* pCount); PFORMAT_STRING NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +#endif + #endif /* WINPR_RPC_NDR_CORRELATION_H */ diff --git a/winpr/libwinpr/rpc/ndr_pointer.c b/winpr/libwinpr/rpc/ndr_pointer.c index f140776d3..691691d2d 100644 --- a/winpr/libwinpr/rpc/ndr_pointer.c +++ b/winpr/libwinpr/rpc/ndr_pointer.c @@ -25,6 +25,9 @@ #include #include + +#ifndef _WIN32 + #include "ndr_pointer.h" #include "ndr_private.h" @@ -324,3 +327,5 @@ void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* p { printf("warning: NdrByteCountPointerBufferSize unimplemented\n"); } + +#endif diff --git a/winpr/libwinpr/rpc/ndr_pointer.h b/winpr/libwinpr/rpc/ndr_pointer.h index 676832239..292bafa5c 100644 --- a/winpr/libwinpr/rpc/ndr_pointer.h +++ b/winpr/libwinpr/rpc/ndr_pointer.h @@ -22,6 +22,8 @@ #include +#ifndef _WIN32 + PFORMAT_STRING NdrpSkipPointerLayout(PFORMAT_STRING pFormat); void NdrpPointerBufferSize(unsigned char* pMemory, PFORMAT_STRING pFormat, PMIDL_STUB_MESSAGE pStubMsg); @@ -34,4 +36,6 @@ PFORMAT_STRING NdrpEmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsign void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +#endif + #endif /* WINPR_RPC_NDR_POINTER_H */ diff --git a/winpr/libwinpr/rpc/ndr_private.c b/winpr/libwinpr/rpc/ndr_private.c index db57de23b..f927a1321 100644 --- a/winpr/libwinpr/rpc/ndr_private.c +++ b/winpr/libwinpr/rpc/ndr_private.c @@ -26,6 +26,8 @@ #include +#ifndef _WIN32 + #include "ndr_array.h" #include "ndr_context.h" #include "ndr_pointer.h" @@ -554,3 +556,5 @@ const NDR_TYPE_FREE_ROUTINE pfnFreeRoutines[] = NULL, /* FC_END */ NULL, /* FC_PAD */ }; + +#endif diff --git a/winpr/libwinpr/rpc/ndr_private.h b/winpr/libwinpr/rpc/ndr_private.h index d5eb947b1..a45f36109 100644 --- a/winpr/libwinpr/rpc/ndr_private.h +++ b/winpr/libwinpr/rpc/ndr_private.h @@ -22,6 +22,8 @@ #include +#ifndef _WIN32 + void NdrpAlignLength(unsigned long* length, unsigned int alignment); void NdrpIncrementLength(unsigned long* length, unsigned int size); @@ -39,4 +41,6 @@ extern const char* FC_TYPE_STRINGS[]; #include "ndr_correlation.h" +#endif + #endif /* WINPR_RPC_NDR_PRIVATE_H */ diff --git a/winpr/libwinpr/rpc/ndr_simple.c b/winpr/libwinpr/rpc/ndr_simple.c index d9492c130..46af05478 100644 --- a/winpr/libwinpr/rpc/ndr_simple.c +++ b/winpr/libwinpr/rpc/ndr_simple.c @@ -25,6 +25,9 @@ #include #include + +#ifndef _WIN32 + #include "ndr_simple.h" #include "ndr_private.h" @@ -195,3 +198,5 @@ void NdrSimpleTypeFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFOR { } + +#endif diff --git a/winpr/libwinpr/rpc/ndr_simple.h b/winpr/libwinpr/rpc/ndr_simple.h index bbd454209..67e387a7d 100644 --- a/winpr/libwinpr/rpc/ndr_simple.h +++ b/winpr/libwinpr/rpc/ndr_simple.h @@ -22,6 +22,8 @@ #include +#ifndef _WIN32 + void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); void NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); @@ -32,4 +34,6 @@ char NdrGetSimpleTypeBufferSize(unsigned char FormatChar); char NdrGetSimpleTypeMemorySize(unsigned char FormatChar); int NdrGetTypeFlags(unsigned char FormatChar); +#endif + #endif /* WINPR_RPC_NDR_SIMPLE_H */ diff --git a/winpr/libwinpr/rpc/ndr_string.c b/winpr/libwinpr/rpc/ndr_string.c index e5f022df4..40312b06a 100644 --- a/winpr/libwinpr/rpc/ndr_string.c +++ b/winpr/libwinpr/rpc/ndr_string.c @@ -26,6 +26,8 @@ #include +#ifndef _WIN32 + #include "ndr_string.h" void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) @@ -37,3 +39,6 @@ void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char { printf("warning: NdrNonConformantStringBufferSize unimplemented\n"); } + +#endif + diff --git a/winpr/libwinpr/rpc/ndr_string.h b/winpr/libwinpr/rpc/ndr_string.h index cbbd63308..fe91a9313 100644 --- a/winpr/libwinpr/rpc/ndr_string.h +++ b/winpr/libwinpr/rpc/ndr_string.h @@ -22,7 +22,11 @@ #include +#ifndef _WIN32 + void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +#endif + #endif /* WINPR_RPC_NDR_STRING_H */ diff --git a/winpr/libwinpr/rpc/ndr_structure.c b/winpr/libwinpr/rpc/ndr_structure.c index cf0895c30..fa6434677 100644 --- a/winpr/libwinpr/rpc/ndr_structure.c +++ b/winpr/libwinpr/rpc/ndr_structure.c @@ -25,6 +25,9 @@ #include #include + +#ifndef _WIN32 + #include "ndr_private.h" #include "ndr_pointer.h" #include "ndr_structure.h" @@ -315,3 +318,5 @@ void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem pStubMsg->PointerLength = 0; } } + +#endif diff --git a/winpr/libwinpr/rpc/ndr_structure.h b/winpr/libwinpr/rpc/ndr_structure.h index ca60c62fe..f4a02bd0d 100644 --- a/winpr/libwinpr/rpc/ndr_structure.h +++ b/winpr/libwinpr/rpc/ndr_structure.h @@ -22,9 +22,13 @@ #include +#ifndef _WIN32 + void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +#endif + #endif /* WINPR_RPC_NDR_STRUCTURE_H */ diff --git a/winpr/libwinpr/rpc/ndr_union.c b/winpr/libwinpr/rpc/ndr_union.c index be4fab3e2..fbe5be922 100644 --- a/winpr/libwinpr/rpc/ndr_union.c +++ b/winpr/libwinpr/rpc/ndr_union.c @@ -26,6 +26,8 @@ #include +#ifndef _WIN32 + #include "ndr_union.h" void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) @@ -37,3 +39,5 @@ void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned cha { printf("warning: NdrNonEncapsulatedUnionBufferSize unimplemented\n"); } + +#endif diff --git a/winpr/libwinpr/rpc/ndr_union.h b/winpr/libwinpr/rpc/ndr_union.h index 7cd81d05b..5a6e2cd55 100644 --- a/winpr/libwinpr/rpc/ndr_union.h +++ b/winpr/libwinpr/rpc/ndr_union.h @@ -22,7 +22,11 @@ #include +#ifndef _WIN32 + void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +#endif + #endif /* WINPR_RPC_NDR_UNION_H */ diff --git a/winpr/libwinpr/rpc/rpc.c b/winpr/libwinpr/rpc/rpc.c index 2987cfb54..b6770e0d3 100644 --- a/winpr/libwinpr/rpc/rpc.c +++ b/winpr/libwinpr/rpc/rpc.c @@ -25,7 +25,11 @@ #include +#ifndef _WIN32 + void RpcRaiseException(RPC_STATUS exception) { printf("RpcRaiseException: 0x%08luX\n", exception); } + +#endif diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index e586f00ff..f408dafa3 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -132,7 +132,11 @@ NTLM_CONTEXT* ntlm_ContextNew() RegCloseKey(hKey); } - context->SuppressExtendedProtection = FALSE; + /* + * Extended Protection is enabled by default in Windows 7, + * but enabling it in WinPR breaks TS Gateway at this point + */ + context->SuppressExtendedProtection = TRUE; status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\LSA"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c index 9e75b71a3..2b53821ec 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -265,7 +265,8 @@ void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context) NTLM_AV_PAIR* ChallengeTargetInfo; NTLM_AV_PAIR* AuthenticateTargetInfo; - AvPairsCount = AvPairsValueLength = 0; + AvPairsCount = 1; + AvPairsValueLength = 0; ChallengeTargetInfo = (NTLM_AV_PAIR*) context->ChallengeTargetInfo.pvBuffer; AvNbDomainName = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvNbDomainName); @@ -317,8 +318,18 @@ void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context) //AvPairsCount++; /* MsvAvRestrictions */ //AvPairsValueLength += 48; - if (!context->SuppressExtendedProtection) + /** + * Extended Protection for Authentication: + * http://blogs.technet.com/b/srd/archive/2009/12/08/extended-protection-for-authentication.aspx + */ + + if (context->SuppressExtendedProtection != FALSE) { + /** + * SEC_CHANNEL_BINDINGS structure + * http://msdn.microsoft.com/en-us/library/windows/desktop/dd919963/ + */ + AvPairsCount++; /* MsvChannelBindings */ AvPairsValueLength += 16; @@ -363,7 +374,7 @@ void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context) ntlm_av_pair_add(AuthenticateTargetInfo, MsvAvFlags, (PBYTE) &flags, 4); } - if (!context->SuppressExtendedProtection) + if (context->SuppressExtendedProtection != FALSE) { BYTE ChannelBindingToken[16]; diff --git a/winpr/libwinpr/utils/sam.c b/winpr/libwinpr/utils/sam.c index dfc48f459..0aa0bc883 100644 --- a/winpr/libwinpr/utils/sam.c +++ b/winpr/libwinpr/utils/sam.c @@ -29,6 +29,10 @@ #include #include +#ifdef HAVE_UNISTD_H +#include +#endif + #ifdef _WIN32 #define WINPR_SAM_FILE "C:\\SAM" #else